Skip to content

Commit 69ccfe3

Browse files
committed
Reject attempts to set supports_agentless when not supported
1 parent 920c022 commit 69ccfe3

File tree

9 files changed

+149
-37
lines changed

9 files changed

+149
-37
lines changed

internal/clients/api_client.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type CompositeId struct {
3333
ResourceId string
3434
}
3535

36+
const ServerlessFlavor = "serverless"
37+
3638
func CompositeIdFromStr(id string) (*CompositeId, diag.Diagnostics) {
3739
var diags diag.Diagnostics
3840
idParts := strings.Split(id, "/")
@@ -352,6 +354,24 @@ func (a *ApiClient) serverInfo(ctx context.Context) (*models.ClusterInfo, diag.D
352354
return &info, diags
353355
}
354356

357+
func (a *ApiClient) EnforceMinVersion(ctx context.Context, minVersion *version.Version) (bool, diag.Diagnostics) {
358+
flavor, diags := a.ServerFlavor(ctx)
359+
if diags.HasError() {
360+
return false, diags
361+
}
362+
363+
if flavor == ServerlessFlavor {
364+
return true, nil
365+
}
366+
367+
serverVersion, diags := a.ServerVersion(ctx)
368+
if diags.HasError() {
369+
return false, diags
370+
}
371+
372+
return serverVersion.GreaterThanOrEqual(minVersion), nil
373+
}
374+
355375
func (a *ApiClient) ServerVersion(ctx context.Context) (*version.Version, diag.Diagnostics) {
356376
if a.elasticsearch != nil {
357377
return a.versionFromElasticsearch(ctx)

internal/elasticsearch/index/index/models.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ func (model tfModel) toPutIndexParams(serverFlavor string) models.PutIndexParams
290290
Timeout: timeout,
291291
}
292292

293-
if serverFlavor != "serverless" {
293+
if serverFlavor != clients.ServerlessFlavor {
294294
params.WaitForActiveShards = model.WaitForActiveShards.ValueString()
295295
}
296296

internal/elasticsearch/index/index/models_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
fuzz "github.com/google/gofuzz"
99

10+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
1011
"github.com/elastic/terraform-provider-elasticstack/internal/models"
1112
"github.com/elastic/terraform-provider-elasticstack/internal/utils/customtypes"
1213
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
@@ -363,7 +364,7 @@ func Test_tfModel_toPutIndexParams(t *testing.T) {
363364

364365
flavor := "not_serverless"
365366
if isServerless {
366-
flavor = "serverless"
367+
flavor = clients.ServerlessFlavor
367368
expectedParams.WaitForActiveShards = ""
368369
}
369370

internal/fleet/agent_policy/create.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ func (r *agentPolicyResource) Create(ctx context.Context, req resource.CreateReq
2222
return
2323
}
2424

25-
sVersion, e := r.client.ServerVersion(ctx)
26-
if e != nil {
25+
feat, diags := r.buildFeatures(ctx)
26+
resp.Diagnostics.Append(diags...)
27+
if resp.Diagnostics.HasError() {
2728
return
2829
}
2930

30-
body, diags := planModel.toAPICreateModel(ctx, sVersion)
31+
body, diags := planModel.toAPICreateModel(ctx, feat)
3132
resp.Diagnostics.Append(diags...)
3233
if resp.Diagnostics.HasError() {
3334
return

internal/fleet/agent_policy/models.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ import (
88
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
99
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
1010

11-
"github.com/hashicorp/go-version"
1211
"github.com/hashicorp/terraform-plugin-framework/attr"
1312
"github.com/hashicorp/terraform-plugin-framework/diag"
1413
"github.com/hashicorp/terraform-plugin-framework/path"
1514
"github.com/hashicorp/terraform-plugin-framework/types"
1615
)
1716

17+
type features struct {
18+
SupportsGlobalDataTags bool
19+
SupportsSupportsAgentless bool
20+
}
21+
1822
type globalDataTagsItemModel struct {
1923
StringValue types.String `tfsdk:"string_value"`
2024
NumberValue types.Float32 `tfsdk:"number_value"`
@@ -101,18 +105,18 @@ func (model *agentPolicyModel) populateFromAPI(ctx context.Context, data *kbapi.
101105

102106
// convertGlobalDataTags converts the global data tags from terraform model to API model
103107
// and performs version validation
104-
func (model *agentPolicyModel) convertGlobalDataTags(ctx context.Context, serverVersion *version.Version) (*[]kbapi.AgentPolicyGlobalDataTagsItem, diag.Diagnostics) {
108+
func (model *agentPolicyModel) convertGlobalDataTags(ctx context.Context, feat features) (*[]kbapi.AgentPolicyGlobalDataTagsItem, diag.Diagnostics) {
105109
var diags diag.Diagnostics
106110

107111
if len(model.GlobalDataTags.Elements()) == 0 {
108-
if serverVersion.GreaterThanOrEqual(MinVersionGlobalDataTags) {
112+
if feat.SupportsGlobalDataTags {
109113
emptyList := make([]kbapi.AgentPolicyGlobalDataTagsItem, 0)
110114
return &emptyList, diags
111115
}
112116
return nil, diags
113117
}
114118

115-
if serverVersion.LessThan(MinVersionGlobalDataTags) {
119+
if !feat.SupportsGlobalDataTags {
116120
diags.AddError("global_data_tags ES version error", fmt.Sprintf("Global data tags are only supported in Elastic Stack %s and above", MinVersionGlobalDataTags))
117121
return nil, diags
118122
}
@@ -148,7 +152,7 @@ func (model *agentPolicyModel) convertGlobalDataTags(ctx context.Context, server
148152
return &itemsList, diags
149153
}
150154

151-
func (model *agentPolicyModel) toAPICreateModel(ctx context.Context, serverVersion *version.Version) (kbapi.PostFleetAgentPoliciesJSONRequestBody, diag.Diagnostics) {
155+
func (model *agentPolicyModel) toAPICreateModel(ctx context.Context, feat features) (kbapi.PostFleetAgentPoliciesJSONRequestBody, diag.Diagnostics) {
152156
monitoring := make([]kbapi.PostFleetAgentPoliciesJSONBodyMonitoringEnabled, 0, 2)
153157

154158
if model.MonitorLogs.ValueBool() {
@@ -158,6 +162,16 @@ func (model *agentPolicyModel) toAPICreateModel(ctx context.Context, serverVersi
158162
monitoring = append(monitoring, kbapi.PostFleetAgentPoliciesJSONBodyMonitoringEnabledMetrics)
159163
}
160164

165+
if utils.IsKnown(model.SupportsAgentless) && !feat.SupportsSupportsAgentless {
166+
return kbapi.PostFleetAgentPoliciesJSONRequestBody{}, diag.Diagnostics{
167+
diag.NewAttributeErrorDiagnostic(
168+
path.Root("supports_agentless"),
169+
"Unsupported Elasticsearch version",
170+
fmt.Sprintf("Supports agentless is only supported in Elastic Stack %s and above", MinSupportsAgentlessVersion),
171+
),
172+
}
173+
}
174+
161175
body := kbapi.PostFleetAgentPoliciesJSONRequestBody{
162176
DataOutputId: model.DataOutputId.ValueStringPointer(),
163177
Description: model.Description.ValueStringPointer(),
@@ -171,7 +185,7 @@ func (model *agentPolicyModel) toAPICreateModel(ctx context.Context, serverVersi
171185
SupportsAgentless: model.SupportsAgentless.ValueBoolPointer(),
172186
}
173187

174-
tags, diags := model.convertGlobalDataTags(ctx, serverVersion)
188+
tags, diags := model.convertGlobalDataTags(ctx, feat)
175189
if diags.HasError() {
176190
return kbapi.PostFleetAgentPoliciesJSONRequestBody{}, diags
177191
}
@@ -180,7 +194,7 @@ func (model *agentPolicyModel) toAPICreateModel(ctx context.Context, serverVersi
180194
return body, nil
181195
}
182196

183-
func (model *agentPolicyModel) toAPIUpdateModel(ctx context.Context, serverVersion *version.Version) (kbapi.PutFleetAgentPoliciesAgentpolicyidJSONRequestBody, diag.Diagnostics) {
197+
func (model *agentPolicyModel) toAPIUpdateModel(ctx context.Context, feat features) (kbapi.PutFleetAgentPoliciesAgentpolicyidJSONRequestBody, diag.Diagnostics) {
184198
monitoring := make([]kbapi.PutFleetAgentPoliciesAgentpolicyidJSONBodyMonitoringEnabled, 0, 2)
185199
if model.MonitorLogs.ValueBool() {
186200
monitoring = append(monitoring, kbapi.Logs)
@@ -189,6 +203,16 @@ func (model *agentPolicyModel) toAPIUpdateModel(ctx context.Context, serverVersi
189203
monitoring = append(monitoring, kbapi.Metrics)
190204
}
191205

206+
if utils.IsKnown(model.SupportsAgentless) && !feat.SupportsSupportsAgentless {
207+
return kbapi.PutFleetAgentPoliciesAgentpolicyidJSONRequestBody{}, diag.Diagnostics{
208+
diag.NewAttributeErrorDiagnostic(
209+
path.Root("supports_agentless"),
210+
"Unsupported Elasticsearch version",
211+
fmt.Sprintf("Supports agentless is only supported in Elastic Stack %s and above", MinSupportsAgentlessVersion),
212+
),
213+
}
214+
}
215+
192216
body := kbapi.PutFleetAgentPoliciesAgentpolicyidJSONRequestBody{
193217
DataOutputId: model.DataOutputId.ValueStringPointer(),
194218
Description: model.Description.ValueStringPointer(),
@@ -201,7 +225,7 @@ func (model *agentPolicyModel) toAPIUpdateModel(ctx context.Context, serverVersi
201225
SupportsAgentless: model.SupportsAgentless.ValueBoolPointer(),
202226
}
203227

204-
tags, diags := model.convertGlobalDataTags(ctx, serverVersion)
228+
tags, diags := model.convertGlobalDataTags(ctx, feat)
205229
if diags.HasError() {
206230
return kbapi.PutFleetAgentPoliciesAgentpolicyidJSONRequestBody{}, diags
207231
}

internal/fleet/agent_policy/resource.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"fmt"
66

77
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
89
"github.com/hashicorp/go-version"
10+
"github.com/hashicorp/terraform-plugin-framework/diag"
911
"github.com/hashicorp/terraform-plugin-framework/path"
1012
"github.com/hashicorp/terraform-plugin-framework/resource"
1113
)
@@ -16,7 +18,10 @@ var (
1618
_ resource.ResourceWithImportState = &agentPolicyResource{}
1719
)
1820

19-
var MinVersionGlobalDataTags = version.Must(version.NewVersion("8.15.0"))
21+
var (
22+
MinVersionGlobalDataTags = version.Must(version.NewVersion("8.15.0"))
23+
MinSupportsAgentlessVersion = version.Must(version.NewVersion("8.15.0"))
24+
)
2025

2126
// NewResource is a helper function to simplify the provider implementation.
2227
func NewResource() resource.Resource {
@@ -40,3 +45,20 @@ func (r *agentPolicyResource) Metadata(ctx context.Context, req resource.Metadat
4045
func (r *agentPolicyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
4146
resource.ImportStatePassthroughID(ctx, path.Root("policy_id"), req, resp)
4247
}
48+
49+
func (r *agentPolicyResource) buildFeatures(ctx context.Context) (features, diag.Diagnostics) {
50+
supportsGDT, diags := r.client.EnforceMinVersion(ctx, MinVersionGlobalDataTags)
51+
if diags.HasError() {
52+
return features{}, utils.FrameworkDiagsFromSDK(diags)
53+
}
54+
55+
supportsSupportsAgentless, diags := r.client.EnforceMinVersion(ctx, MinSupportsAgentlessVersion)
56+
if diags.HasError() {
57+
return features{}, utils.FrameworkDiagsFromSDK(diags)
58+
}
59+
60+
return features{
61+
SupportsGlobalDataTags: supportsGDT,
62+
SupportsSupportsAgentless: supportsSupportsAgentless,
63+
}, nil
64+
}

0 commit comments

Comments
 (0)