From 7cb14a872a531717a0128105d2467044b086398f Mon Sep 17 00:00:00 2001 From: Martin McCaffery Date: Wed, 19 Nov 2025 09:53:11 +0100 Subject: [PATCH 1/5] test: output json from goreleaser --- .github/workflows/release.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3040258..da0ef5f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -26,9 +26,15 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser + id: goreleaser uses: https://github.com/goreleaser/goreleaser-action@v6 env: GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }} GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} with: args: release --clean + + - name: TEST output json (artifacts) + run: echo "${{steps.goreleaser.outputs.artifacts}}" + - name: TEST output json (metadata) + run: echo "${{steps.goreleaser.outputs.metadata}}" From c8104c0f1d500d9853c9a793adf1bc5c3a55ff92 Mon Sep 17 00:00:00 2001 From: Martin McCaffery Date: Wed, 19 Nov 2025 10:50:39 +0100 Subject: [PATCH 2/5] workflow: generate provider.json, upload to terralist --- .github/workflows/release.yaml | 12 +++++--- generate-provider-json.sh | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100755 generate-provider-json.sh diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index da0ef5f..11ec0f8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -34,7 +34,11 @@ jobs: with: args: release --clean - - name: TEST output json (artifacts) - run: echo "${{steps.goreleaser.outputs.artifacts}}" - - name: TEST output json (metadata) - run: echo "${{steps.goreleaser.outputs.metadata}}" + - name: Generate and upload provider.json + run: | + echo '${{steps.goreleaser.outputs.artifacts}}' >artifacts.json + echo '${{steps.goreleaser.outputs.metadata}}' >metadata.json + ./generate-provider-json.sh artifacts.json metadata.json + env: + TERRALIST_API: https://terralist.garm-provider-test.t09.de/v1/api + TERRALIST_API_KEY: ${{ secrets.TERRALIST_API_KEY }} diff --git a/generate-provider-json.sh b/generate-provider-json.sh new file mode 100755 index 0000000..1cd1124 --- /dev/null +++ b/generate-provider-json.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -o errexit + +# This script generates and uploads a terraform provider.json file and uploads it to Terralist + +ARTIFACTS_FILE=$1 +METADATA_FILE=$2 + +TERRALIST_API=${TERRALIST_API:-https://terralist.garm-provider-test.t09.de/v1/api} +TERRALIST_API_KEY=${TERRALIST_API_KEY:-invalid-key} + +VERSION=$(cat $METADATA_FILE | jq -r '.version') + +BASE_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download" + +if ! [[ "$BASE_URL" =~ "terraform" ]]; then + echo "Error: GITHUB_ environment variables not set correctly" >&2 + exit 1 +fi + +jq --arg base_url "$BASE_URL" --arg version "$VERSION" ' +{ + protocols: ["6"], + + shasums: ( + { + url: ($base_url + "/v" + $version + "/" + (.[] + | select(.type=="Checksum").name)), + signature_url: ($base_url + "/v" + $version + "/" + (.[] + | select(.type=="Signature").name)) + } + ), + + platforms: [ + .[] + | select(.type=="Archive") + | { + os: .goos, + arch: .goarch, + download_url: ($base_url + "/v" + $version + "/" + .name), + shasum: (.extra.Checksum | sub("^sha256:";"")) + } + ] +} +' $ARTIFACTS_FILE >./provider.json + +cat provider.json | jq . + +curl -X POST $TERRALIST_API/providers/edge-connect/${VERSION}/upload \ + -H "Authorization: Bearer x-api-key:$TERRALIST_API_KEY" \ + -d "$(cat ./provider.json)" \ No newline at end of file From da1f4eecdb6b23a6cc180d80a9b8002c80dace2f Mon Sep 17 00:00:00 2001 From: "martin.mccaffery" Date: Wed, 3 Dec 2025 10:26:45 +0000 Subject: [PATCH 3/5] Update README.md to separate provider conf and local dev --- README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d2f1b50..e94483b 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,11 @@ mkdir -p ~/.terraform.d/plugins/registry.terraform.io/DevFW-CICD/edge-connect/1. cp terraform-provider-edge-connect ~/.terraform.d/plugins/registry.terraform.io/DevFW-CICD/edge-connect/1.0.0/darwin_arm64/ ``` -Note: Adjust the path based on your OS and architecture (e.g., `linux_amd64`, `darwin_amd64`, etc.) +> Note: Adjust the path based on your OS and architecture (e.g., `linux_amd64`, `darwin_amd64`, etc.) -## Usage +4. Generate the binary by running `go install .` from the repository root. This installs the provider binary to `$HOME/go/bin` and means that `terraform init` is not necessary. -### Provider Configuration - -As the provider is currently not officially registered for public download, terraform must be configured to use a locally built version. - -To generate the binary run `go install .` from the repository root. This installs the provider binary to `$HOME/go/bin` and means that `terraform init` is not necessary. - -You will also need a `~/.terraformrc` file with the following contents. `` should refer to your `$HOME` directory. +5. You will also need a `~/.terraformrc` file with the following contents. `` should refer to your `$HOME` directory. ```hcl provider_installation { @@ -76,7 +70,11 @@ provider_installation { } ``` -You can then reference the local provider in your `.tf` files as follows: +## Usage + +### Provider Configuration + +The provider must be configured with credentials and a URL. This can be done with a token in your code: ```hcl provider "edge-connect" { @@ -85,7 +83,7 @@ provider "edge-connect" { } ``` -Or using basic authentication: +Or with basic authentication: ```hcl provider "edge-connect" { @@ -95,7 +93,7 @@ provider "edge-connect" { } ``` -Configuration can also be provided via environment variables: +Or without code changes, via environment variables: - `EDGE_CONNECT_BASE_URL` - `EDGE_CONNECT_TOKEN` - `EDGE_CONNECT_USERNAME` From 9024fe56bd7ef34ad089975f93999d89899f8553 Mon Sep 17 00:00:00 2001 From: Martin McCaffery Date: Thu, 8 Jan 2026 11:09:55 +0100 Subject: [PATCH 4/5] Output terralist ascii armor in release pipeline --- .github/workflows/release.yaml | 7 +++++++ README.md | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 11ec0f8..638cbe3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -25,6 +25,13 @@ jobs: with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: Print GPG information + run: | + echo "To set up Terralist properly, you need to input the following Signing Key as per the README:" + echo "More info: https://edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect#terralist" + echo "Key ID: ${{ steps.import_gpg.outputs.keyid }}" + echo "ASCII armor:" + gpg --armor --export ${{ steps.import_gpg.outputs.keyid }} - name: Run GoReleaser id: goreleaser uses: https://github.com/goreleaser/goreleaser-action@v6 diff --git a/README.md b/README.md index e94483b..91ee6b9 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,23 @@ This Terraform provider allows you to manage Edge Connect applications and appli terraform { required_providers { edge-connect = { - source = "DevFW-CICD/edge-connect" - version = "~> 1.0" + source = "terralist.garm-provider-test.t09.de/edge-connect/edge-connect" + version = ">= 0.0.15" } } } ``` +### Terralist + +To allow the above downloads, the provider artifact must be published to a private Terraform registry. We use [Terralist](https://www.terralist.io/). + +Terralist is deployed on EDP [clusters](https://terralist.garm-provider-test.t09.de/) via [ArgoCD](https://argocd.garm-provider-test.t09.de) using the [terralist stack](https://edp.buildth.ing/DevFW-CICD/stacks/src/branch/main/template/stacks/terralist). Administration can be performed by logging in via the relevant [Forgejo instance](https://garm-provider-test.t09.de/) ([set up](https://edp.buildth.ing/DevFW-CICD/stacks/src/commit/ce8865007cefe3aaec3184fcbf7df955b95a8ef3/template/stacks/terralist/terralist/values.yaml#L7-L38) during [cluster deployment](https://edp.buildth.ing/DevFW/infra-deploy/src/commit/95904c87f0c7248d418d7ed1dc6754d81fc4cccc/scripts/edp-install.sh#L216-L224)), but no authentication is needed to download published Providers. + +Publishing a new instance requires a GPG key, which is stored within the Forgejo [Organisation secrets](https://edp.buildth.ing/org/DevFW-CICD/settings/actions/secrets) to be [available](https://edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect/src/commit/da1f4eecdb6b23a6cc180d80a9b8002c80dace2f/.github/workflows/release.yaml#L26-L27) to the [release pipeline](https://edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect/src/branch/main/.github/workflows/release.yaml). It also requires a `TERRALIST_API_KEY` (stored at the [repository level](https://edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect/settings/actions/secrets)) to be able to push; this can be created within [terralist settings](https://terralist.garm-provider-test.t09.de/#/settings): first create a new Authority with Name `edge-connect` and empty Policy, create a new API Key, then hit the ▽ button and 𓁹 to view the Key. + +Next, you must ensure Terraform can download the Provider. To the Authority, add a Signing Key, with Key ID and ASCII Armor copied from the output of the [release workflow](https://edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect/actions/?workflow=release.yaml&actor=0&status=0). Trust Signature can be left empty. + ### Local Development 1. Clone the repository: From b921dd16f623f1cc38d7897d83237c845a10981d Mon Sep 17 00:00:00 2001 From: Martin McCaffery Date: Thu, 8 Jan 2026 11:42:40 +0100 Subject: [PATCH 5/5] Switch provider to use v1 not v2 of edge connect client --- README.md | 52 ++++++++++-------------- go.mod | 1 + go.sum | 2 + internal/provider/app_data_source.go | 2 +- internal/provider/app_resource.go | 2 +- internal/provider/appinst_data_source.go | 8 ++-- internal/provider/appinst_resource.go | 14 ++----- internal/provider/provider.go | 2 +- 8 files changed, 35 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 91ee6b9..96ec605 100644 --- a/README.md +++ b/README.md @@ -44,41 +44,33 @@ Next, you must ensure Terraform can download the Provider. To the Authority, add ### Local Development 1. Clone the repository: -```bash -git clone ssh://git@edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect.git -cd terraform-provider-edge-connect -``` + ```bash + git clone ssh://git@edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect.git + cd terraform-provider-edge-connect + ``` -2. Build the provider: -```bash -go build -o terraform-provider-edge-connect -``` +1. Generate the binary by running `go install .` from the repository root. This installs the provider binary to `$HOME/go/bin` and means that `terraform init` is not necessary. Note that you will need `$HOME/go/bin` to be in your `$PATH` variable for this to work smoothly. -3. Install locally: -```bash -mkdir -p ~/.terraform.d/plugins/registry.terraform.io/DevFW-CICD/edge-connect/1.0.0/darwin_arm64 -cp terraform-provider-edge-connect ~/.terraform.d/plugins/registry.terraform.io/DevFW-CICD/edge-connect/1.0.0/darwin_arm64/ -``` +1. You will also need a `~/.terraformrc` file with the following contents. `` should refer to your `$HOME` directory. It should contain the following: -> Note: Adjust the path based on your OS and architecture (e.g., `linux_amd64`, `darwin_amd64`, etc.) + ```hcl + provider_installation { -4. Generate the binary by running `go install .` from the repository root. This installs the provider binary to `$HOME/go/bin` and means that `terraform init` is not necessary. + dev_overrides { + "local/edge-connect" = "/go/bin" + } -5. You will also need a `~/.terraformrc` file with the following contents. `` should refer to your `$HOME` directory. - -```hcl -provider_installation { - - dev_overrides { - "local/edge-connect" = "/go/bin" - } - - # For all other providers, install them directly from their origin provider - # registries as normal. If you omit this, Terraform will _only_ use - # the dev_overrides block, and so no other providers will be available. - direct {} -} -``` + # For all other providers, install them directly from their origin provider + # registries as normal. If you omit this, Terraform will _only_ use + # the dev_overrides block, and so no other providers will be available. + direct {} + } + ``` +1. You can then test changes by running the following from the /examples/edgeconnect-config/ repo whenever you update the source code: + ```bash + go install ../../ && terraform plan + ``` + - You will of course need credentials in order to execute `terraform plan`, as described below. ## Usage diff --git a/go.mod b/go.mod index ca742a4..efeb3ff 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module edp.buildth.ing/DevFW-CICD/terraform-provider-edge-connect go 1.25.3 require ( + edp.buildth.ing/DevFW-CICD/edge-connect-client v1.0.0 edp.buildth.ing/DevFW-CICD/edge-connect-client/v2 v2.1.2 github.com/hashicorp/terraform-plugin-framework v1.16.1 github.com/hashicorp/terraform-plugin-log v0.9.0 diff --git a/go.sum b/go.sum index a87b49f..a2bf825 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +edp.buildth.ing/DevFW-CICD/edge-connect-client v1.0.0 h1:WcQmJNHS/4dlGx3lpw3x0hZdPj+GKSdGsQrWRxpdhyI= +edp.buildth.ing/DevFW-CICD/edge-connect-client v1.0.0/go.mod h1:qZUPl2hFLNuhtkIojGfSq/MF7DQJGwvq6KbmtqPwZws= edp.buildth.ing/DevFW-CICD/edge-connect-client/v2 v2.1.2 h1:g1iY/8Au4T6UV6cFm8/SQXAAF+DvFcjR6Hb0TqTF064= edp.buildth.ing/DevFW-CICD/edge-connect-client/v2 v2.1.2/go.mod h1:nPZ4K4BB7eXyeSrcHXvSPkNZbs+XgmxbDJOM4KhbI1A= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= diff --git a/internal/provider/app_data_source.go b/internal/provider/app_data_source.go index 0c2a6fc..14ce336 100644 --- a/internal/provider/app_data_source.go +++ b/internal/provider/app_data_source.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2" + edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect" ) var _ datasource.DataSource = &AppDataSource{} diff --git a/internal/provider/app_resource.go b/internal/provider/app_resource.go index 6454e8f..6701257 100644 --- a/internal/provider/app_resource.go +++ b/internal/provider/app_resource.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2" + edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect" ) var _ resource.Resource = &AppResource{} diff --git a/internal/provider/appinst_data_source.go b/internal/provider/appinst_data_source.go index 45f5784..5d67363 100644 --- a/internal/provider/appinst_data_source.go +++ b/internal/provider/appinst_data_source.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2" + edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect" ) var _ datasource.DataSource = &AppInstanceDataSource{} @@ -144,12 +144,10 @@ func (d *AppInstanceDataSource) Read(ctx context.Context, req datasource.ReadReq Name: data.CloudletName.ValueString(), }, } - appKey := edgeclient.AppKey{ - Name: data.AppId.ValueString(), - } + region := data.Region.ValueString() - appInstances, err := d.client.ShowAppInstances(ctx, appInstKey, appKey, region) + appInstances, err := d.client.ShowAppInstances(ctx, appInstKey, region) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app instance %s/%s in region %s, got error: %s", data.Organization.ValueString(), data.Name.ValueString(), region, err)) diff --git a/internal/provider/appinst_resource.go b/internal/provider/appinst_resource.go index b57510d..58033ec 100644 --- a/internal/provider/appinst_resource.go +++ b/internal/provider/appinst_resource.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2" + edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect" ) var _ resource.Resource = &AppInstanceResource{} @@ -190,7 +190,7 @@ func (r *AppInstanceResource) Create(ctx context.Context, req resource.CreateReq data.Id = types.StringValue(appInstInput.AppInst.Key.Name) data.State = types.StringValue("created") - appInstance, err := r.client.ShowAppInstance(ctx, appInstInput.AppInst.Key, appInstInput.AppInst.AppKey, data.Region.ValueString()) + appInstance, err := r.client.ShowAppInstance(ctx, appInstInput.AppInst.Key, data.Region.ValueString()) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app instance %s, got error: %s", data.Id.ValueString(), err)) return @@ -221,11 +221,8 @@ func (r *AppInstanceResource) Read(ctx context.Context, req resource.ReadRequest Name: data.CloudletName.ValueString(), }, } - appKey := edgeclient.AppKey{ - Name: data.AppName.ValueString(), - } - appInstance, err := r.client.ShowAppInstance(ctx, appInstKey, appKey, data.Region.ValueString()) + appInstance, err := r.client.ShowAppInstance(ctx, appInstKey, data.Region.ValueString()) if err != nil { if errors.Is(err, edgeclient.ErrResourceNotFound) { @@ -270,9 +267,6 @@ func (r *AppInstanceResource) Update(ctx context.Context, req resource.UpdateReq Flavor: edgeclient.Flavor{Name: data.FlavorName.ValueString()}, }, } - appInput := edgeclient.AppKey{ - Name: data.AppName.ValueString(), - } err := r.client.UpdateAppInstance(ctx, updateInput) if err != nil { @@ -280,7 +274,7 @@ func (r *AppInstanceResource) Update(ctx context.Context, req resource.UpdateReq return } - appInstance, err := r.client.ShowAppInstance(ctx, updateInput.AppInst.Key, appInput, data.Region.ValueString()) + appInstance, err := r.client.ShowAppInstance(ctx, updateInput.AppInst.Key, data.Region.ValueString()) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app instance %s, got error: %s", data.Id.ValueString(), err)) return diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 0c418e3..82bd0b4 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2" + edgeclient "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect" ) var _ provider.Provider = &EdgeConnectProvider{}