Skip to content

Commit

Permalink
Merge pull request #56 from pluralsh/sebastian/prod-2580-shared_secre…
Browse files Browse the repository at this point in the history
…t-terraform-resource

feat: add shared secret resource
  • Loading branch information
floreks authored Sep 11, 2024
2 parents aec39c8 + b016005 commit 80ee00c
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 3 deletions.
35 changes: 35 additions & 0 deletions example/sharedsecret/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
terraform {
required_providers {
plural = {
source = "pluralsh/plural"
version = "0.2.1"
}
}
}

provider "plural" {
use_cli = true
}

data "plural_user" "user" {
email = "[email protected]"
}

resource "plural_shared_secret" "mysecret" {
name = "mysecret"
secret = "password"
notification_bindings = [
{ user_id = data.plural_user.user.id }
]
}

resource "null_resource" "default" {
provisioner "local-exec" {
command = "echo name:${plural_shared_secret.mysecret.name}"
}
}

output "secretoutput" {
value = plural_shared_secret.mysecret.secret
sensitive = true
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/hashicorp/terraform-plugin-framework-validators v0.13.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/mitchellh/go-homedir v1.1.0
github.com/pluralsh/console/go/client v1.10.0
github.com/pluralsh/console/go/client v1.15.0
github.com/pluralsh/plural-cli v0.9.14-0.20240730152129-7ce540b144fd
github.com/pluralsh/polly v0.1.10
github.com/samber/lo v1.46.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFz
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pluralsh/console/go/client v1.10.0 h1:oY8ZeTcoyP5WhrAheQm0PwONJQ/O65sqeWRfgQknMtI=
github.com/pluralsh/console/go/client v1.10.0/go.mod h1:lpoWASYsM9keNePS3dpFiEisUHEfObIVlSL3tzpKn8k=
github.com/pluralsh/console/go/client v1.15.0 h1:dFbTGs6648o1VfaS5ZwBcXOKfQUtjIDCs9/8l13PsXU=
github.com/pluralsh/console/go/client v1.15.0/go.mod h1:lpoWASYsM9keNePS3dpFiEisUHEfObIVlSL3tzpKn8k=
github.com/pluralsh/gqlclient v1.12.1 h1:JDOkP9jjqkPdTYdpH5hooG4F8T6FDH90XfipeXJmJFY=
github.com/pluralsh/gqlclient v1.12.1/go.mod h1:OEjN9L63x8m3A3eQBv5kVkFgiY9fp2aZ0cgOF0uII58=
github.com/pluralsh/plural-cli v0.9.14-0.20240730152129-7ce540b144fd h1:gg+5AUbiip8WzAQE+avozXLBdP5eS19J6x6+BhtkGNY=
Expand Down
4 changes: 4 additions & 0 deletions internal/common/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func bindingsFrom(bindings []*console.PolicyBindingFragment, config types.Set, c
return setValue
}

func SetToPolicyBindingAttributes(set types.Set, ctx context.Context, d diag.Diagnostics) []*console.PolicyBindingAttributes {
return policyBindingAttributes(set, ctx, d)
}

type PolicyBinding struct {
GroupID types.String `tfsdk:"group_id"`
ID types.String `tfsdk:"id"`
Expand Down
25 changes: 25 additions & 0 deletions internal/model/shared_secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package model

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
console "github.com/pluralsh/console/go/client"

"terraform-provider-plural/internal/common"
)

type SharedSecret struct {
Name types.String `tfsdk:"name"`
Secret types.String `tfsdk:"secret"`
NotificationBindings types.Set `tfsdk:"notification_bindings"`
}

func (in *SharedSecret) Attributes(ctx context.Context, d diag.Diagnostics) console.SharedSecretAttributes {
return console.SharedSecretAttributes{
Name: in.Name.ValueString(),
Secret: in.Secret.ValueString(),
NotificationBindings: common.SetToPolicyBindingAttributes(in.NotificationBindings, ctx, d),
}
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func (p *PluralProvider) Resources(_ context.Context) []func() resource.Resource
r.NewGroupResource,
r.NewPrAutomationTriggerResource,
r.NewStackRunTriggerResource,
r.NewSharedSecretResource,
}
}

Expand Down
130 changes: 130 additions & 0 deletions internal/resource/shared_secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package resource

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"

"terraform-provider-plural/internal/client"
"terraform-provider-plural/internal/common"
"terraform-provider-plural/internal/model"
)

var _ resource.ResourceWithConfigure = &sharedSecretResource{}

func NewSharedSecretResource() resource.Resource {
return &sharedSecretResource{}
}

type sharedSecretResource struct {
client *client.Client
}

func (in *sharedSecretResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) {
response.TypeName = request.ProviderTypeName + "_shared_secret"
}

func (in *sharedSecretResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) {
response.Schema = schema.Schema{
Description: "A one-time-viewable secret shared with a list of eligible users.",
MarkdownDescription: "A one-time-viewable secret shared with a list of eligible users.",
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Description: "The name of this shared secret.",
MarkdownDescription: "The name of this shared secret.",
Required: true,
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"secret": schema.StringAttribute{
Description: "Content of this shared secret.",
MarkdownDescription: "Content of this shared secret.",
Required: true,
Sensitive: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"notification_bindings": schema.SetNestedAttribute{
Description: "The users/groups you want this secret to be delivered to.",
MarkdownDescription: "The users/groups you want this secret to be delivered to.",
Optional: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"group_id": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"id": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"user_id": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
},
},
PlanModifiers: []planmodifier.Set{setplanmodifier.RequiresReplace()},
},
},
}
}

func (in *sharedSecretResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) {
if request.ProviderData == nil {
return
}

data, ok := request.ProviderData.(*common.ProviderData)
if !ok {
response.Diagnostics.AddError(
"Unexpected Project Resource Configure Type",
fmt.Sprintf("Expected *common.ProviderData, got: %T. Please report this issue to the provider developers.", request.ProviderData),
)
return
}

in.client = data.Client
}

func (in *sharedSecretResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
data := new(model.SharedSecret)
response.Diagnostics.Append(request.Plan.Get(ctx, data)...)
if response.Diagnostics.HasError() {
return
}

_, err := in.client.ShareSecret(ctx, data.Attributes(ctx, response.Diagnostics))
if err != nil {
response.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to share a secret, got error: %s", err))
return
}

response.Diagnostics.Append(response.State.Set(ctx, &data)...)
}

func (in *sharedSecretResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
data := new(model.SharedSecret)
response.Diagnostics.Append(request.State.Get(ctx, data)...)
if response.Diagnostics.HasError() {
return
}

response.Diagnostics.Append(response.State.Set(ctx, data)...)
}

func (in *sharedSecretResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {
// Ignore.
}

func (in *sharedSecretResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {
// Ignore.
}

0 comments on commit 80ee00c

Please sign in to comment.