Skip to content

Commit

Permalink
Merge pull request #36 from pluralsh/stack-actor-hooks
Browse files Browse the repository at this point in the history
feat: extend stacks for hooks and actor
  • Loading branch information
zreigz authored Jun 3, 2024
2 parents aebf17d + 789b107 commit 59b382d
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 14 deletions.
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.3
github.com/pluralsh/console-client-go v0.5.14
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
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -856,10 +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.4.0 h1:lgKaVGi8jB7S8wFF6L3P6H/4Xc88e4FozhyW58O1w3Q=
github.com/pluralsh/console-client-go v0.4.0/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
github.com/pluralsh/console-client-go v0.5.3 h1:RB4XtKlvh8+BM5o1o0h+W6zHculBGbL6q5lI/yRnqJE=
github.com/pluralsh/console-client-go v0.5.3/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
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/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
14 changes: 12 additions & 2 deletions internal/resource/infrastructure_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ func (r *InfrastructureStackResource) Create(ctx context.Context, req resource.C
return
}

sd, err := r.client.CreateStack(ctx, data.Attributes(ctx, resp.Diagnostics))
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.CreateStack(ctx, *attr)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create infrastructure stack, got error: %s", err))
return
Expand Down Expand Up @@ -92,7 +97,12 @@ func (r *InfrastructureStackResource) Update(ctx context.Context, req resource.U
return
}

