From 2e2c21fb72fc189bb2e79f49926cdd170e99a6fd Mon Sep 17 00:00:00 2001 From: Lucas TESSON Date: Sun, 17 Dec 2023 20:44:28 +0100 Subject: [PATCH] feat: add support of `ctfd_challenge.function` --- .../provider-install-verification/main.tf | 1 + internal/provider/challenge/function.go | 10 ++++ internal/provider/challenge_data_source.go | 43 ++++++++++----- internal/provider/challenge_resource.go | 55 +++++++++++++------ 4 files changed, 76 insertions(+), 33 deletions(-) create mode 100644 internal/provider/challenge/function.go diff --git a/examples/provider-install-verification/main.tf b/examples/provider-install-verification/main.tf index b48b696..7e20e97 100644 --- a/examples/provider-install-verification/main.tf +++ b/examples/provider-install-verification/main.tf @@ -25,6 +25,7 @@ resource "ctfd_challenge" "http" { decay = 17 minimum = 50 state = "visible" + function = "logarithmic" flags = [{ content = "24HIUT{Http_1s_n0t_s3cuR3}" diff --git a/internal/provider/challenge/function.go b/internal/provider/challenge/function.go new file mode 100644 index 0000000..12ea7e7 --- /dev/null +++ b/internal/provider/challenge/function.go @@ -0,0 +1,10 @@ +// This file is related to the challenge.function attribute + +package challenge + +import "github.com/hashicorp/terraform-plugin-framework/types" + +var ( + FunctionLinear = types.StringValue("linear") + FunctionLogarithmic = types.StringValue("logarithmic") +) diff --git a/internal/provider/challenge_data_source.go b/internal/provider/challenge_data_source.go index ce35c11..382b294 100644 --- a/internal/provider/challenge_data_source.go +++ b/internal/provider/challenge_data_source.go @@ -57,6 +57,9 @@ func (ch *challengeDataSource) Schema(ctx context.Context, req datasource.Schema "description": schema.StringAttribute{ Computed: true, }, + "connection_info": schema.StringAttribute{ + Computed: true, + }, "value": schema.Int64Attribute{ Computed: true, }, @@ -69,6 +72,13 @@ func (ch *challengeDataSource) Schema(ctx context.Context, req datasource.Schema "minimum": schema.Int64Attribute{ Computed: true, }, + "max_attempts": schema.StringAttribute{ + Computed: true, + }, + "function": schema.StringAttribute{ + Computed: true, + }, + // TODO add support of next + requirements "state": schema.StringAttribute{ Computed: true, }, @@ -240,21 +250,24 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ } challState := challengeResourceModel{ - ID: types.StringValue(strconv.Itoa(chall.ID)), - Name: types.StringValue(chall.Name), - Category: types.StringValue(chall.Category), - Description: types.StringValue(chall.Description), - Value: types.Int64Value(int64(chall.Value)), - Initial: utils.ToTFInt64(chall.Initial), - Decay: utils.ToTFInt64(chall.Decay), - Minimum: utils.ToTFInt64(chall.Minimum), - State: types.StringValue(chall.State), - Type: types.StringValue(chall.Type), - Files: challFiles, - Flags: challFlags, - Tags: challTags, - Topics: challTopics, - Hints: challHints, + ID: types.StringValue(strconv.Itoa(chall.ID)), + Name: types.StringValue(chall.Name), + Category: types.StringValue(chall.Category), + Description: types.StringValue(chall.Description), + ConnectionInfo: utils.ToTFString(chall.ConnectionInfo), + MaxAttempts: utils.ToTFInt64(chall.MaxAttempts), + Function: types.StringValue(chall.Function), + Value: types.Int64Value(int64(chall.Value)), + Initial: utils.ToTFInt64(chall.Initial), + Decay: utils.ToTFInt64(chall.Decay), + Minimum: utils.ToTFInt64(chall.Minimum), + State: types.StringValue(chall.State), + Type: types.StringValue(chall.Type), + Files: challFiles, + Flags: challFlags, + Tags: challTags, + Topics: challTopics, + Hints: challHints, } state.ID = types.StringValue("placeholder") diff --git a/internal/provider/challenge_resource.go b/internal/provider/challenge_resource.go index 72ad6cb..982e0fe 100644 --- a/internal/provider/challenge_resource.go +++ b/internal/provider/challenge_resource.go @@ -12,6 +12,7 @@ import ( "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/defaults" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" @@ -37,24 +38,26 @@ type challengeResource struct { } type challengeResourceModel struct { - ID types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - Category types.String `tfsdk:"category"` - Description types.String `tfsdk:"description"` - ConnectionInfo types.String `tfsdk:"connection_info"` - MaxAttempts types.Int64 `tfsdk:"max_attempts"` - Value types.Int64 `tfsdk:"value"` - Initial types.Int64 `tfsdk:"initial"` - Decay types.Int64 `tfsdk:"decay"` - Minimum types.Int64 `tfsdk:"minimum"` - State types.String `tfsdk:"state"` - Type types.String `tfsdk:"type"` - Requirements *challenge.RequirementsSubresourceModel `tfsdk:"requirements"` - Flags []challenge.FlagSubresourceModel `tfsdk:"flags"` - Tags []types.String `tfsdk:"tags"` - Topics []types.String `tfsdk:"topics"` - Hints []challenge.HintSubresourceModel `tfsdk:"hints"` - Files []challenge.FileSubresourceModel `tfsdk:"files"` + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Category types.String `tfsdk:"category"` + Description types.String `tfsdk:"description"` + ConnectionInfo types.String `tfsdk:"connection_info"` + MaxAttempts types.Int64 `tfsdk:"max_attempts"` + Function types.String `tfsdk:"function"` + Value types.Int64 `tfsdk:"value"` + Initial types.Int64 `tfsdk:"initial"` + Decay types.Int64 `tfsdk:"decay"` + Minimum types.Int64 `tfsdk:"minimum"` + State types.String `tfsdk:"state"` + Type types.String `tfsdk:"type"` + // TODO add support of Next challenges + Requirements *challenge.RequirementsSubresourceModel `tfsdk:"requirements"` + Flags []challenge.FlagSubresourceModel `tfsdk:"flags"` + Tags []types.String `tfsdk:"tags"` + Topics []types.String `tfsdk:"topics"` + Hints []challenge.HintSubresourceModel `tfsdk:"hints"` + Files []challenge.FileSubresourceModel `tfsdk:"files"` } func (r *challengeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -91,6 +94,19 @@ func (r *challengeResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, Default: int64default.StaticInt64(0), }, + "function": schema.StringAttribute{ + Optional: true, + Computed: true, + Default: defaults.String(stringdefault.StaticString("linear")), + Description: "Decay function to define how the challenge's value will change through time.", + MarkdownDescription: "Decay function to define how the challenge's value will change through time.", + Validators: []validator.String{ + validators.NewStringEnumValidator([]basetypes.StringValue{ + challenge.FunctionLinear, + challenge.FunctionLogarithmic, + }), + }, + }, // TODO value can't be set side to , depends on .type value (respectively standard and dynamic) "value": schema.Int64Attribute{ Optional: true, @@ -214,6 +230,7 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque Description: data.Description.ValueString(), ConnectionInfo: data.ConnectionInfo.ValueStringPointer(), MaxAttempts: utils.ToInt(data.MaxAttempts), + Function: data.Function.ValueString(), Value: int(data.Value.ValueInt64()), Initial: utils.ToInt(data.Initial), Decay: utils.ToInt(data.Decay), @@ -330,6 +347,7 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, data.Description = types.StringValue(res.Description) data.ConnectionInfo = utils.ToTFString(res.ConnectionInfo) data.MaxAttempts = utils.ToTFInt64(res.MaxAttempts) + data.Function = types.StringValue(res.Function) data.Value = types.Int64Value(int64(res.Value)) data.Initial = utils.ToTFInt64(res.Initial) data.Decay = utils.ToTFInt64(res.Decay) @@ -500,6 +518,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque Description: data.Description.ValueString(), ConnectionInfo: data.ConnectionInfo.ValueStringPointer(), MaxAttempts: utils.ToInt(data.MaxAttempts), + Function: data.Function.ValueString(), // Value: int(data.Value.ToInt64Value()), // TODO add support of .value in PATCH /challenges Initial: utils.ToInt(data.Initial), Decay: utils.ToInt(data.Decay),