Skip to content

Commit

Permalink
Merge pull request #39 from pluralsh/marcin/eng-2167-add-custom-stack…
Browse files Browse the repository at this point in the history
…-runs-to-terraform-provider

feat: Add custom stack run resource
  • Loading branch information
maciaszczykm authored Jun 7, 2024
2 parents e97ade9 + dcd636e commit 0011626
Show file tree
Hide file tree
Showing 11 changed files with 646 additions and 8 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ jobs:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with:
go-version-file: 'go.mod'
cache: true
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@82a020f1f7f605c65dd2449b392a52c3fcfef7ef # v6.0.0
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
id: import_gpg
with:
gpg_private_key: ${{ secrets.PLURAL_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PLURAL_GPG_KEY_PASSWORD }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
uses: goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5.1.0
with:
args: release --clean
env:
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ before:
builds:
- env:
# goreleaser does not work with CGO, it could also complicate
# usage by users in CI/CD systems like Terraform Cloud where
# usage by users in CI/CD systems like HCP Terraform where
# they are unable to install libraries.
- CGO_ENABLED=0
mod_timestamp: '{{ .CommitTimestamp }}'
Expand Down
73 changes: 73 additions & 0 deletions docs/resources/custom_stack_run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "plural_custom_stack_run Resource - terraform-provider-plural"
subcategory: ""
description: |-
---

# plural_custom_stack_run (Resource)





<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) Human-readable name of this custom run.

### Optional

