From 9453fa9ff3a07bbeb7c53c52743796192cce85ac Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 2 Aug 2024 14:42:51 +0200 Subject: [PATCH] Rd 339 amplience update amplience go sdk and provider to allow hub update (#34) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add resource hub update options * 🔄 synced local '.github/' with remote 'projects/go-terraform-provider/.github' * 🔄 synced local '.github/' with remote 'projects/go-terraform-provider/.github' * 🔄 synced local '.changie.yaml' with remote 'projects/go-terraform-provider/.changie.yaml' * 🔄 synced local '.github/' with remote 'projects/go-terraform-provider/.github' * 🔄 synced local '.github/' with remote 'projects/go-terraform-provider/.github' * feat: add resource hub update options * feat: fixed goreleaser issues * feat: updated versions --------- Co-authored-by: labd-project-manager[bot] <141430439+labd-project-manager[bot]@users.noreply.github.com> --- .../unreleased/Added-20240802-123857.yaml | 3 + .github/workflows/codeql.yml | 81 +++++ .github/workflows/prepare-release.yaml | 20 ++ .../{tests.yaml => pull-request.yaml} | 11 +- .github/workflows/release.yaml | 2 +- .goreleaser.yml | 3 +- amplience/data_source_content_repository.go | 2 +- amplience/data_source_hub.go | 2 +- amplience/provider.go | 13 +- amplience/resource_content_repository.go | 8 +- amplience/resource_content_type.go | 18 +- amplience/resource_content_type_assignment.go | 4 +- amplience/resource_content_type_schema.go | 24 +- amplience/resource_search_index.go | 20 +- amplience/resource_webhook.go | 10 +- amplience/utils.go | 4 +- docs/resources/hub.md | 187 ++++++++++ examples/resources/amplience_hub/resource.tf | 57 +++ go.mod | 70 ++-- go.sum | 179 +++++++--- internal/provider/provider.go | 198 +++++++++++ internal/resources/hub/model.go | 331 ++++++++++++++++++ internal/resources/hub/resource.go | 296 ++++++++++++++++ internal/utils/env.go | 10 + internal/utils/transport.go | 13 + main.go | 64 +++- 26 files changed, 1489 insertions(+), 141 deletions(-) create mode 100644 .changes/unreleased/Added-20240802-123857.yaml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/prepare-release.yaml rename .github/workflows/{tests.yaml => pull-request.yaml} (85%) create mode 100644 docs/resources/hub.md create mode 100644 examples/resources/amplience_hub/resource.tf create mode 100644 internal/provider/provider.go create mode 100644 internal/resources/hub/model.go create mode 100644 internal/resources/hub/resource.go create mode 100644 internal/utils/env.go create mode 100644 internal/utils/transport.go diff --git a/.changes/unreleased/Added-20240802-123857.yaml b/.changes/unreleased/Added-20240802-123857.yaml new file mode 100644 index 0000000..14ebfc6 --- /dev/null +++ b/.changes/unreleased/Added-20240802-123857.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Added full Hub resource logic +time: 2024-08-02T12:38:57.201504019+02:00 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..5d7800d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,81 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '44 19 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version-file: go.mod + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml new file mode 100644 index 0000000..159a4cb --- /dev/null +++ b/.github/workflows/prepare-release.yaml @@ -0,0 +1,20 @@ +name: Generate release pull request + +on: + push: + branches: [ "main" ] + +jobs: + generate-pr: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Prepare release + uses: labd/changie-release-action@v0.3.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + release-workflow: release.yaml diff --git a/.github/workflows/tests.yaml b/.github/workflows/pull-request.yaml similarity index 85% rename from .github/workflows/tests.yaml rename to .github/workflows/pull-request.yaml index 3e8c955..4a13841 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/pull-request.yaml @@ -1,6 +1,6 @@ name: Run Tests -on: [push] +on: [ pull_request ] jobs: @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version-file: "go.mod" - name: Install dependencies run: go get ./... @@ -40,6 +40,13 @@ jobs: with: verbose: true + - name: build binary + uses: goreleaser/goreleaser-action@v3 + with: + args: build --snapshot --clean --single-target + env: + GOPATH: ${{ env.GOPATH }} + changie: runs-on: ubuntu-latest needs: test diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3151dea..428380b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,7 +14,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.19 + go-version-file: "go.mod" - name: Import GPG key id: import_gpg diff --git a/.goreleaser.yml b/.goreleaser.yml index 52816da..5b5ea11 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: terraform-provider-amplience builds: @@ -47,4 +48,4 @@ release: # If you want to manually examine the release before its live, uncomment this line: # draft: true changelog: - skip: true + disable: true diff --git a/amplience/data_source_content_repository.go b/amplience/data_source_content_repository.go index f880525..2c9d5f9 100644 --- a/amplience/data_source_content_repository.go +++ b/amplience/data_source_content_repository.go @@ -42,7 +42,7 @@ func dataSourceContentRepositoryRead(ctx context.Context, data *schema.ResourceD ci := getClient(meta) repository_id := data.Get("id").(string) - repository, err := ci.client.ContentRepositoryGet(repository_id) + repository, err := ci.Client.ContentRepositoryGet(repository_id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/data_source_hub.go b/amplience/data_source_hub.go index 71f243a..6e926f4 100644 --- a/amplience/data_source_hub.go +++ b/amplience/data_source_hub.go @@ -34,7 +34,7 @@ func dataSourceHubRead(ctx context.Context, data *schema.ResourceData, meta inte hub_id := data.Get("id").(string) - hub, err := ci.client.HubGet(hub_id) + hub, err := ci.Client.HubGet(hub_id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/provider.go b/amplience/provider.go index 7138f9c..d34dacd 100644 --- a/amplience/provider.go +++ b/amplience/provider.go @@ -3,7 +3,6 @@ package amplience import ( "context" - "github.com/davecgh/go-spew/spew" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -74,10 +73,6 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{} var diags diag.Diagnostics - // FIXME: pass context to amplience sdk client - spew.Dump(clientID) - spew.Dump(clientSecret) - client, err := content.NewClient(&content.ClientConfig{ ClientID: clientID, ClientSecret: clientSecret, @@ -88,10 +83,10 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{} return nil, diag.FromErr(err) } - client_info := &ClientInfo{ - client: client, - hubID: d.Get("hub_id").(string), + clientInfo := &ClientInfo{ + Client: client, + HubID: d.Get("hub_id").(string), } - return client_info, diags + return clientInfo, diags } diff --git a/amplience/resource_content_repository.go b/amplience/resource_content_repository.go index 93ba6b4..9ac12a0 100644 --- a/amplience/resource_content_repository.go +++ b/amplience/resource_content_repository.go @@ -49,7 +49,7 @@ func resourceContentRepositoryCreate(ctx context.Context, data *schema.ResourceD Label: data.Get("label").(string), } - repository, err := ci.client.ContentRepositoryCreate(ci.hubID, input) + repository, err := ci.Client.ContentRepositoryCreate(ci.HubID, input) if err != nil { return diag.FromErr(err) @@ -67,7 +67,7 @@ func resourceContentRepositoryRead(ctx context.Context, data *schema.ResourceDat repository_id := data.Id() - repository, err := ci.client.ContentRepositoryGet(repository_id) + repository, err := ci.Client.ContentRepositoryGet(repository_id) if err != nil { return diag.FromErr(err) } @@ -84,7 +84,7 @@ func resourceContentRepositoryUpdate(ctx context.Context, data *schema.ResourceD repository_id := data.Id() if data.HasChange("label") || data.HasChange("name") { - current, err := ci.client.ContentRepositoryGet(repository_id) + current, err := ci.Client.ContentRepositoryGet(repository_id) if err != nil { return diag.FromErr(err) } @@ -94,7 +94,7 @@ func resourceContentRepositoryUpdate(ctx context.Context, data *schema.ResourceD Label: data.Get("label").(string), } - repository, err := ci.client.ContentRepositoryUpdate(current, input) + repository, err := ci.Client.ContentRepositoryUpdate(current, input) if err != nil { return diag.FromErr(err) } diff --git a/amplience/resource_content_type.go b/amplience/resource_content_type.go index 6f74631..0543983 100644 --- a/amplience/resource_content_type.go +++ b/amplience/resource_content_type.go @@ -86,7 +86,7 @@ func resourceContentTypeCreate(ctx context.Context, data *schema.ResourceData, m ci := getClient(meta) input := resourceContentTypeCreateInput(data) - instance, err := ci.client.ContentTypeCreate(ci.hubID, input) + instance, err := ci.Client.ContentTypeCreate(ci.HubID, input) if errResp, ok := err.(*content.ErrorResponse); ok { if errResp.StatusCode >= 400 { @@ -94,20 +94,20 @@ func resourceContentTypeCreate(ctx context.Context, data *schema.ResourceData, m log.Println("Received 400 conflict response: content type already exists.") log.Println("Proceeding to unarchive if necessary and update exiting content type.") - instance, err = ci.client.ContentTypeFindByUri(input.ContentTypeURI, ci.hubID) + instance, err = ci.Client.ContentTypeFindByUri(input.ContentTypeURI, ci.HubID) if err != nil { return diag.FromErr(err) } if instance.Status == string(content.StatusArchived) { - instance, err = ci.client.ContentTypeUnarchive(instance.ID) + instance, err = ci.Client.ContentTypeUnarchive(instance.ID) } if err != nil { return diag.FromErr(err) } - instance, err = ci.client.ContentTypeUpdate(instance, input) + instance, err = ci.Client.ContentTypeUpdate(instance, input) if err != nil { return diag.FromErr(err) } @@ -127,7 +127,7 @@ func resourceContentTypeRead(ctx context.Context, data *schema.ResourceData, met ci := getClient(meta) content_type_id := data.Id() - content_type, err := ci.client.ContentTypeGet(content_type_id) + content_type, err := ci.Client.ContentTypeGet(content_type_id) if err != nil { return diag.FromErr(err) } @@ -142,7 +142,7 @@ func resourceContentTypeUpdate(ctx context.Context, data *schema.ResourceData, m id := data.Id() - instance, err := ci.client.ContentTypeGet(id) + instance, err := ci.Client.ContentTypeGet(id) if err != nil { return diag.FromErr(err) } @@ -150,14 +150,14 @@ func resourceContentTypeUpdate(ctx context.Context, data *schema.ResourceData, m if instance.Status == string(content.StatusArchived) { log.Println("Content type was archived. Proceed to unarchive first before applying update.") - instance, err = ci.client.ContentTypeUnarchive(instance.ID) + instance, err = ci.Client.ContentTypeUnarchive(instance.ID) if err != nil { return diag.FromErr(err) } } input := resourceContentTypeCreateInput(data) - content_type, err := ci.client.ContentTypeUpdate(instance, input) + content_type, err := ci.Client.ContentTypeUpdate(instance, input) if err != nil { return diag.FromErr(err) } @@ -173,7 +173,7 @@ func resourceContentTypeDelete(ctx context.Context, data *schema.ResourceData, m id := data.Id() - _, err := ci.client.ContentTypeArchive(id) + _, err := ci.Client.ContentTypeArchive(id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/resource_content_type_assignment.go b/amplience/resource_content_type_assignment.go index 58a7a32..1e8bcd1 100644 --- a/amplience/resource_content_type_assignment.go +++ b/amplience/resource_content_type_assignment.go @@ -37,7 +37,7 @@ func resourceContentTypeAssignmentCreate(ctx context.Context, data *schema.Resou repository_id := data.Get("repository_id").(string) content_type_id := data.Get("content_type_id").(string) - _, err := ci.client.ContentRepositoryAssignContentType(repository_id, content_type_id) + _, err := ci.Client.ContentRepositoryAssignContentType(repository_id, content_type_id) if err != nil { return diag.FromErr(err) } @@ -63,7 +63,7 @@ func resourceContentTypeAssignmentDelete(ctx context.Context, data *schema.Resou repository_id, content_type_id := parseID(data.Id()) - _, err := ci.client.ContentRepositoryRemoveContentType(repository_id, content_type_id) + _, err := ci.Client.ContentRepositoryRemoveContentType(repository_id, content_type_id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/resource_content_type_schema.go b/amplience/resource_content_type_schema.go index f8c0863..fbdbcf0 100644 --- a/amplience/resource_content_type_schema.go +++ b/amplience/resource_content_type_schema.go @@ -67,7 +67,7 @@ func resourceContentTypeSchemaCreate(ctx context.Context, data *schema.ResourceD ValidationLevel: data.Get("validation_level").(string), } - instance, err := ci.client.ContentTypeSchemaCreate(ci.hubID, input) + instance, err := ci.Client.ContentTypeSchemaCreate(ci.HubID, input) if errResp, ok := err.(*content.ErrorResponse); ok { if errResp.StatusCode >= 400 { @@ -75,19 +75,19 @@ func resourceContentTypeSchemaCreate(ctx context.Context, data *schema.ResourceD log.Println("Received 400 conflict response: content type schema already exists.") log.Println("Proceeding to unarchive if necessary and update exiting content type schema.") - instance, err = ci.client.ContentTypeSchemaFindBySchemaId(input.SchemaID, ci.hubID) + instance, err = ci.Client.ContentTypeSchemaFindBySchemaId(input.SchemaID, ci.HubID) if err != nil { return diag.FromErr(err) } if instance.Status == string(content.StatusArchived) { - instance, err = ci.client.ContentTypeSchemaUnarchive(instance.ID, instance.Version) + instance, err = ci.Client.ContentTypeSchemaUnarchive(instance.ID, instance.Version) } if err != nil { return diag.FromErr(err) } - instance, err = ci.client.ContentTypeSchemaUpdate(instance, input) + instance, err = ci.Client.ContentTypeSchemaUpdate(instance, input) if err != nil { return diag.FromErr(err) } @@ -107,7 +107,7 @@ func resourceContentTypeSchemaRead(ctx context.Context, data *schema.ResourceDat ci := getClient(meta) schema_id := data.Id() - schema, err := ci.client.ContentTypeSchemaGet(schema_id) + schema, err := ci.Client.ContentTypeSchemaGet(schema_id) if err != nil { return diag.FromErr(err) } @@ -123,7 +123,7 @@ func resourceContentTypeSchemaUpdate(ctx context.Context, data *schema.ResourceD id := data.Id() if data.HasChange("body") || data.HasChange("validation_level") { - instance, err := ci.client.ContentTypeSchemaGet(id) + instance, err := ci.Client.ContentTypeSchemaGet(id) if err != nil { return diag.FromErr(err) @@ -131,7 +131,7 @@ func resourceContentTypeSchemaUpdate(ctx context.Context, data *schema.ResourceD if instance.Status == string(content.StatusArchived) { log.Println("Content type schema was archived. Proceed to unarchive first before applying update.") - instance, err = ci.client.ContentTypeSchemaUnarchive(instance.ID, instance.Version) + instance, err = ci.Client.ContentTypeSchemaUnarchive(instance.ID, instance.Version) if err != nil { return diag.FromErr(err) } @@ -142,7 +142,7 @@ func resourceContentTypeSchemaUpdate(ctx context.Context, data *schema.ResourceD Body: data.Get("body").(string), ValidationLevel: data.Get("validation_level").(string), } - schema, err := ci.client.ContentTypeSchemaUpdate(instance, input) + schema, err := ci.Client.ContentTypeSchemaUpdate(instance, input) if err != nil { return diag.FromErr(err) } @@ -152,11 +152,11 @@ func resourceContentTypeSchemaUpdate(ctx context.Context, data *schema.ResourceD if data.Get("auto_sync").(bool) { log.Printf("Content type schema %s has been updated; will auto-sync...", instance.SchemaID) - contentType, err := ci.client.ContentTypeFindByUri(instance.SchemaID, ci.hubID) + contentType, err := ci.Client.ContentTypeFindByUri(instance.SchemaID, ci.HubID) if err != nil { log.Printf("No content type found for %s, will skip syncing", instance.SchemaID) } else { - syncResult, err := ci.client.ContentTypeSyncSchema(contentType) + syncResult, err := ci.Client.ContentTypeSyncSchema(contentType) if err != nil { // When syncing could not be performed, for example when no content type exists with this schema, @@ -182,7 +182,7 @@ func resourceContentTypeSchemaDelete(ctx context.Context, data *schema.ResourceD ci := getClient(meta) id := data.Id() - instance, err := ci.client.ContentTypeSchemaGet(id) + instance, err := ci.Client.ContentTypeSchemaGet(id) if err != nil { return diag.FromErr(err) } @@ -191,7 +191,7 @@ func resourceContentTypeSchemaDelete(ctx context.Context, data *schema.ResourceD } if instance.Status == string(content.StatusActive) { - _, err = ci.client.ContentTypeSchemaArchive(id, instance.Version) + _, err = ci.Client.ContentTypeSchemaArchive(id, instance.Version) } if err != nil { return diag.FromErr(err) diff --git a/amplience/resource_search_index.go b/amplience/resource_search_index.go index 0885da0..25b823d 100644 --- a/amplience/resource_search_index.go +++ b/amplience/resource_search_index.go @@ -68,15 +68,15 @@ func resourceSearchIndexCreate(ctx context.Context, data *schema.ResourceData, m return diag.FromErr(err) } - resource, err := ci.client.AlgoliaIndexCreate(ci.hubID, *input) + resource, err := ci.Client.AlgoliaIndexCreate(ci.HubID, *input) if err != nil { return diag.FromErr(err) } - err = updateIndexWebhooksAndSettings(ci.client, ci.hubID, resource.ID, data) + err = updateIndexWebhooksAndSettings(ci.Client, ci.HubID, resource.ID, data) if err != nil { // clean up for timeouts etc. - _, err = ci.client.AlgoliaIndexDelete(ci.hubID, resource.ID) + _, err = ci.Client.AlgoliaIndexDelete(ci.HubID, resource.ID) return diag.FromErr(err) } @@ -90,7 +90,7 @@ func resourceSearchIndexRead(ctx context.Context, data *schema.ResourceData, met id := data.Id() - resource, err := ci.client.AlgoliaIndexGet(ci.hubID, id) + resource, err := ci.Client.AlgoliaIndexGet(ci.HubID, id) if err != nil { return diag.FromErr(err) } @@ -104,7 +104,7 @@ func resourceSearchIndexUpdate(ctx context.Context, data *schema.ResourceData, m id := data.Id() - old, err := ci.client.AlgoliaIndexGet(ci.hubID, id) + old, err := ci.Client.AlgoliaIndexGet(ci.HubID, id) if err != nil { return diag.FromErr(err) } @@ -118,23 +118,23 @@ func resourceSearchIndexUpdate(ctx context.Context, data *schema.ResourceData, m // NOTE: this removes all currently saved indexes and requires a republish of all content types involved. var new content.AlgoliaIndex if old.Suffix != input.Suffix || old.Type != input.Type { - _, err = ci.client.AlgoliaIndexDelete(ci.hubID, id) + _, err = ci.Client.AlgoliaIndexDelete(ci.HubID, id) if err != nil { return diag.FromErr(err) } - new, err = ci.client.AlgoliaIndexCreate(ci.hubID, *input) + new, err = ci.Client.AlgoliaIndexCreate(ci.HubID, *input) if err != nil { return diag.FromErr(err) } } else { - new, err = ci.client.AlgoliaIndexUpdate(ci.hubID, old, *input) + new, err = ci.Client.AlgoliaIndexUpdate(ci.HubID, old, *input) if err != nil { return diag.FromErr(err) } } - err = updateIndexWebhooksAndSettings(ci.client, ci.hubID, id, data) + err = updateIndexWebhooksAndSettings(ci.Client, ci.HubID, id, data) if err != nil { return diag.FromErr(err) } @@ -149,7 +149,7 @@ func resourceSearchIndexDelete(ctx context.Context, data *schema.ResourceData, m id := data.Id() - _, err := ci.client.AlgoliaIndexDelete(ci.hubID, id) + _, err := ci.Client.AlgoliaIndexDelete(ci.HubID, id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/resource_webhook.go b/amplience/resource_webhook.go index 326601c..5178134 100644 --- a/amplience/resource_webhook.go +++ b/amplience/resource_webhook.go @@ -167,7 +167,7 @@ func resourceWebhookCreate(ctx context.Context, data *schema.ResourceData, meta return diag.FromErr(fmt.Errorf("error creating webhook draft: %w", err)) } - webhook, err := ci.client.WebhookCreate(ci.hubID, *input) + webhook, err := ci.Client.WebhookCreate(ci.HubID, *input) if err != nil { return diag.FromErr(err) } @@ -182,7 +182,7 @@ func resourceWebhookRead(ctx context.Context, data *schema.ResourceData, meta in webhook_id := data.Id() - webhook, err := ci.client.WebhookGet(ci.hubID, webhook_id) + webhook, err := ci.Client.WebhookGet(ci.HubID, webhook_id) if err != nil { return diag.FromErr(err) } @@ -196,7 +196,7 @@ func resourceWebhookUpdate(ctx context.Context, data *schema.ResourceData, meta webhook_id := data.Id() - webhook, err := ci.client.WebhookGet(ci.hubID, webhook_id) + webhook, err := ci.Client.WebhookGet(ci.HubID, webhook_id) if err != nil { return diag.FromErr(err) } @@ -206,7 +206,7 @@ func resourceWebhookUpdate(ctx context.Context, data *schema.ResourceData, meta return diag.FromErr(err) } - new, err := ci.client.WebhookUpdate(ci.hubID, webhook, *input) + new, err := ci.Client.WebhookUpdate(ci.HubID, webhook, *input) if err != nil { return diag.FromErr(err) } @@ -220,7 +220,7 @@ func resourceWebhookDelete(ctx context.Context, data *schema.ResourceData, meta webhook_id := data.Id() - err := ci.client.WebhookDelete(ci.hubID, webhook_id) + err := ci.Client.WebhookDelete(ci.HubID, webhook_id) if err != nil { return diag.FromErr(err) } diff --git a/amplience/utils.go b/amplience/utils.go index 0cb9109..544cd7e 100644 --- a/amplience/utils.go +++ b/amplience/utils.go @@ -20,8 +20,8 @@ func createID(hub_id string, resource_id string) string { } type ClientInfo struct { - client *content.Client - hubID string + Client *content.Client + HubID string } func getClient(meta interface{}) *ClientInfo { diff --git a/docs/resources/hub.md b/docs/resources/hub.md new file mode 100644 index 0000000..83aa3e5 --- /dev/null +++ b/docs/resources/hub.md @@ -0,0 +1,187 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "amplience_hub Resource - terraform-provider-amplience" +subcategory: "" +description: |- + Permissions are set at the hub level. All users of a hub can at least view all of the content within the repositories inside that hub. Content cannot be shared across hubs. However, content can be shared and linked to across repositories within the same hub. So you can create a content item in one repository and include content stored in another. Events and editions are scheduled within a single hub. So if you want an overall view of the planning calendar across many brands, then you may wish to consider a single hub. However, in some cases you may want to keep the calendars separate. Many settings, such as the publishing endpoint (the subdomain to which your content is published) are set at a hub level. Multiple hubs may publish content to the same endpoint. + For more info see Amplience Hubs & Repositories Docs https://amplience.com/docs/intro/hubsandrepositories.html + It is recommended to import a new hub instead of creating it! This is because the hub already exists, so any differences in configuration might be overwritten, leading to unintended outcomes. +--- + +# amplience_hub (Resource) + +Permissions are set at the hub level. All users of a hub can at least view all of the content within the repositories inside that hub. Content cannot be shared across hubs. However, content can be shared and linked to across repositories within the same hub. So you can create a content item in one repository and include content stored in another. Events and editions are scheduled within a single hub. So if you want an overall view of the planning calendar across many brands, then you may wish to consider a single hub. However, in some cases you may want to keep the calendars separate. Many settings, such as the publishing endpoint (the subdomain to which your content is published) are set at a hub level. Multiple hubs may publish content to the same endpoint. + +For more info see [Amplience Hubs & Repositories Docs](https://amplience.com/docs/intro/hubsandrepositories.html) + +**It is recommended to import a new hub instead of creating it!** This is because the hub already exists, so any differences in configuration might be overwritten, leading to unintended outcomes. + +## Example Usage + +```terraform +resource "amplience_hub" "my-hub" { + name = "myhub" + label = "My Hub" + settings = { + applications = [ + { + name = "Application" + template_uri = "https://application.com/preview/" + } + ] + asset_management = { + client_config = "HUB" + enabled = true + } + devices = [ + { + name = "Desktop" + width = 1024 + height = 1024 + orientate = false + }, + { + name = "Tablet" + width = 640 + height = 768 + orientate = false + }, + { + name = "Mobile" + width = 320 + height = 512 + orientate = false + } + ] + localization = { + locales = [ + "en-GB", + "nl-NL" + ] + } + preview_virtual_staging_environment = { + hostname = "my-preview-virtual-staging.environment.io" + } + virtual_staging_environment = { + hostname = "my-virtual-staging.environment.io" + } + publishing = { + platforms = { + amplience_dam = { + api_key = "my-api-key" + api_secret = "my-api-secret" + endpoint = "my-endpoint" + } + } + } + } +} +``` + + +## Schema + +### Required + +- `label` (String) Hub label +- `name` (String) Hub name + +### Optional + +- `description` (String) Hub description +- `settings` (Attributes) Hub settings (see [below for nested schema](#nestedatt--settings)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `settings` + +Optional: + +- `applications` (Attributes List) (see [below for nested schema](#nestedatt--settings--applications)) +- `asset_management` (Attributes) (see [below for nested schema](#nestedatt--settings--asset_management)) +- `devices` (Attributes List) (see [below for nested schema](#nestedatt--settings--devices)) +- `localization` (Attributes) (see [below for nested schema](#nestedatt--settings--localization)) +- `preview_virtual_staging_environment` (Attributes) (see [below for nested schema](#nestedatt--settings--preview_virtual_staging_environment)) +- `publishing` (Attributes) (see [below for nested schema](#nestedatt--settings--publishing)) +- `virtual_staging_environment` (Attributes) (see [below for nested schema](#nestedatt--settings--virtual_staging_environment)) + + +### Nested Schema for `settings.applications` + +Required: + +- `name` (String) +- `template_uri` (String) + + + +### Nested Schema for `settings.asset_management` + +Optional: + +- `client_config` (String) +- `enabled` (Boolean) + + + +### Nested Schema for `settings.devices` + +Required: + +- `height` (Number) +- `name` (String) +- `orientate` (Boolean) +- `width` (Number) + + + +### Nested Schema for `settings.localization` + +Optional: + +- `locales` (List of String) + + + +### Nested Schema for `settings.preview_virtual_staging_environment` + +Required: + +- `hostname` (String) Virtual Staging Environment hostname + + + +### Nested Schema for `settings.publishing` + +Optional: + +- `platforms` (Attributes) (see [below for nested schema](#nestedatt--settings--publishing--platforms)) + + +### Nested Schema for `settings.publishing.platforms` + +Optional: + +- `amplience_dam` (Attributes) (see [below for nested schema](#nestedatt--settings--publishing--platforms--amplience_dam)) + + +### Nested Schema for `settings.publishing.platforms.amplience_dam` + +Required: + +- `api_key` (String) DAM publishing client key +- `api_secret` (String, Sensitive) DAM publishing client secret +- `endpoint` (String) Publishing endpoint, also known as Company Tag + + + + + +### Nested Schema for `settings.virtual_staging_environment` + +Required: + +- `hostname` (String) Virtual Staging Environment hostname diff --git a/examples/resources/amplience_hub/resource.tf b/examples/resources/amplience_hub/resource.tf new file mode 100644 index 0000000..8ec04f5 --- /dev/null +++ b/examples/resources/amplience_hub/resource.tf @@ -0,0 +1,57 @@ +resource "amplience_hub" "my-hub" { + name = "myhub" + label = "My Hub" + settings = { + applications = [ + { + name = "Application" + template_uri = "https://application.com/preview/" + } + ] + asset_management = { + client_config = "HUB" + enabled = true + } + devices = [ + { + name = "Desktop" + width = 1024 + height = 1024 + orientate = false + }, + { + name = "Tablet" + width = 640 + height = 768 + orientate = false + }, + { + name = "Mobile" + width = 320 + height = 512 + orientate = false + } + ] + localization = { + locales = [ + "en-GB", + "nl-NL" + ] + } + preview_virtual_staging_environment = { + hostname = "my-preview-virtual-staging.environment.io" + } + virtual_staging_environment = { + hostname = "my-virtual-staging.environment.io" + } + publishing = { + platforms = { + amplience_dam = { + api_key = "my-api-key" + api_secret = "my-api-secret" + endpoint = "my-endpoint" + } + } + } + } +} diff --git a/go.mod b/go.mod index f4fc9ef..80bb3c6 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,14 @@ module github.com/labd/terraform-provider-amplience -go 1.20 +go 1.22 require ( - github.com/davecgh/go-spew v1.1.1 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-docs v0.19.4 + github.com/hashicorp/terraform-plugin-framework v1.10.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 + github.com/hashicorp/terraform-plugin-go v0.23.0 + github.com/hashicorp/terraform-plugin-mux v0.16.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 github.com/labd/amplience-go-sdk v0.1.1 github.com/stretchr/testify v1.9.0 @@ -15,20 +18,21 @@ require ( // replace github.com/labd/amplience-go-sdk => ../amplience-go-sdk require ( - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/bgentry/speakeasy v0.2.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/cloudflare/circl v1.3.9 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/evanphx/json-patch v0.5.2 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -36,26 +40,26 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/hc-install v0.7.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.1 // indirect + github.com/hashicorp/hc-install v0.8.0 // indirect + github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect github.com/hashicorp/terraform-json v0.22.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.23.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect - github.com/huandu/xstrings v1.3.3 // indirect - github.com/imdario/mergo v0.3.15 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -65,27 +69,29 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/cast v1.5.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark v1.7.4 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect - github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.23.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.34.0 // indirect - gopkg.in/yaml.v2 v2.3.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 57b1852..9f60c47 100644 --- a/go.sum +++ b/go.sum @@ -595,26 +595,33 @@ cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vf cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= 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.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= 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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton h1:HKz85FwoXx86kVtTvFke7rgHvq/HoloSUvW5semjFWs= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton h1:KVBEgU3CJpmzLChnLiSuEyCuhGhcMt3eOST+7A+ckto= +github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= @@ -633,11 +640,14 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E= +github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -648,8 +658,10 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI= +github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= +github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= +github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -665,12 +677,14 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -689,11 +703,12 @@ github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6Ni github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= @@ -701,8 +716,11 @@ github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2H github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= 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.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -711,6 +729,7 @@ github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpx github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= 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/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -838,36 +857,62 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= -github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= +github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= -github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= +github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= +github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= +github.com/hashicorp/hc-install v0.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= +github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= +github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= +github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo= +github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= +github.com/hashicorp/terraform-json v0.22.0 h1:cTZejr05cbovFmQ05MeJ43CPrn/+1hUBG7KDTcRwBc0= +github.com/hashicorp/terraform-json v0.22.0/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= +github.com/hashicorp/terraform-plugin-docs v0.19.2 h1:YjdKa1vuqt9EnPYkkrv9HnGZz175HhSJ7Vsn8yZeWus= +github.com/hashicorp/terraform-plugin-docs v0.19.2/go.mod h1:gad2aP6uObFKhgNE8DR9nsEuEQnibp7il0jZYYOunWY= github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c= github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA= +github.com/hashicorp/terraform-plugin-framework v1.9.0 h1:caLcDoxiRucNi2hk8+j3kJwkKfvHznubyFsJMWfZqKU= +github.com/hashicorp/terraform-plugin-framework v1.9.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= +github.com/hashicorp/terraform-plugin-framework v1.10.0 h1:xXhICE2Fns1RYZxEQebwkB2+kXouLC932Li9qelozrc= +github.com/hashicorp/terraform-plugin-framework v1.10.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= +github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E= +github.com/hashicorp/terraform-plugin-framework-validators v0.13.0/go.mod h1:wGeI02gEhj9nPANU62F2jCaHjXulejm/X+af4PdZaNo= github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-mux v0.16.0 h1:RCzXHGDYwUwwqfYYWJKBFaS3fQsWn/ZECEiW7p2023I= +github.com/hashicorp/terraform-plugin-mux v0.16.0/go.mod h1:PF79mAsPc8CpusXPfEVa4X8PtkB+ngWoiUClMrNZlYo= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= @@ -876,23 +921,29 @@ github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -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/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/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/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -900,12 +951,15 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/labd/amplience-go-sdk v0.1.0 h1:h+7WVZZR/VX7TsUSIR/mUNHLkzlN8w2KNOYEMHX662k= +github.com/labd/amplience-go-sdk v0.1.0/go.mod h1:yHJoWYQm4GmOm/9s3hriboRdIRwfkKAGWBBX5VGez+Y= github.com/labd/amplience-go-sdk v0.1.1 h1:XWaRc/VsQj50wHK9YyW+ld3gLS8e03uUd7kCp15EC7M= github.com/labd/amplience-go-sdk v0.1.1/go.mod h1:yHJoWYQm4GmOm/9s3hriboRdIRwfkKAGWBBX5VGez+Y= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= @@ -920,8 +974,10 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= @@ -944,6 +1000,7 @@ github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -958,25 +1015,31 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 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/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= 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= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -999,6 +1062,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.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1008,11 +1072,16 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= +github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= @@ -1046,6 +1115,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1061,8 +1132,10 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -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-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1107,6 +1180,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1169,8 +1244,10 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1202,8 +1279,10 @@ golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1221,7 +1300,8 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1306,6 +1386,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1319,6 +1401,7 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1339,6 +1422,8 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1406,8 +1491,10 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1638,8 +1725,10 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 h1:mxSlqyb8ZAHsYDCfiXN1EDdNTdvjUJSLY+OnAUtYNYA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1681,8 +1770,10 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1702,18 +1793,22 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 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.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/provider/provider.go b/internal/provider/provider.go new file mode 100644 index 0000000..e62b436 --- /dev/null +++ b/internal/provider/provider.go @@ -0,0 +1,198 @@ +package provider + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/provider/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/amplience-go-sdk/content" + "github.com/labd/terraform-provider-amplience/amplience" + "github.com/labd/terraform-provider-amplience/internal/resources/hub" + "github.com/labd/terraform-provider-amplience/internal/utils" + "net/http" + "os" +) + +// Ensure the implementation satisfies the expected interfaces +var ( + _ provider.Provider = &lienceProvider{} +) + +func New(version string) provider.Provider { + return &lienceProvider{ + version: version, + } +} + +type amplienceProvider struct { + version string +} + +// Provider schema struct +type amplienceProviderModel struct { + ClientID types.String `tfsdk:"client_id"` + ClientSecret types.String `tfsdk:"client_secret"` + ContentApiUrl types.String `tfsdk:"content_api_url"` + AuthUrl types.String `tfsdk:"auth_url"` + HubID types.String `tfsdk:"hub_id"` +} + +// Metadata returns the provider type name. +func (p *amplienceProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) { + resp.TypeName = "amplience" +} + +// Schema returns a Terraform.ResourceProvider. +func (p *amplienceProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "client_id": schema.StringAttribute{ + Description: "The OAuth Client ID for the Amplience management API https://amplience_provider.com/docs/api/dynamic-content/management/index.html#section/Authentication", + Required: true, + Sensitive: true, + }, + "client_secret": schema.StringAttribute{ + Description: "The OAuth Client Secret for Amplience management API. https://amplience_provider.com/docs/api/dynamic-content/management/index.html#section/Authentication", + Required: true, + Sensitive: true, + }, + "content_api_url": schema.StringAttribute{ + Description: "The base URL path for the Amplience Content API", + Optional: true, + Sensitive: false, + }, + "auth_url": schema.StringAttribute{ + Description: "The Amplience authentication URL", + Optional: true, + Sensitive: false, + }, + "hub_id": schema.StringAttribute{ + Description: "ID of the Hub to manage", + Required: true, + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + }, + }, + } +} + +func (p *amplienceProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { + var config amplienceProviderModel + + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + var clientID string + if config.ClientID.IsUnknown() || config.ClientID.IsNull() { + clientID = os.Getenv("AMPLIENCE_CLIENT_ID") + } else { + clientID = config.ClientID.ValueString() + } + + if clientID == "" { + resp.Diagnostics.AddAttributeError( + path.Root("client_id"), + "Unknown Amplience Client ID", + "Unknown Amplience Client ID. Please provide a valid client ID.", + ) + } + + var clientSecret string + if config.ClientSecret.IsUnknown() || config.ClientSecret.IsNull() { + clientSecret = os.Getenv("AMPLIENCE_CLIENT_SECRET") + } else { + clientSecret = config.ClientSecret.ValueString() + } + + if clientSecret == "" { + resp.Diagnostics.AddAttributeError( + path.Root("client_secret"), + "Unknown Amplience Client Secret", + "Unknown Amplience Client Secret. Please provide a valid client secret", + ) + } + + var hubId string + if config.HubID.IsUnknown() || config.HubID.IsNull() { + hubId = os.Getenv("AMPLIENCE_HUB_ID") + } else { + hubId = config.HubID.ValueString() + } + + if hubId == "" { + resp.Diagnostics.AddAttributeError( + path.Root("hub_id"), + "Unknown Amplience Hub ID", + "Unknown Amplience Hub ID. Please provide a valid hub ID.", + ) + } + + var contentApiUrl string + if config.ContentApiUrl.IsUnknown() || config.ContentApiUrl.IsNull() { + contentApiUrl = utils.GetEnv( + "AMPLIENCE_CONTENT_API_URL", + "https://api.amplience.net/v2/content", + ) + } else { + contentApiUrl = config.ContentApiUrl.ValueString() + } + + var authUrl string + if config.AuthUrl.IsUnknown() || config.AuthUrl.IsNull() { + authUrl = utils.GetEnv( + "AMPLIENCE_AUTH_URL", + "https://auth.amplience.net/oauth/token", + ) + } else { + authUrl = config.AuthUrl.ValueString() + } + + httpClient := &http.Client{ + Transport: &utils.UserAgentTransport{ + UserAgent: fmt.Sprintf("terraform-provider-amplience/%s", p.version), + Transport: http.DefaultTransport, + }, + } + + client, err := content.NewClient(&content.ClientConfig{ + ClientID: clientID, + ClientSecret: clientSecret, + URL: contentApiUrl, + AuthURL: authUrl, + HTTPClient: httpClient, + }) + if err != nil { + resp.Diagnostics.AddError( + "Unable to create client", + "Unable to create amplience client:\n\n"+err.Error(), + ) + return + } + + data := &lience.ClientInfo{ + Client: client, + HubID: hubId, + } + resp.DataSourceData = data + resp.ResourceData = data +} + +// DataSources defines the data sources implemented in the provider. +func (p *amplienceProvider) DataSources(_ context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{} +} + +// Resources defines the resources implemented in the provider. +func (p *amplienceProvider) Resources(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + hub.NewHubResource, + } +} diff --git a/internal/resources/hub/model.go b/internal/resources/hub/model.go new file mode 100644 index 0000000..807075a --- /dev/null +++ b/internal/resources/hub/model.go @@ -0,0 +1,331 @@ +package hub + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/amplience-go-sdk/content" +) + +type Hub struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Label types.String `tfsdk:"label"` + Description types.String `tfsdk:"description"` + Settings *Settings `tfsdk:"settings"` +} + +type Settings struct { + Publishing *Publishing `tfsdk:"publishing"` + Devices Devices `tfsdk:"devices"` + Localization *Localization `tfsdk:"localization"` + Applications Applications `tfsdk:"applications"` + PreviewVirtualStagingEnvironment *PreviewVirtualStagingEnvironment `tfsdk:"preview_virtual_staging_environment"` + VirtualStagingEnvironment *VirtualStagingEnvironment `tfsdk:"virtual_staging_environment"` + AssetManagement *AssetManagement `tfsdk:"asset_management"` +} + +type Publishing struct { + Platforms *Platforms `tfsdk:"platforms"` +} + +type Platforms struct { + AmplienceDAM *AmplienceDAM `tfsdk:"amplience_dam"` +} + +type AmplienceDAM struct { + APIKey types.String `tfsdk:"api_key"` + APISecret types.String `tfsdk:"api_secret"` + Endpoint types.String `tfsdk:"endpoint"` +} + +type Devices []DeviceSettings + +type DeviceSettings struct { + Name types.String `tfsdk:"name"` + Width types.Int64 `tfsdk:"width"` + Height types.Int64 `tfsdk:"height"` + Orientate types.Bool `tfsdk:"orientate"` +} + +type Localization struct { + Locales []types.String `tfsdk:"locales"` +} + +type Applications []Application + +type Application struct { + Name types.String `tfsdk:"name"` + TemplateURI types.String `tfsdk:"template_uri"` +} + +type PreviewVirtualStagingEnvironment struct { + Hostname types.String `tfsdk:"hostname"` +} + +type VirtualStagingEnvironment struct { + Hostname types.String `tfsdk:"hostname"` +} + +type AssetManagement struct { + Enabled types.Bool `tfsdk:"enabled"` + ClientConfig types.String `tfsdk:"client_config"` +} + +func (h *Hub) ToUpdateInput() content.HubUpdateInput { + return content.HubUpdateInput{ + Name: h.Name.ValueString(), + Label: h.Label.ValueString(), + Description: h.Description.ValueStringPointer(), + Settings: h.Settings.ToUpdateInput(), + } +} + +func (h *Hub) setSecretValuesFromState(s Hub) { + if h.Settings == nil || h.Settings.Publishing == nil || h.Settings.Publishing.Platforms == nil || h.Settings.Publishing.Platforms.AmplienceDAM == nil { + return + } + + if s.Settings == nil || s.Settings.Publishing == nil || s.Settings.Publishing.Platforms == nil || s.Settings.Publishing.Platforms.AmplienceDAM == nil { + return + } + + h.Settings.Publishing.Platforms.AmplienceDAM.APISecret = s.Settings.Publishing.Platforms.AmplienceDAM.APISecret +} + +func (s *Settings) ToUpdateInput() *content.Settings { + if s == nil { + return nil + } + + return &content.Settings{ + Publishing: s.Publishing.ToUpdateInput(), + Devices: s.Devices.ToUpdateInput(), + Localization: s.Localization.ToUpdateInput(), + Applications: s.Applications.ToUpdateInput(), + PreviewVirtualStagingEnvironment: s.PreviewVirtualStagingEnvironment.ToUpdateInput(), + VirtualStagingEnvironment: s.VirtualStagingEnvironment.ToUpdateInput(), + AssetManagement: s.AssetManagement.ToUpdateInput(), + } +} + +func (p *Publishing) ToUpdateInput() *content.PublishingSettings { + if p == nil { + return nil + } + + return &content.PublishingSettings{ + Platforms: p.Platforms.ToUpdateInput(), + } +} + +func (p *Platforms) ToUpdateInput() *content.PlatformSettings { + if p == nil { + return nil + } + + return &content.PlatformSettings{ + AmplienceDam: p.AmplienceDAM.ToUpdateInput(), + } +} + +func (a *AmplienceDAM) ToUpdateInput() *content.AmplienceDamSettings { + if a == nil { + return nil + } + + return &content.AmplienceDamSettings{ + ApiKey: a.APIKey.ValueString(), + ApiSecret: a.APISecret.ValueString(), + Endpoint: a.Endpoint.ValueString(), + } +} + +func (d Devices) ToUpdateInput() []content.DeviceSettings { + var devices = make([]content.DeviceSettings, 0, len(d)) + for _, device := range d { + devices = append(devices, content.DeviceSettings{ + Name: device.Name.ValueString(), + Width: int(device.Width.ValueInt64()), + Height: int(device.Height.ValueInt64()), + Orientate: device.Orientate.ValueBool(), + }) + } + + return devices +} + +func (l *Localization) ToUpdateInput() *content.LocalizationSettings { + if l == nil { + return nil + } + + var locales = make([]string, 0, len(l.Locales)) + for _, locale := range l.Locales { + locales = append(locales, locale.ValueString()) + } + + return &content.LocalizationSettings{ + Locales: locales, + } +} + +func (a Applications) ToUpdateInput() []content.ApplicationSettings { + var applications = make([]content.ApplicationSettings, 0, len(a)) + for _, app := range a { + applications = append(applications, content.ApplicationSettings{ + Name: app.Name.ValueString(), + TemplatedUri: app.TemplateURI.ValueString(), + }) + } + + return applications +} + +func (p *PreviewVirtualStagingEnvironment) ToUpdateInput() *content.PreviewVirtualStagingEnvironmentSettings { + if p == nil { + return nil + } + + return &content.PreviewVirtualStagingEnvironmentSettings{ + Hostname: p.Hostname.ValueString(), + } +} + +func (v *VirtualStagingEnvironment) ToUpdateInput() *content.VirtualStagingEnvironmentSettings { + if v == nil { + return nil + } + + return &content.VirtualStagingEnvironmentSettings{ + Hostname: v.Hostname.ValueString(), + } +} + +func (a *AssetManagement) ToUpdateInput() *content.AssetManagementSettings { + if a == nil { + return nil + } + + return &content.AssetManagementSettings{ + Enabled: a.Enabled.ValueBoolPointer(), + ClientConfig: a.ClientConfig.ValueStringPointer(), + } +} + +func NewHubFromNative(hub *content.Hub) *Hub { + return &Hub{ + ID: types.StringValue(hub.ID), + Name: types.StringValue(hub.Name), + Label: types.StringValue(hub.Label), + Description: types.StringPointerValue(hub.Description), + Settings: NewSettingsFromNative(hub.Settings), + } +} + +func NewSettingsFromNative(settings *content.Settings) *Settings { + if settings == nil { + return nil + } + return &Settings{ + Publishing: NewPublishingFromNative(settings.Publishing), + Devices: NewDevicesFromNative(settings.Devices), + Localization: NewLocalizationFromNative(settings.Localization), + Applications: NewApplicationsFromNative(settings.Applications), + PreviewVirtualStagingEnvironment: NewPreviewVirtualStagingEnvironmentFromNative(settings.PreviewVirtualStagingEnvironment), + VirtualStagingEnvironment: NewVirtualStagingEnvironmentFromNative(settings.VirtualStagingEnvironment), + AssetManagement: NewAssetManagementFromNative(settings.AssetManagement), + } +} + +func NewPublishingFromNative(publishing *content.PublishingSettings) *Publishing { + if publishing == nil { + return nil + } + return &Publishing{ + Platforms: NewPlatformsFromNative(publishing.Platforms), + } +} + +func NewPlatformsFromNative(platforms *content.PlatformSettings) *Platforms { + if platforms == nil { + return nil + } + return &Platforms{ + AmplienceDAM: NewAmplienceDAMFromNative(platforms.AmplienceDam), + } +} + +func NewAmplienceDAMFromNative(dam *content.AmplienceDamSettings) *AmplienceDAM { + if dam == nil { + return nil + } + return &AmplienceDAM{ + APIKey: types.StringValue(dam.ApiKey), + APISecret: types.StringValue(dam.ApiSecret), + Endpoint: types.StringValue(dam.Endpoint), + } +} + +func NewDevicesFromNative(devices []content.DeviceSettings) Devices { + var result Devices + for _, device := range devices { + result = append(result, DeviceSettings{ + Name: types.StringValue(device.Name), + Width: types.Int64Value(int64(device.Width)), + Height: types.Int64Value(int64(device.Height)), + Orientate: types.BoolValue(device.Orientate), + }) + } + return result +} + +func NewLocalizationFromNative(localization *content.LocalizationSettings) *Localization { + if localization == nil { + return nil + } + var locales []types.String + for _, locale := range localization.Locales { + locales = append(locales, types.StringValue(locale)) + } + return &Localization{ + Locales: locales, + } +} + +func NewApplicationsFromNative(applications []content.ApplicationSettings) Applications { + var result Applications + for _, app := range applications { + result = append(result, Application{ + Name: types.StringValue(app.Name), + TemplateURI: types.StringValue(app.TemplatedUri), + }) + } + return result +} + +func NewPreviewVirtualStagingEnvironmentFromNative(env *content.PreviewVirtualStagingEnvironmentSettings) *PreviewVirtualStagingEnvironment { + if env == nil { + return nil + } + return &PreviewVirtualStagingEnvironment{ + Hostname: types.StringValue(env.Hostname), + } +} + +func NewVirtualStagingEnvironmentFromNative(env *content.VirtualStagingEnvironmentSettings) *VirtualStagingEnvironment { + if env == nil { + return nil + } + return &VirtualStagingEnvironment{ + Hostname: types.StringValue(env.Hostname), + } +} + +func NewAssetManagementFromNative(assetManagement *content.AssetManagementSettings) *AssetManagement { + if assetManagement == nil { + return nil + } + return &AssetManagement{ + Enabled: types.BoolPointerValue(assetManagement.Enabled), + ClientConfig: types.StringPointerValue(assetManagement.ClientConfig), + } +} diff --git a/internal/resources/hub/resource.go b/internal/resources/hub/resource.go new file mode 100644 index 0000000..4eb9366 --- /dev/null +++ b/internal/resources/hub/resource.go @@ -0,0 +1,296 @@ +package hub + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/labd/amplience-go-sdk/content" + "github.com/labd/terraform-provider-amplience/amplience" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &hubResource{} + _ resource.ResourceWithConfigure = &hubResource{} + _ resource.ResourceWithImportState = &hubResource{} +) + +// NewHubResource is a helper function to simplify the provider implementation. +func NewHubResource() resource.Resource { + return &hubResource{} +} + +// hubResource is the resource implementation. +type hubResource struct { + client *content.Client + hubId string +} + +// Metadata returns the data source type name. +func (r *hubResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_hub" +} + +// Schema defines the schema for the data source. +func (r *hubResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "Permissions are set at the hub level. All users of a hub can at least view all of the " + + "content within the repositories inside that hub. Content cannot be shared across hubs. However, content " + + "can be shared and linked to across repositories within the same hub. So you can create a content item " + + "in one repository and include content stored in another. Events and editions are scheduled within a " + + "single hub. So if you want an overall view of the planning calendar across many brands, then you may wish " + + "to consider a single hub. However, in some cases you may want to keep the calendars separate. Many " + + "settings, such as the publishing endpoint (the subdomain to which your content is published) are set at " + + "a hub level. Multiple hubs may publish content to the same endpoint.\n\n" + + "For more info see [Amplience Hubs & Repositories Docs](https://amplience.com/docs/intro/hubsandrepositories.html)\n\n" + + "**It is recommended to import a " + + "new hub instead of creating it!** This is because the hub already exists, so any differences in " + + "configuration might be overwritten, leading to unintended outcomes.", + Version: 0, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Description: "Hub name", + Required: true, + }, + "label": schema.StringAttribute{ + Description: "Hub label", + Required: true, + }, + "description": schema.StringAttribute{ + Description: "Hub description", + Optional: true, + }, + "settings": schema.SingleNestedAttribute{ + Optional: true, + Description: "Hub settings", + Attributes: map[string]schema.Attribute{ + "publishing": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "platforms": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "amplience_dam": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "api_key": schema.StringAttribute{ + Description: "DAM publishing client key", + Required: true, + }, + "api_secret": schema.StringAttribute{ + Description: "DAM publishing client secret", + Required: true, + Sensitive: true, + }, + "endpoint": schema.StringAttribute{ + Description: "Publishing endpoint, also known as Company Tag", + Required: true, + }, + }, + }, + }, + }, + }, + }, + "devices": schema.ListNestedAttribute{ + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + Validators: []validator.String{stringvalidator.LengthBetween(1, 50)}, + }, + "width": schema.Int64Attribute{ + Required: true, + }, + "height": schema.Int64Attribute{ + Required: true, + }, + "orientate": schema.BoolAttribute{ + Required: true, + }, + }, + }, + }, + "localization": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "locales": schema.ListAttribute{ + Optional: true, + ElementType: basetypes.StringType{}, + }, + }, + }, + "applications": schema.ListNestedAttribute{ + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + }, + "template_uri": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + "preview_virtual_staging_environment": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "hostname": schema.StringAttribute{ + Description: "Virtual Staging Environment hostname", + Required: true, + }, + }, + }, + "virtual_staging_environment": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "hostname": schema.StringAttribute{ + Description: "Virtual Staging Environment hostname", + Required: true, + }, + }, + }, + "asset_management": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Optional: true, + }, + "client_config": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("HUB", "USER"), + }, + }, + }, + }, + }, + }, + }, + } +} + +// Configure adds the provider configured client to the data source. +func (r *hubResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + data := req.ProviderData.(*amplience.ClientInfo) + r.client = data.Client + r.hubId = data.HubID +} + +// Create creates the resource and sets the initial Terraform state. +func (r *hubResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan Hub + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + hub, err := r.client.HubGet(r.hubId) + if err != nil { + resp.Diagnostics.AddError("Unable to get hub", err.Error()) + return + } + current := NewHubFromNative(&hub) + fmt.Println("current", current) + + hub, err = r.client.HubPatch(r.hubId, current.ToUpdateInput()) + if err != nil { + resp.Diagnostics.AddError("Unable to update hub", err.Error()) + return + } + + result := NewHubFromNative(&hub) + + // Set state to fully populated data + diags = resp.State.Set(ctx, result) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Read refreshes the Terraform state with the latest data. +func (r *hubResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + // Get current state + var state Hub + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + res, err := r.client.HubGet(state.ID.ValueString()) + if err != nil { + resp.Diagnostics.AddError("Error reading hub", err.Error()) + return + } + current := NewHubFromNative(&res) + current.setSecretValuesFromState(state) + + // Set refreshed state + diags = resp.State.Set(ctx, current) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Update updates the resource and sets the updated Terraform state on success. +func (r *hubResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + // Get current state + var current Hub + diags := req.State.Get(ctx, ¤t) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Get updated plan + var plan Hub + diags = req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Update the resource + hub, err := r.client.HubPatch(current.ID.ValueString(), plan.ToUpdateInput()) + if err != nil { + resp.Diagnostics.AddError("Unable to update hub", err.Error()) + return + } + + newState := NewHubFromNative(&hub) + newState.setSecretValuesFromState(current) + + // Set updated state + diags = resp.State.Set(ctx, newState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Delete deletes the resource and removes the Terraform state on success. +func (r *hubResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + resp.Diagnostics.AddWarning("Delete not implemented", "Deleting a hub is not supported. The hub data has been removed from state, but still exists in Amplience.") +} + +func (r *hubResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // Retrieve import ID and save to id attribute + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/utils/env.go b/internal/utils/env.go new file mode 100644 index 0000000..282a613 --- /dev/null +++ b/internal/utils/env.go @@ -0,0 +1,10 @@ +package utils + +import "os" + +func GetEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} diff --git a/internal/utils/transport.go b/internal/utils/transport.go new file mode 100644 index 0000000..e8111c4 --- /dev/null +++ b/internal/utils/transport.go @@ -0,0 +1,13 @@ +package utils + +import "net/http" + +type UserAgentTransport struct { + UserAgent string + Transport http.RoundTripper +} + +func (u *UserAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set("User-Agent", u.UserAgent) + return u.Transport.RoundTrip(req) +} diff --git a/main.go b/main.go index f4b6a41..c861a85 100644 --- a/main.go +++ b/main.go @@ -1,15 +1,23 @@ package main import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + "context" + "flag" + "fmt" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" + "github.com/hashicorp/terraform-plugin-mux/tf5to6server" + "github.com/hashicorp/terraform-plugin-mux/tf6muxserver" + "log" + "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/labd/terraform-provider-amplience/amplience" + "github.com/labd/terraform-provider-amplience/internal/provider" ) // Run "go generate" to format example terraform files and generate the docs for the registry/website -// If you do not have terraform installed, you can remove the formatting command, but its suggested to +// If you do not have Terraform installed, you can remove the formatting command, but it's suggested to // ensure the documentation is formatted properly. //go:generate terraform fmt -recursive ./examples/ @@ -17,10 +25,50 @@ import ( // can be customized. //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs +var ( + // these will be set by the goreleaser configuration + // to appropriate values for the compiled binary + version = "dev" + commit = "snapshot" +) + func main() { - plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: func() *schema.Provider { - return amplience.Provider() - }, - }) + debugFlag := flag.Bool("debug", false, "Start provider in debug mode.") + flag.Parse() + + fullVersion := fmt.Sprintf("%s (%s)", version, commit) + + legacyServerFunc := func() tfprotov6.ProviderServer { + legacyServer, err := tf5to6server.UpgradeServer(context.Background(), amplience.Provider().GRPCProvider) + if err != nil { + log.Fatal(err) + } + + return legacyServer + } + + ctx := context.Background() + providers := []func() tfprotov6.ProviderServer{ + providerserver.NewProtocol6(provider.New(fullVersion)), + legacyServerFunc, + } + + muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...) + if err != nil { + log.Fatal(err) + } + + var serveOpts []tf6server.ServeOpt + if *debugFlag { + serveOpts = append(serveOpts, tf6server.WithManagedDebug()) + } + + err = tf6server.Serve( + "registry.terraform.io/labd/amplience", + muxServer.ProviderServer, + serveOpts..., + ) + if err != nil { + log.Fatal(err) + } }