Skip to content

Commit

Permalink
fix: force replace secrets of VCS resource (#70)
Browse files Browse the repository at this point in the history
Since Terrakube doesn't reply back the client_secret and private key of
VCS connection back to the client and `terrakube_vcs` resource uses
what's supplied to the state, any changes on these two fields
should result into a force replace of the `terrakube_vcs` resource.

Additional changes:

1. More help information on `terrakube_vcs` resource
2. Make `vcs_id` updatable in `terrakube_workspace_vcs` resource
3. Make import work on `terrakube_organization_variable` resource
stanleyz authored Oct 7, 2024
1 parent 6810948 commit 0a2f1d3
Showing 4 changed files with 35 additions and 8 deletions.
4 changes: 2 additions & 2 deletions docs/resources/vcs.md
Original file line number Diff line number Diff line change
@@ -30,15 +30,15 @@ resource "terrakube_vcs" "vcs" {

### Required

- `client_id` (String) The client ID of the VCS connection
- `client_id` (String) The client ID or GitHub Application ID for the VCS connection
- `name` (String) The name of the VCS connection
- `organization_id` (String) Terrakube organization id

### Optional

- `api_url` (String) The API URL of the VCS connection
- `client_secret` (String, Sensitive) The secret of the VCS connection
- `connection_type` (String) The connection type of the VCS connection
- `connection_type` (String) The connection type of the VCS connection, valid vaules are `OAUTH` and `STANDALONE`, default is `OAUTH`. `STANDALONE` is used for GitHub App only.
- `description` (String) The description of the VCS connection
- `endpoint` (String) The endpoint of the VCS connection
- `private_key` (String, Sensitive) The private key in PKCS8 format of the VCS connection. Please use command `openssl pkcs8 -topk8 -inform PEM -inform pem -outform pem -in github_rsa_private_key.pem -out private_key.pem -nocrypt` to convert the private key to PKCS8 format form Github default RSA.
20 changes: 16 additions & 4 deletions internal/provider/organization_variable_resource.go
Original file line number Diff line number Diff line change
@@ -5,15 +5,16 @@ import (
"context"
"crypto/tls"
"fmt"
"github.com/google/jsonapi"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"io"
"net/http"
"strconv"
"strings"
"terraform-provider-terrakube/internal/client"

"github.com/google/jsonapi"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -386,5 +387,16 @@ func (r *OrganizationVariableResource) Delete(ctx context.Context, req resource.
}

func (r *OrganizationVariableResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
idParts := strings.Split(req.ID, ",")

if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
resp.Diagnostics.AddError(
"Unexpected Import Identifier",
fmt.Sprintf("Expected import identifier with format: 'organization_ID,ID', Got: %q", req.ID),
)
return
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("organization_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), idParts[1])...)
}
10 changes: 8 additions & 2 deletions internal/provider/vcs_resource.go
Original file line number Diff line number Diff line change
@@ -95,14 +95,14 @@ func (r *VcsResource) Schema(ctx context.Context, req resource.SchemaRequest, re
Optional: true,
Computed: true,
Default: stringdefault.StaticString("OAUTH"),
Description: "The connection type of the VCS connection",
Description: "The connection type of the VCS connection, valid vaules are `OAUTH` and `STANDALONE`, default is `OAUTH`. `STANDALONE` is used for GitHub App only.",
Validators: []validator.String{
stringvalidator.OneOf("OAUTH", "STANDALONE"),
},
},
"client_id": schema.StringAttribute{
Required: true,
Description: "The client ID of the VCS connection",
Description: "The client ID or GitHub Application ID for the VCS connection",
},
"client_secret": schema.StringAttribute{
Optional: true,
@@ -111,6 +111,9 @@ func (r *VcsResource) Schema(ctx context.Context, req resource.SchemaRequest, re
Validators: []validator.String{
stringvalidator.AtLeastOneOf(path.MatchRelative().AtParent().AtName("client_secret"), path.MatchRelative().AtParent().AtName("private_key")),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"private_key": schema.StringAttribute{
Optional: true,
@@ -119,6 +122,9 @@ func (r *VcsResource) Schema(ctx context.Context, req resource.SchemaRequest, re
Validators: []validator.String{
stringvalidator.AtLeastOneOf(path.MatchRelative().AtParent().AtName("client_secret"), path.MatchRelative().AtParent().AtName("private_key")),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"endpoint": schema.StringAttribute{
Optional: true,
9 changes: 9 additions & 0 deletions internal/provider/workspace_vcs_resource.go
Original file line number Diff line number Diff line change
@@ -296,6 +296,10 @@ func (r *WorkspaceVcsResource) Read(ctx context.Context, req resource.ReadReques
state.IaCVersion = types.StringValue(workspace.IaCVersion)
state.ID = types.StringValue(workspace.ID)

if workspace.Vcs != nil {
state.VcsId = types.StringValue(workspace.Vcs.ID)
}

// Set refreshed state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
@@ -329,6 +333,11 @@ func (r *WorkspaceVcsResource) Update(ctx context.Context, req resource.UpdateRe
ID: state.ID.ValueString(),
}

if !plan.VcsId.IsNull() {
tflog.Info(ctx, fmt.Sprintf("Workspace using Vcs connection id: %s", plan.VcsId.ValueString()))
bodyRequest.Vcs = &client.VcsEntity{ID: plan.VcsId.ValueString()}
}

var out = new(bytes.Buffer)
err := jsonapi.MarshalPayload(out, bodyRequest)

0 comments on commit 0a2f1d3

Please sign in to comment.