_, err := r.client.UpdateStack(ctx, data.Id.ValueString(), data.Attributes(ctx, resp.Diagnostics))
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.UpdateStack(ctx, data.Id.ValueString(), *attr)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update infrastructure stack, got error: %s", err))
return
Expand Down
98 changes: 91 additions & 7 deletions internal/resource/infrastructure_stack_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resource
import (
"context"

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

"github.com/hashicorp/terraform-plugin-framework/attr"
Expand All @@ -17,6 +18,7 @@ type infrastructureStack struct {
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Type types.String `tfsdk:"type"`
Actor types.String `tfsdk:"actor"`
Approval types.Bool `tfsdk:"approval"`
Detach types.Bool `tfsdk:"detach"`
ClusterId types.String `tfsdk:"cluster_id"`
Expand All @@ -28,21 +30,30 @@ type infrastructureStack struct {
Bindings *common.ClusterBindings `tfsdk:"bindings"`
}

func (is *infrastructureStack) Attributes(ctx context.Context, d diag.Diagnostics) gqlclient.StackAttributes {
return gqlclient.StackAttributes{
func (is *infrastructureStack) Attributes(ctx context.Context, d diag.Diagnostics, client *client.Client) (*gqlclient.StackAttributes, error) {
attr := &gqlclient.StackAttributes{
Name: is.Name.ValueString(),
Type: gqlclient.StackType(is.Type.ValueString()),
RepositoryID: is.Repository.Id.ValueString(),
ClusterID: is.ClusterId.ValueString(),
Git: is.Repository.Attributes(),
JobSpec: is.JobSpec.Attributes(ctx, d),
Configuration: is.Configuration.Attributes(),
Configuration: is.Configuration.Attributes(ctx, d),
Approval: is.Approval.ValueBoolPointer(),
ReadBindings: is.Bindings.ReadAttributes(ctx, d),
WriteBindings: is.Bindings.WriteAttributes(ctx, d),
Files: is.FilesAttributes(ctx, d),
Environment: is.EnvironmentAttributes(ctx, d),
}
if !is.Actor.IsNull() {
user, err := client.GetUser(ctx, is.Actor.ValueString())
if err != nil {
return nil, err
}
attr.ActorID = &user.User.ID
}

return attr, nil
}

func (is *infrastructureStack) FilesAttributes(ctx context.Context, d diag.Diagnostics) []*gqlclient.StackFileAttributes {
Expand Down Expand Up @@ -88,7 +99,7 @@ func (is *infrastructureStack) From(stack *gqlclient.InfrastructureStackFragment
is.Approval = types.BoolPointerValue(stack.Approval)
is.ClusterId = types.StringValue(stack.Cluster.ID)
is.Repository.From(stack.Repository, stack.Git)
is.Configuration.From(stack.Configuration)
is.Configuration.From(ctx, stack.Configuration, d)
is.Files = infrastructureStackFilesFrom(stack.Files, is.Files, d)
is.Environment = infrastructureStackEnvironmentsFrom(stack.Environment, is.Environment, ctx, d)
is.Bindings.From(stack.ReadBindings, stack.WriteBindings, ctx, d)
Expand Down Expand Up @@ -168,29 +179,102 @@ func (isr *InfrastructureStackRepository) From(repository *gqlclient.GitReposito
isr.Folder = types.StringValue(ref.Folder)
}

type InfrastructureStackHookSpec struct {
// the command this hook will execute
Cmd types.String `tfsdk:"cmd"`

// optional arguments to pass to the command
Args types.List `tfsdk:"args"`

AfterStage types.String `tfsdk:"after_stage"`
}

var InfrastructureStackHookTypes = map[string]attr.Type{
"cmd": types.StringType,
"args": types.ListType{ElemType: types.StringType},
"after_stage": types.StringType,
}

func infrastructureStackHooksFrom(ctx context.Context, hooks []*gqlclient.StackHookFragment, configHooks types.Set, d diag.Diagnostics) types.Set {
if len(hooks) == 0 {
return configHooks
}

values := make([]attr.Value, len(hooks))

for i, h := range hooks {
objValue, diags := types.ObjectValueFrom(ctx, InfrastructureStackHookTypes, InfrastructureStackHookSpec{
Cmd: types.StringValue(h.Cmd),
Args: infrastructureStackContainerSpecArgsFrom(h.Args, ctx, d),
AfterStage: types.StringValue(h.AfterStage.String()),
})
values[i] = objValue
d.Append(diags...)
}

setValue, diags := types.SetValue(basetypes.ObjectType{AttrTypes: InfrastructureStackHookTypes}, values)
d.Append(diags...)
return setValue
}

func (sh *InfrastructureStackHookSpec) Attributes(ctx context.Context, d diag.Diagnostics) *gqlclient.StackHookAttributes {
if sh == nil {
return &gqlclient.StackHookAttributes{}
}

args := make([]types.String, len(sh.Args.Elements()))
d.Append(sh.Args.ElementsAs(ctx, &args, false)...)
return &gqlclient.StackHookAttributes{
Cmd: sh.Cmd.ValueString(),
Args: algorithms.Map(args, func(v types.String) *string {
return v.ValueStringPointer()
}),
AfterStage: gqlclient.StepStage(sh.AfterStage.ValueString()),
}
}

type InfrastructureStackConfiguration struct {
Image types.String `tfsdk:"image"`
Version types.String `tfsdk:"version"`
Hooks types.Set `tfsdk:"hooks"`
}

func (isc *InfrastructureStackConfiguration) HooksAttributes(ctx context.Context, d diag.Diagnostics) []*gqlclient.StackHookAttributes {
if isc.Hooks.IsNull() {
return nil
}

result := make([]*gqlclient.StackHookAttributes, 0, len(isc.Hooks.Elements()))
elements := make([]InfrastructureStackHookSpec, len(isc.Hooks.Elements()))
d.Append(isc.Hooks.ElementsAs(ctx, &elements, false)...)

for _, hook := range elements {
result = append(result, hook.Attributes(ctx, d))
}

return result
}

func (isc *InfrastructureStackConfiguration) Attributes() gqlclient.StackConfigurationAttributes {
func (isc *InfrastructureStackConfiguration) Attributes(ctx context.Context, d diag.Diagnostics) gqlclient.StackConfigurationAttributes {
if isc == nil {
return gqlclient.StackConfigurationAttributes{}
}

return gqlclient.StackConfigurationAttributes{
Image: isc.Image.ValueStringPointer(),
Version: isc.Version.ValueString(),
Version: isc.Version.ValueStringPointer(),
Hooks: isc.HooksAttributes(ctx, d),
}
}

func (isc *InfrastructureStackConfiguration) From(configuration *gqlclient.StackConfigurationFragment) {
func (isc *InfrastructureStackConfiguration) From(ctx context.Context, configuration *gqlclient.StackConfigurationFragment, d diag.Diagnostics) {
if isc == nil || configuration == nil {
return
}

isc.Image = types.StringPointerValue(configuration.Image)
isc.Version = types.StringValue(configuration.Version)
isc.Hooks = infrastructureStackHooksFrom(ctx, configuration.Hooks, isc.Hooks, d)
}

type InfrastructureStackEnvironment struct {
Expand Down
26 changes: 26 additions & 0 deletions internal/resource/infrastructure_stack_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func (r *InfrastructureStackResource) schema() schema.Schema {
Computed: true,
Default: booldefault.StaticBool(false),
},
"actor": schema.StringAttribute{
Description: "The User email to use for default Plural authentication in this stack.",
MarkdownDescription: "The User email to use for default Plural authentication in this stack.",
Optional: true,
},
"cluster_id": schema.StringAttribute{
Description: "The cluster on which the stack will be applied.",
MarkdownDescription: "The cluster on which the stack will be applied.",
Expand Down Expand Up @@ -94,6 +99,27 @@ func (r *InfrastructureStackResource) schema() schema.Schema {
MarkdownDescription: "The semver of the tool you wish to use.",
Required: true,
},
"hooks": schema.SetNestedAttribute{
Description: "The hooks to customize execution for this stack.",
MarkdownDescription: "The hooks to customize execution for this stack.",
Optional: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"cmd": schema.StringAttribute{
Required: true,
},
"args": schema.ListAttribute{
Description: "Arguments to pass to the command when executing it.",
MarkdownDescription: "Arguments to pass to the command when executing it.",
Optional: true,
ElementType: types.StringType,
},
"after_stage": schema.StringAttribute{
Required: true,
},
},
},
},
},
},
"files": schema.MapAttribute{
Expand Down

0 comments on commit 59b382d

Please sign in to comment.