From 78c491e9565d2965f6e3d9edc2edf10a283f3487 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 10:16:58 +0200 Subject: [PATCH 01/14] use new client --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1965dd1..55d06d2 100644 --- a/go.mod +++ b/go.mod @@ -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.15.0 + github.com/pluralsh/console/go/client v1.21.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 diff --git a/go.sum b/go.sum index 281cebc..6df234f 100644 --- a/go.sum +++ b/go.sum @@ -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.15.0 h1:dFbTGs6648o1VfaS5ZwBcXOKfQUtjIDCs9/8l13PsXU= -github.com/pluralsh/console/go/client v1.15.0/go.mod h1:lpoWASYsM9keNePS3dpFiEisUHEfObIVlSL3tzpKn8k= +github.com/pluralsh/console/go/client v1.21.0 h1:l7gltTPY8gR4qhK0RV8WYBP3MdpwJe96AIclTti9Hz0= +github.com/pluralsh/console/go/client v1.21.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= From 95eeafd9a6aa89f34d79efe15d08c3c3378d2dd8 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 11:29:48 +0200 Subject: [PATCH 02/14] add model --- internal/common/set.go | 18 +++++++++++ internal/model/custom_stack_run.go | 13 ++------ internal/model/oidc_provider.go | 49 ++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 internal/common/set.go create mode 100644 internal/model/oidc_provider.go diff --git a/internal/common/set.go b/internal/common/set.go new file mode 100644 index 0000000..92f63c4 --- /dev/null +++ b/internal/common/set.go @@ -0,0 +1,18 @@ +package common + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func SetFrom(values []*string, ctx context.Context, d diag.Diagnostics) types.Set { + if values == nil { + return types.SetNull(types.StringType) + } + + setValue, diags := types.SetValueFrom(ctx, types.StringType, values) + d.Append(diags...) + return setValue +} diff --git a/internal/model/custom_stack_run.go b/internal/model/custom_stack_run.go index d5d31d8..4de3070 100644 --- a/internal/model/custom_stack_run.go +++ b/internal/model/custom_stack_run.go @@ -4,6 +4,7 @@ import ( "context" "terraform-provider-plural/internal/client" + "terraform-provider-plural/internal/common" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -116,7 +117,7 @@ func commandsFrom(commands []*gqlclient.StackCommandFragment, config types.Set, for i, command := range commands { objValue, diags := types.ObjectValueFrom(ctx, CustomStackRunCommandAttrTypes, CustomStackRunCommand{ Cmd: types.StringValue(command.Cmd), - Args: commandArgsFrom(command.Args, ctx, d), + Args: common.SetFrom(command.Args, ctx, d), Dir: types.StringPointerValue(command.Dir), }) values[i] = objValue @@ -128,16 +129,6 @@ func commandsFrom(commands []*gqlclient.StackCommandFragment, config types.Set, return setValue } -func commandArgsFrom(values []*string, ctx context.Context, d diag.Diagnostics) types.Set { - if values == nil { - return types.SetNull(types.StringType) - } - - setValue, diags := types.SetValueFrom(ctx, types.StringType, values) - d.Append(diags...) - return setValue -} - type CustomStackRunConfiguration struct { Type types.String `tfsdk:"type"` Name types.String `tfsdk:"name"` diff --git a/internal/model/oidc_provider.go b/internal/model/oidc_provider.go new file mode 100644 index 0000000..15c5331 --- /dev/null +++ b/internal/model/oidc_provider.go @@ -0,0 +1,49 @@ +package model + +import ( + "context" + + "terraform-provider-plural/internal/common" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + gqlclient "github.com/pluralsh/console/go/client" + "github.com/pluralsh/polly/algorithms" +) + +type OIDCProvider struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Type types.String `tfsdk:"type"` + Description types.String `tfsdk:"description"` + ClientID types.String `tfsdk:"clientID"` + ClientSecret types.String `tfsdk:"clientSecret"` + RedirectURIs types.Set `tfsdk:"redirectURIs"` +} + +func (p *OIDCProvider) Attributes(ctx context.Context, d diag.Diagnostics) gqlclient.OidcProviderAttributes { + return gqlclient.OidcProviderAttributes{ + Name: p.Name.ValueString(), + Description: p.Description.ValueStringPointer(), + RedirectUris: p.redirectURIsAttribute(ctx, d), + } +} + +func (p *OIDCProvider) redirectURIsAttribute(ctx context.Context, d diag.Diagnostics) []*string { + redirectURIs := make([]types.String, len(p.RedirectURIs.Elements())) + d.Append(p.RedirectURIs.ElementsAs(ctx, &redirectURIs, false)...) + return algorithms.Map(redirectURIs, func(v types.String) *string { return v.ValueStringPointer() }) +} + +func (p *OIDCProvider) TypeAttribute() gqlclient.OidcProviderType { + return gqlclient.OidcProviderType(p.Type.ValueString()) +} + +func (p *OIDCProvider) From(response *gqlclient.OIDCProviderFragment, ctx context.Context, d diag.Diagnostics) { + p.ID = types.StringValue(response.ID) + p.Name = types.StringValue(response.Name) + p.Description = types.StringPointerValue(response.Description) + p.ClientID = types.StringValue(response.ClientID) + p.ClientSecret = types.StringValue(response.ClientSecret) + p.RedirectURIs = common.SetFrom(response.RedirectUris, ctx, d) +} From c51e03cd5b4079dbfaa700beaf8de6c6c0159645 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 11:45:45 +0200 Subject: [PATCH 03/14] add resource --- internal/provider/provider.go | 1 + internal/resource/oidc_provider.go | 150 +++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 internal/resource/oidc_provider.go diff --git a/internal/provider/provider.go b/internal/provider/provider.go index f582a25..d30c659 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -194,6 +194,7 @@ func (p *PluralProvider) Resources(_ context.Context) []func() resource.Resource r.NewPrAutomationTriggerResource, r.NewStackRunTriggerResource, r.NewSharedSecretResource, + r.NewOIDCProviderResourceResource, } } diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go new file mode 100644 index 0000000..70ceafd --- /dev/null +++ b/internal/resource/oidc_provider.go @@ -0,0 +1,150 @@ +package resource + +import ( + "context" + "fmt" + + "terraform-provider-plural/internal/client" + "terraform-provider-plural/internal/common" + "terraform-provider-plural/internal/model" + + "github.com/hashicorp/terraform-plugin-framework/path" + "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/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ resource.Resource = &OIDCProviderResource{} +var _ resource.ResourceWithImportState = &OIDCProviderResource{} + +func NewOIDCProviderResourceResource() resource.Resource { + return &OIDCProviderResource{} +} + +// OIDCProviderResource defines the OIDC provider resource implementation. +type OIDCProviderResource struct { + client *client.Client +} + +func (r *OIDCProviderResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_oidc_provider" +} + +func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "Internal identifier of this OIDC provider.", + MarkdownDescription: "Internal identifier of this OIDC provider.", + Computed: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "name": schema.StringAttribute{ + Description: "Human-readable name of this OIDC provider.", + MarkdownDescription: "Human-readable name of this OIDC provider.", + Required: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "type": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "description": schema.StringAttribute{ + Description: "Description of this OIDC provider.", + MarkdownDescription: "Description of this OIDC provider.", + Optional: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "clientID": schema.StringAttribute{ + Computed: true, + Sensitive: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "clientSecret": schema.StringAttribute{ + Computed: true, + Sensitive: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "redirectURIs": schema.SetAttribute{ + Optional: true, + ElementType: types.StringType, + }, + }, + } +} + +func (r *OIDCProviderResource) 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 OIDC Provider 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 *OIDCProviderResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + data := new(model.OIDCProvider) + resp.Diagnostics.Append(req.Plan.Get(ctx, data)...) + if resp.Diagnostics.HasError() { + return + } + + result, err := r.client.CreateOIDCProvider(ctx, data.TypeAttribute(), data.Attributes(ctx, resp.Diagnostics)) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create OIDC provider, got error: %s", err)) + return + } + + data.From(result.CreateOidcProvider, ctx, resp.Diagnostics) + resp.Diagnostics.Append(resp.State.Set(ctx, data)...) +} + +func (r *OIDCProviderResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) { + // Ignore. +} + +func (r *OIDCProviderResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + data := new(model.OIDCProvider) + resp.Diagnostics.Append(req.Plan.Get(ctx, data)...) + if resp.Diagnostics.HasError() { + return + } + + result, err := r.client.UpdateOIDCProvider(ctx, data.ID.ValueString(), data.TypeAttribute(), data.Attributes(ctx, resp.Diagnostics)) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update OIDC provider, got error: %s", err)) + return + } + + data.From(result.UpdateOidcProvider, ctx, resp.Diagnostics) + resp.Diagnostics.Append(resp.State.Set(ctx, data)...) +} + +func (r *OIDCProviderResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + data := new(model.OIDCProvider) + resp.Diagnostics.Append(req.State.Get(ctx, data)...) + if resp.Diagnostics.HasError() { + return + } + + _, err := r.client.DeleteOIDCProvider(ctx, data.ID.ValueString(), data.TypeAttribute()) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete OIDC provider, got error: %s", err)) + return + } +} + +func (r *OIDCProviderResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} From 31f4401b3b8564814d5d2b2a7cdc0d0a6fe8a9cc Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 12:01:53 +0200 Subject: [PATCH 04/14] add example --- example/oidcprovider/main.tf | 19 +++++++++++++++++++ internal/model/oidc_provider.go | 6 +++--- internal/resource/oidc_provider.go | 6 +++--- 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 example/oidcprovider/main.tf diff --git a/example/oidcprovider/main.tf b/example/oidcprovider/main.tf new file mode 100644 index 0000000..b03bd69 --- /dev/null +++ b/example/oidcprovider/main.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + plural = { + source = "pluralsh/plural" + version = "0.2.1" + } + } +} + +provider "plural" { + use_cli = true +} + +resource "plural_oidc_provider" "provider" { + name = "marcin" + type = "PLURAL" + description = "test provider" + redirect_uris = ["abc", "xyz"] +} diff --git a/internal/model/oidc_provider.go b/internal/model/oidc_provider.go index 15c5331..86eb829 100644 --- a/internal/model/oidc_provider.go +++ b/internal/model/oidc_provider.go @@ -16,9 +16,9 @@ type OIDCProvider struct { Name types.String `tfsdk:"name"` Type types.String `tfsdk:"type"` Description types.String `tfsdk:"description"` - ClientID types.String `tfsdk:"clientID"` - ClientSecret types.String `tfsdk:"clientSecret"` - RedirectURIs types.Set `tfsdk:"redirectURIs"` + ClientID types.String `tfsdk:"client_id"` + ClientSecret types.String `tfsdk:"client_secret"` + RedirectURIs types.Set `tfsdk:"redirect_uris"` } func (p *OIDCProvider) Attributes(ctx context.Context, d diag.Diagnostics) gqlclient.OidcProviderAttributes { diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index 70ceafd..062e195 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -57,17 +57,17 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques Optional: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "clientID": schema.StringAttribute{ + "client_id": schema.StringAttribute{ Computed: true, Sensitive: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "clientSecret": schema.StringAttribute{ + "client_secret": schema.StringAttribute{ Computed: true, Sensitive: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "redirectURIs": schema.SetAttribute{ + "redirect_uris": schema.SetAttribute{ Optional: true, ElementType: types.StringType, }, From b1c1ad96f3b6e654e2fd232914f4f577d6db3977 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 12:10:00 +0200 Subject: [PATCH 05/14] validate type enum --- internal/resource/oidc_provider.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index 062e195..6197625 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -8,12 +8,16 @@ import ( "terraform-provider-plural/internal/common" "terraform-provider-plural/internal/model" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/path" "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/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + gqlclient "github.com/pluralsh/console/go/client" + "github.com/pluralsh/polly/algorithms" ) var _ resource.Resource = &OIDCProviderResource{} @@ -50,6 +54,8 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques "type": schema.StringAttribute{ Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + Validators: []validator.String{stringvalidator.OneOfCaseInsensitive( + algorithms.Map(gqlclient.AllOidcProviderType, func(t gqlclient.OidcProviderType) string { return string(t) })...)}, }, "description": schema.StringAttribute{ Description: "Description of this OIDC provider.", From 4af1bf0b9d5f4b64c4da3ded803aa9da263a5473 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 12:10:30 +0200 Subject: [PATCH 06/14] format --- internal/resource/oidc_provider.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index 6197625..07d4a70 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -54,8 +54,11 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques "type": schema.StringAttribute{ Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, - Validators: []validator.String{stringvalidator.OneOfCaseInsensitive( - algorithms.Map(gqlclient.AllOidcProviderType, func(t gqlclient.OidcProviderType) string { return string(t) })...)}, + Validators: []validator.String{ + stringvalidator.OneOfCaseInsensitive( + algorithms.Map(gqlclient.AllOidcProviderType, + func(t gqlclient.OidcProviderType) string { return string(t) })...), + }, }, "description": schema.StringAttribute{ Description: "Description of this OIDC provider.", From 5efd6fd2eb831fa90e2257b88b81604e9d4acffa Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 9 Oct 2024 13:15:51 +0200 Subject: [PATCH 07/14] generate docs --- docs/resources/oidc_provider.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 docs/resources/oidc_provider.md diff --git a/docs/resources/oidc_provider.md b/docs/resources/oidc_provider.md new file mode 100644 index 0000000..a154868 --- /dev/null +++ b/docs/resources/oidc_provider.md @@ -0,0 +1,32 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "plural_oidc_provider Resource - terraform-provider-plural" +subcategory: "" +description: |- + +--- + +# plural_oidc_provider (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) Human-readable name of this OIDC provider. +- `type` (String) + +### Optional + +- `description` (String) Description of this OIDC provider. +- `redirect_uris` (Set of String) + +### Read-Only + +- `client_id` (String, Sensitive) +- `client_secret` (String, Sensitive) +- `id` (String) Internal identifier of this OIDC provider. From 72ebd1b8ce56434d3783e2079fa60122e192ed26 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 10 Oct 2024 10:55:07 +0200 Subject: [PATCH 08/14] update client --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 55d06d2..ee7e353 100644 --- a/go.mod +++ b/go.mod @@ -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.21.0 + github.com/pluralsh/console/go/client v1.21.1 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 diff --git a/go.sum b/go.sum index 6df234f..878f99f 100644 --- a/go.sum +++ b/go.sum @@ -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.21.0 h1:l7gltTPY8gR4qhK0RV8WYBP3MdpwJe96AIclTti9Hz0= -github.com/pluralsh/console/go/client v1.21.0/go.mod h1:lpoWASYsM9keNePS3dpFiEisUHEfObIVlSL3tzpKn8k= +github.com/pluralsh/console/go/client v1.21.1 h1:uYTc54qJbP/7tpsVG4pELasY/+05J+EO8yo7pMu9thw= +github.com/pluralsh/console/go/client v1.21.1/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= From 7c648d9b623617ec8848fe7b9847ee112ff72c48 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 10 Oct 2024 11:05:57 +0200 Subject: [PATCH 09/14] add auth method support --- internal/model/oidc_provider.go | 21 +++++++++++++++++++++ internal/resource/oidc_provider.go | 9 +++++++++ 2 files changed, 30 insertions(+) diff --git a/internal/model/oidc_provider.go b/internal/model/oidc_provider.go index 86eb829..4b76ddd 100644 --- a/internal/model/oidc_provider.go +++ b/internal/model/oidc_provider.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" gqlclient "github.com/pluralsh/console/go/client" "github.com/pluralsh/polly/algorithms" + "github.com/samber/lo" ) type OIDCProvider struct { @@ -18,6 +19,7 @@ type OIDCProvider struct { Description types.String `tfsdk:"description"` ClientID types.String `tfsdk:"client_id"` ClientSecret types.String `tfsdk:"client_secret"` + AuthMethod types.String `tfsdk:"auth_method"` RedirectURIs types.Set `tfsdk:"redirect_uris"` } @@ -25,10 +27,19 @@ func (p *OIDCProvider) Attributes(ctx context.Context, d diag.Diagnostics) gqlcl return gqlclient.OidcProviderAttributes{ Name: p.Name.ValueString(), Description: p.Description.ValueStringPointer(), + AuthMethod: p.authMethodAttribute(), RedirectUris: p.redirectURIsAttribute(ctx, d), } } +func (p *OIDCProvider) authMethodAttribute() *gqlclient.OidcAuthMethod { + if p.AuthMethod.IsNull() { + return nil + } + + return lo.ToPtr(gqlclient.OidcAuthMethod(p.AuthMethod.ValueString())) +} + func (p *OIDCProvider) redirectURIsAttribute(ctx context.Context, d diag.Diagnostics) []*string { redirectURIs := make([]types.String, len(p.RedirectURIs.Elements())) d.Append(p.RedirectURIs.ElementsAs(ctx, &redirectURIs, false)...) @@ -45,5 +56,15 @@ func (p *OIDCProvider) From(response *gqlclient.OIDCProviderFragment, ctx contex p.Description = types.StringPointerValue(response.Description) p.ClientID = types.StringValue(response.ClientID) p.ClientSecret = types.StringValue(response.ClientSecret) + p.AuthMethod = p.authMethodFrom(response.AuthMethod) p.RedirectURIs = common.SetFrom(response.RedirectUris, ctx, d) + +} + +func (p *OIDCProvider) authMethodFrom(authMethod *gqlclient.OidcAuthMethod) types.String { + if authMethod == nil { + return types.StringNull() + } + + return types.StringValue(string(*authMethod)) } diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index 07d4a70..e3c8e0c 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -76,6 +76,15 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques Sensitive: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, + "auth_method": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + Validators: []validator.String{ + stringvalidator.OneOfCaseInsensitive( + algorithms.Map(gqlclient.AllOidcAuthMethod, + func(t gqlclient.OidcAuthMethod) string { return string(t) })...), + }, + }, "redirect_uris": schema.SetAttribute{ Optional: true, ElementType: types.StringType, From 090d89669114c6455114d5f5b7fcedf63e75f5ac Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 10 Oct 2024 11:15:05 +0200 Subject: [PATCH 10/14] use case-sensitive checks --- internal/resource/oidc_provider.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index e3c8e0c..156b2a9 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -55,7 +55,7 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, Validators: []validator.String{ - stringvalidator.OneOfCaseInsensitive( + stringvalidator.OneOf( algorithms.Map(gqlclient.AllOidcProviderType, func(t gqlclient.OidcProviderType) string { return string(t) })...), }, @@ -80,7 +80,7 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques Optional: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, Validators: []validator.String{ - stringvalidator.OneOfCaseInsensitive( + stringvalidator.OneOf( algorithms.Map(gqlclient.AllOidcAuthMethod, func(t gqlclient.OidcAuthMethod) string { return string(t) })...), }, From 389ff9fe53a80a0aca4bc9f009925a1d604ce8df Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 10 Oct 2024 13:46:37 +0200 Subject: [PATCH 11/14] update example --- example/oidcprovider/main.tf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example/oidcprovider/main.tf b/example/oidcprovider/main.tf index b03bd69..83c88be 100644 --- a/example/oidcprovider/main.tf +++ b/example/oidcprovider/main.tf @@ -12,8 +12,9 @@ provider "plural" { } resource "plural_oidc_provider" "provider" { - name = "marcin" + name = "tf-test-provider" + auth_method = "BASIC" type = "PLURAL" description = "test provider" - redirect_uris = ["abc", "xyz"] + redirect_uris = ["localhost:8000"] } From d0c728078f8b2bf363fca8d704a89522e81a70e9 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Fri, 11 Oct 2024 10:24:10 +0200 Subject: [PATCH 12/14] adjust auth method schema --- internal/resource/oidc_provider.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index 156b2a9..c71e28b 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -13,6 +13,7 @@ import ( "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/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" @@ -78,6 +79,8 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques }, "auth_method": schema.StringAttribute{ Optional: true, + Computed: true, + Default: stringdefault.StaticString(string(gqlclient.OidcAuthMethodBasic)), PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, Validators: []validator.String{ stringvalidator.OneOf( From ff44da30b4778b84e1cac8a06a49eef957108684 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Fri, 11 Oct 2024 11:27:16 +0200 Subject: [PATCH 13/14] fix description handling --- internal/model/oidc_provider.go | 12 ++++++++++-- internal/resource/oidc_provider.go | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/model/oidc_provider.go b/internal/model/oidc_provider.go index 4b76ddd..fe63f25 100644 --- a/internal/model/oidc_provider.go +++ b/internal/model/oidc_provider.go @@ -26,12 +26,21 @@ type OIDCProvider struct { func (p *OIDCProvider) Attributes(ctx context.Context, d diag.Diagnostics) gqlclient.OidcProviderAttributes { return gqlclient.OidcProviderAttributes{ Name: p.Name.ValueString(), - Description: p.Description.ValueStringPointer(), + Description: p.descriptionAttribute(), AuthMethod: p.authMethodAttribute(), RedirectUris: p.redirectURIsAttribute(ctx, d), } } +func (p *OIDCProvider) descriptionAttribute() *string { + if p.Description.IsNull() { + // Setting to empty string as using null will have no effect even if it was deleted from config. + return lo.ToPtr("") + } + + return p.Description.ValueStringPointer() +} + func (p *OIDCProvider) authMethodAttribute() *gqlclient.OidcAuthMethod { if p.AuthMethod.IsNull() { return nil @@ -58,7 +67,6 @@ func (p *OIDCProvider) From(response *gqlclient.OIDCProviderFragment, ctx contex p.ClientSecret = types.StringValue(response.ClientSecret) p.AuthMethod = p.authMethodFrom(response.AuthMethod) p.RedirectURIs = common.SetFrom(response.RedirectUris, ctx, d) - } func (p *OIDCProvider) authMethodFrom(authMethod *gqlclient.OidcAuthMethod) types.String { diff --git a/internal/resource/oidc_provider.go b/internal/resource/oidc_provider.go index c71e28b..1bec9dc 100644 --- a/internal/resource/oidc_provider.go +++ b/internal/resource/oidc_provider.go @@ -65,7 +65,7 @@ func (r *OIDCProviderResource) Schema(_ context.Context, _ resource.SchemaReques Description: "Description of this OIDC provider.", MarkdownDescription: "Description of this OIDC provider.", Optional: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, }, "client_id": schema.StringAttribute{ Computed: true, From c984adc21e3c69804fb2822313e9fc7839206e92 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Fri, 11 Oct 2024 11:39:20 +0200 Subject: [PATCH 14/14] fix set from handling --- internal/common/set.go | 8 +++++--- internal/model/custom_stack_run.go | 2 +- internal/model/oidc_provider.go | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/common/set.go b/internal/common/set.go index 92f63c4..ff44b92 100644 --- a/internal/common/set.go +++ b/internal/common/set.go @@ -7,9 +7,11 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" ) -func SetFrom(values []*string, ctx context.Context, d diag.Diagnostics) types.Set { - if values == nil { - return types.SetNull(types.StringType) +func SetFrom(values []*string, config types.Set, ctx context.Context, d diag.Diagnostics) types.Set { + if len(values) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config } setValue, diags := types.SetValueFrom(ctx, types.StringType, values) diff --git a/internal/model/custom_stack_run.go b/internal/model/custom_stack_run.go index 4de3070..2a51ad4 100644 --- a/internal/model/custom_stack_run.go +++ b/internal/model/custom_stack_run.go @@ -117,7 +117,7 @@ func commandsFrom(commands []*gqlclient.StackCommandFragment, config types.Set, for i, command := range commands { objValue, diags := types.ObjectValueFrom(ctx, CustomStackRunCommandAttrTypes, CustomStackRunCommand{ Cmd: types.StringValue(command.Cmd), - Args: common.SetFrom(command.Args, ctx, d), + Args: common.SetFrom(command.Args, types.SetNull(types.StringType), ctx, d), Dir: types.StringPointerValue(command.Dir), }) values[i] = objValue diff --git a/internal/model/oidc_provider.go b/internal/model/oidc_provider.go index fe63f25..a5604ca 100644 --- a/internal/model/oidc_provider.go +++ b/internal/model/oidc_provider.go @@ -66,7 +66,7 @@ func (p *OIDCProvider) From(response *gqlclient.OIDCProviderFragment, ctx contex p.ClientID = types.StringValue(response.ClientID) p.ClientSecret = types.StringValue(response.ClientSecret) p.AuthMethod = p.authMethodFrom(response.AuthMethod) - p.RedirectURIs = common.SetFrom(response.RedirectUris, ctx, d) + p.RedirectURIs = common.SetFrom(response.RedirectUris, p.RedirectURIs, ctx, d) } func (p *OIDCProvider) authMethodFrom(authMethod *gqlclient.OidcAuthMethod) types.String {