- `commands` (Attributes Set) The commands for this custom run. (see [below for nested schema](#nestedatt--commands))
- `configuration` (Attributes Set) Self-service configuration which will be presented in UI before triggering. (see [below for nested schema](#nestedatt--configuration))
- `documentation` (String) Extended documentation to explain what this will do.
- `stack_id` (String) The ID of the stack to attach it to.

### Read-Only

- `id` (String) Internal identifier of this custom run.

<a id="nestedatt--commands"></a>
### Nested Schema for `commands`

Required:

- `cmd` (String) Command to run.

Optional:

- `args` (Set of String) Arguments to pass to the command when executing it.
- `dir` (String)


<a id="nestedatt--configuration"></a>
### Nested Schema for `configuration`

Required:

- `name` (String)
- `type` (String)

Optional:

- `condition` (Attributes) (see [below for nested schema](#nestedatt--configuration--condition))
- `default` (String)
- `documentation` (String)
- `longform` (String)
- `optional` (Boolean)
- `placeholder` (String)

<a id="nestedatt--configuration--condition"></a>
### Nested Schema for `configuration.condition`

Required:

- `field` (String)
- `operation` (String)

Optional:

- `value` (String)
15 changes: 15 additions & 0 deletions docs/resources/infrastructure_stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ description: |-

### Optional

- `actor` (String) The User email to use for default Plural authentication in this stack.
- `approval` (Boolean) Determines whether to require approval.
- `bindings` (Attributes) Read and write policies of this stack. (see [below for nested schema](#nestedatt--bindings))
- `detach` (Boolean) Determines behavior during resource destruction, if true it will detach resource instead of deleting it.
Expand All @@ -45,8 +46,22 @@ Required:

Optional:

- `hooks` (Attributes Set) The hooks to customize execution for this stack. (see [below for nested schema](#nestedatt--configuration--hooks))
- `image` (String) Optional custom image you might want to use.

<a id="nestedatt--configuration--hooks"></a>
### Nested Schema for `configuration.hooks`

Required:

- `after_stage` (String)
- `cmd` (String)

Optional:

- `args` (List of String) Arguments to pass to the command when executing it.



<a id="nestedatt--repository"></a>
### Nested Schema for `repository`
Expand Down
70 changes: 70 additions & 0 deletions example/customstackrun/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
terraform {
required_providers {
plural = {
source = "pluralsh/plural"
version = "0.2.1"
}
}
}

provider "plural" {
use_cli = true
}

data "plural_cluster" "cluster" {
handle = "mgmt"
}

data "plural_git_repository" "repository" {
url = "https://github.com/zreigz/tf-hello.git"
}

resource "random_string" "random" {
length = 5
upper = false
special = false
}

resource "plural_infrastructure_stack" "stack" {
name = "stack-tf-${random_string.random.result}"
type = "TERRAFORM"
detach = true
cluster_id = data.plural_cluster.cluster.id
repository = {
id = data.plural_git_repository.repository.id
ref = "main"
folder = "terraform"
}
configuration = {
version = "1.8.1"
}
}

resource "plural_custom_stack_run" "run-full" {
name = "run-tf-full-${random_string.random.result}"
documentation = "test"
stack_id = plural_infrastructure_stack.stack.id
commands = [{
cmd = "ls"
args = ["-al"]
dir = "/"
}]
configuration = [{
type = "STRING"
name = "author"
default = "john"
documentation = "author name"
longform = "author name"
placeholder = "author name, i.e. john"
optional = true
condition = {
operation = "PREFIX"
field = "author"
value = "j"
}
}]
}

resource "plural_custom_stack_run" "run-minimal" {
name = "run-tf-minimal-${random_string.random.result}"
}
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.12.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/mitchellh/go-homedir v1.1.0
github.com/pluralsh/console-client-go v0.5.14
github.com/pluralsh/console-client-go v0.5.16
github.com/pluralsh/plural-cli v0.8.5-0.20240216094552-efc34ee6de37
github.com/pluralsh/polly v0.1.7
github.com/samber/lo v1.38.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -856,8 +856,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pluralsh/console-client-go v0.5.14 h1:JgpFSx481O4Od63iIbj3+hKBn+JW/WyAZrJOofFBPpk=
github.com/pluralsh/console-client-go v0.5.14/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
github.com/pluralsh/console-client-go v0.5.16 h1:AHBnis/xUdXbUclNH1GUwcqAsCOzHzOtwetKOIS0dTM=
github.com/pluralsh/console-client-go v0.5.16/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
github.com/pluralsh/gqlclient v1.11.0 h1:FfXW7FiEJLHOfTAa7NxDb8jb3aMZNIpCAcG+bg8uHYA=
github.com/pluralsh/gqlclient v1.11.0/go.mod h1:qSXKUlio1F2DRPy8el4oFYsmpKbkUYspgPB87T4it5I=
github.com/pluralsh/plural-cli v0.8.5-0.20240216094552-efc34ee6de37 h1:DBnaKvKmbTbKwbkrh/2gJBwyHYfaXdxeT3UGh+94K4g=
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func (p *PluralProvider) Resources(_ context.Context) []func() resource.Resource
r.NewServiceDeploymentResource,
r.NewServiceContextResource,
r.NewInfrastructureStackResource,
r.NewCustomStackRunResource,
}
}

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

import (
"context"
"fmt"

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

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
)

var _ resource.Resource = &CustomStackRunResource{}
var _ resource.ResourceWithImportState = &CustomStackRunResource{}

func NewCustomStackRunResource() resource.Resource {
return &CustomStackRunResource{}
}

// CustomStackRunResource defines the custom stack run resource implementation.
type CustomStackRunResource struct {
client *client.Client
}

func (r *CustomStackRunResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_custom_stack_run"
}

func (r *CustomStackRunResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = r.schema()
}

func (r *CustomStackRunResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

data, ok := req.ProviderData.(*common.ProviderData)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Custom Stack Run Resource Configure Type",
fmt.Sprintf("Expected *common.ProviderData, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

r.client = data.Client
}

func (r *CustomStackRunResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
data := new(customStackRun)
resp.Diagnostics.Append(req.Plan.Get(ctx, data)...)
if resp.Diagnostics.HasError() {
return
}

attr, err := data.Attributes(ctx, resp.Diagnostics, r.client)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get attributes, got error: %s", err))
return
}
sd, err := r.client.CreateCustomStackRun(ctx, *attr)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create custom stack run, got error: %s", err))
return
}

data.From(sd.CreateCustomStackRun, ctx, resp.Diagnostics)
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *CustomStackRunResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
data := new(customStackRun)
resp.Diagnostics.Append(req.State.Get(ctx, data)...)
if resp.Diagnostics.HasError() {
return
}

response, err := r.client.GetCustomStackRun(ctx, data.Id.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read custom stack run, got error: %s", err))
return
}

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

func (r *CustomStackRunResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
data := new(customStackRun)
resp.Diagnostics.Append(req.Plan.Get(ctx, data)...)
if resp.Diagnostics.HasError() {
return
}

attr, err := data.Attributes(ctx, resp.Diagnostics, r.client)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get attributes, got error: %s", err))
return
}
_, err = r.client.UpdateCustomStackRun(ctx, data.Id.ValueString(), *attr)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update custom stack run, got error: %s", err))
return
}

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

func (r *CustomStackRunResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
data := new(customStackRun)
resp.Diagnostics.Append(req.State.Get(ctx, data)...)
if resp.Diagnostics.HasError() {
return
}

_, err := r.client.DeleteCustomStackRun(ctx, data.Id.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete custom stack run, got error: %s", err))
return
}
}

func (r *CustomStackRunResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}
Loading

0 comments on commit 0011626

Please sign in to comment.