diff --git a/internal/provider/cloudprovider_gcp_resource.go b/internal/provider/cloudprovider_gcp_resource.go index 02e0cf7..36c2619 100644 --- a/internal/provider/cloudprovider_gcp_resource.go +++ b/internal/provider/cloudprovider_gcp_resource.go @@ -8,12 +8,14 @@ import ( "fmt" "terraform-provider-tlspc/internal/tlspc" + "terraform-provider-tlspc/internal/validators" "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" ) @@ -60,6 +62,9 @@ func (r *cloudProviderGCPResource) Schema(_ context.Context, _ resource.SchemaRe "team": schema.StringAttribute{ Required: true, MarkdownDescription: "The ID of the owning Team", + Validators: []validator.String{ + validators.Uuid(), + }, }, "service_account_email": schema.StringAttribute{ Required: true, diff --git a/internal/provider/firefly_config_resource.go b/internal/provider/firefly_config_resource.go index 80c7806..cc35a57 100644 --- a/internal/provider/firefly_config_resource.go +++ b/internal/provider/firefly_config_resource.go @@ -8,12 +8,15 @@ import ( "fmt" "terraform-provider-tlspc/internal/tlspc" + "terraform-provider-tlspc/internal/validators" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "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" ) @@ -52,16 +55,25 @@ func (r *fireflyConfigResource) Schema(_ context.Context, _ resource.SchemaReque "subca_provider": schema.StringAttribute{ Required: true, MarkdownDescription: "The ID of the Firefly SubCA Provider", + Validators: []validator.String{ + validators.Uuid(), + }, }, "service_accounts": schema.SetAttribute{ Required: true, ElementType: types.StringType, MarkdownDescription: "A list of service account IDs", + Validators: []validator.Set{ + setvalidator.ValueStringsAre(validators.Uuid()), + }, }, "policies": schema.SetAttribute{ Required: true, ElementType: types.StringType, MarkdownDescription: "A list of Firefly Issuance Policy IDs", + Validators: []validator.Set{ + setvalidator.ValueStringsAre(validators.Uuid()), + }, }, }, } diff --git a/internal/provider/registry_account_resource.go b/internal/provider/registry_account_resource.go index 22f08e4..cd96d91 100644 --- a/internal/provider/registry_account_resource.go +++ b/internal/provider/registry_account_resource.go @@ -8,12 +8,14 @@ import ( "fmt" "terraform-provider-tlspc/internal/tlspc" + "terraform-provider-tlspc/internal/validators" "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" ) @@ -52,6 +54,9 @@ func (r *registryAccountResource) Schema(_ context.Context, _ resource.SchemaReq "owner": schema.StringAttribute{ Required: true, MarkdownDescription: "ID of the team that owns this service account", + Validators: []validator.String{ + validators.Uuid(), + }, }, "scopes": schema.SetAttribute{ Required: true, diff --git a/internal/provider/service_account_resource.go b/internal/provider/service_account_resource.go index e3aae1e..205098f 100644 --- a/internal/provider/service_account_resource.go +++ b/internal/provider/service_account_resource.go @@ -8,12 +8,15 @@ import ( "fmt" "terraform-provider-tlspc/internal/tlspc" + "terraform-provider-tlspc/internal/validators" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "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" ) @@ -52,6 +55,9 @@ func (r *serviceAccountResource) Schema(_ context.Context, _ resource.SchemaRequ "owner": schema.StringAttribute{ Required: true, MarkdownDescription: "ID of the team that owns this service account", + Validators: []validator.String{ + validators.Uuid(), + }, }, "scopes": schema.SetAttribute{ Required: true, @@ -92,6 +98,9 @@ A list of scopes that this service account is authorised for. Available options Optional: true, ElementType: types.StringType, MarkdownDescription: "List of Applications which this service account is authorised for", + Validators: []validator.Set{ + setvalidator.ValueStringsAre(validators.Uuid()), + }, }, }, } diff --git a/internal/provider/team_resource.go b/internal/provider/team_resource.go index 555f928..c122fbd 100644 --- a/internal/provider/team_resource.go +++ b/internal/provider/team_resource.go @@ -9,7 +9,9 @@ import ( "reflect" "terraform-provider-tlspc/internal/tlspc" + "terraform-provider-tlspc/internal/validators" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -64,6 +66,9 @@ func (r *teamResource) Schema(_ context.Context, _ resource.SchemaRequest, resp Required: true, ElementType: types.StringType, MarkdownDescription: "List of user ids", + Validators: []validator.Set{ + setvalidator.ValueStringsAre(validators.Uuid()), + }, }, "user_matching_rules": schema.SetNestedAttribute{ Optional: true, diff --git a/internal/validators/uuid.go b/internal/validators/uuid.go new file mode 100644 index 0000000..3dce140 --- /dev/null +++ b/internal/validators/uuid.go @@ -0,0 +1,48 @@ +// Copyright (c) Venafi, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validators + +import ( + "context" + "fmt" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +func Uuid() uuidValidator { + return uuidValidator{} +} + +type uuidValidator struct { +} + +// Description returns a plain text description of the validator's behavior, suitable for a practitioner to understand its impact. +func (v uuidValidator) Description(ctx context.Context) string { + return "string must be a uuid" +} + +// MarkdownDescription returns a markdown formatted description of the validator's behavior, suitable for a practitioner to understand its impact. +func (v uuidValidator) MarkdownDescription(ctx context.Context) string { + return "string must be a uuid" +} + +// Validate runs the main validation logic of the validator, reading configuration data out of `req` and updating `resp` with diagnostics. +func (v uuidValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + // If the value is unknown or null, there is nothing to validate. + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { + return + } + + if err := uuid.Validate(req.ConfigValue.ValueString()); err != nil { + + resp.Diagnostics.AddAttributeError( + req.Path, + "Invalid uuid", + fmt.Sprintf("String must be a uuid: %s", err), + ) + + return + } +}