Skip to content

Commit c7d42a3

Browse files
synthetics/parameter: Switch to using OAPI client
Co-Authored-By: Toby Brain <toby.brain@elastic.co> Signed-off-by: Andrew Gunnerson <andrew.gunnerson@elastic.co>
1 parent 13df2f0 commit c7d42a3

File tree

12 files changed

+4487
-1141
lines changed

12 files changed

+4487
-1141
lines changed

generated/kbapi/kibana.gen.go

Lines changed: 4322 additions & 946 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/kbapi/transform_schema.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ func transformFilterPaths(schema *Schema) {
570570
"/api/fleet/outputs/{outputId}": {"get", "put", "delete"},
571571
"/api/fleet/package_policies": {"get", "post"},
572572
"/api/fleet/package_policies/{packagePolicyId}": {"get", "put", "delete"},
573+
"/api/synthetics/params": {"post"},
574+
"/api/synthetics/params/{id}": {"get", "put", "delete"},
573575
}
574576

575577
for path, pathInfo := range schema.Paths {
@@ -694,7 +696,11 @@ func transformSimplifyContentType(schema *Schema) {
694696
func transformAddMisingDescriptions(schema *Schema) {
695697
for _, pathInfo := range schema.Paths {
696698
for _, endpoint := range pathInfo.Endpoints {
697-
responses := endpoint.MustGetMap("responses")
699+
responses, ok := endpoint.GetMap("responses")
700+
if !ok {
701+
return
702+
}
703+
698704
for code := range responses {
699705
response := responses.MustGetMap(code)
700706
if _, ok := response["description"]; !ok {
@@ -750,6 +756,9 @@ func transformKibanaPaths(schema *Schema) {
750756

751757
dataViewsPath.Get.CreateRef(schema, "get_data_views_response_item", "responses.200.content.application/json.schema.properties.data_view.items")
752758

759+
sytheticsParamsPath := schema.MustGetPath("/api/synthetics/params")
760+
sytheticsParamsPath.Post.CreateRef(schema, "create_param_response", "responses.200.content.application/json.schema")
761+
753762
schema.Components.CreateRef(schema, "Data_views_data_view_response_object_inner", "schemas.Data_views_data_view_response_object.properties.data_view")
754763
schema.Components.CreateRef(schema, "Data_views_sourcefilter_item", "schemas.Data_views_sourcefilters.items")
755764
schema.Components.CreateRef(schema, "Data_views_runtimefieldmap_script", "schemas.Data_views_runtimefieldmap.properties.script")
Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package parameter
22

33
import (
4+
"bytes"
45
"context"
6+
"encoding/json"
57
"fmt"
68

79
"github.com/elastic/terraform-provider-elasticstack/internal/kibana/synthetics"
810
"github.com/hashicorp/terraform-plugin-framework/resource"
911
)
1012

1113
func (r *Resource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
12-
kibanaClient := synthetics.GetKibanaClient(r, response.Diagnostics)
14+
kibanaClient := synthetics.GetKibanaOAPIClient(r, response.Diagnostics)
1315
if kibanaClient == nil {
1416
return
1517
}
@@ -21,16 +23,36 @@ func (r *Resource) Create(ctx context.Context, request resource.CreateRequest, r
2123
return
2224
}
2325

24-
input := plan.toParameterConfig(false)
26+
input := plan.toParameterRequest(false)
2527

26-
result, err := kibanaClient.KibanaSynthetics.Parameter.Add(ctx, input)
28+
// We shouldn't have to do this json marshalling ourselves,
29+
// https://github.com/oapi-codegen/oapi-codegen/issues/1620 means the generated code doesn't handle the oneOf
30+
// request body properly.
31+
inputJson, err := json.Marshal(input)
32+
if err != nil {
33+
response.Diagnostics.AddError(fmt.Sprintf("Failed to marshal JSON for parameter `%s`", input.Key), err.Error())
34+
return
35+
}
36+
37+
createResult, err := kibanaClient.API.PostParametersWithBodyWithResponse(ctx, "application/json", bytes.NewReader(inputJson))
2738
if err != nil {
2839
response.Diagnostics.AddError(fmt.Sprintf("Failed to create parameter `%s`", input.Key), err.Error())
2940
return
3041
}
3142

43+
createResponse, err := createResult.JSON200.AsSyntheticsPostParameterResponse()
44+
if err != nil {
45+
response.Diagnostics.AddError(fmt.Sprintf("Failed to parse parameter response `%s`", input.Key), err.Error())
46+
return
47+
}
48+
49+
if createResponse.Id == nil {
50+
response.Diagnostics.AddError(fmt.Sprintf("Unexpected nil id in create parameter response `%s`", input.Key), "")
51+
return
52+
}
53+
3254
// We can't trust the response from the POST request, so read the parameter
3355
// again. At least with Kibana 9.0.0, the POST request responds without the
3456
// `value` field set.
35-
r.readState(ctx, kibanaClient, toModelV0(*result), &response.State, &response.Diagnostics)
57+
r.readState(ctx, kibanaClient, *createResponse.Id, &response.State, &response.Diagnostics)
3658
}

internal/kibana/synthetics/parameter/read.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,16 @@ import (
55
"errors"
66
"fmt"
77

8-
"github.com/disaster37/go-kibana-rest/v8"
98
"github.com/disaster37/go-kibana-rest/v8/kbapi"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
1010
"github.com/elastic/terraform-provider-elasticstack/internal/kibana/synthetics"
1111
"github.com/hashicorp/terraform-plugin-framework/diag"
1212
"github.com/hashicorp/terraform-plugin-framework/resource"
1313
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
1414
)
1515

16-
func (r *Resource) readState(ctx context.Context, kibanaClient *kibana.Client, model tfModelV0, state *tfsdk.State, diagnostics *diag.Diagnostics) {
17-
resourceId := model.ID.ValueString()
18-
19-
compositeId, dg := tryReadCompositeId(resourceId)
20-
diagnostics.Append(dg...)
21-
if diagnostics.HasError() {
22-
return
23-
}
24-
25-
if compositeId != nil {
26-
resourceId = compositeId.ResourceId
27-
}
28-
29-
result, err := kibanaClient.KibanaSynthetics.Parameter.Get(ctx, resourceId)
16+
func (r *Resource) readState(ctx context.Context, kibanaClient *kibana_oapi.Client, resourceId string, state *tfsdk.State, diagnostics *diag.Diagnostics) {
17+
getResult, err := kibanaClient.API.GetParameterWithResponse(ctx, resourceId)
3018
if err != nil {
3119
var apiError *kbapi.APIError
3220
if errors.As(err, &apiError) && apiError.Code == 404 {
@@ -38,7 +26,7 @@ func (r *Resource) readState(ctx context.Context, kibanaClient *kibana.Client, m
3826
return
3927
}
4028

41-
model = toModelV0(*result)
29+
model := modelV0FromOAPI(*getResult.JSON200)
4230

4331
// Set refreshed state
4432
diags := state.Set(ctx, &model)
@@ -49,7 +37,7 @@ func (r *Resource) readState(ctx context.Context, kibanaClient *kibana.Client, m
4937
}
5038

5139
func (r *Resource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
52-
kibanaClient := synthetics.GetKibanaClient(r, response.Diagnostics)
40+
kibanaClient := synthetics.GetKibanaOAPIClient(r, response.Diagnostics)
5341
if kibanaClient == nil {
5442
return
5543
}
@@ -61,5 +49,17 @@ func (r *Resource) Read(ctx context.Context, request resource.ReadRequest, respo
6149
return
6250
}
6351

64-
r.readState(ctx, kibanaClient, state, &response.State, &response.Diagnostics)
52+
resourceId := state.ID.ValueString()
53+
54+
compositeId, dg := tryReadCompositeId(resourceId)
55+
response.Diagnostics.Append(dg...)
56+
if response.Diagnostics.HasError() {
57+
return
58+
}
59+
60+
if compositeId != nil {
61+
resourceId = compositeId.ResourceId
62+
}
63+
64+
r.readState(ctx, kibanaClient, resourceId, &response.State, &response.Diagnostics)
6565
}

internal/kibana/synthetics/parameter/schema.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ import (
44
"slices"
55
"strings"
66

7-
"github.com/disaster37/go-kibana-rest/v8/kbapi"
7+
kboapi "github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
88
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
99
"github.com/elastic/terraform-provider-elasticstack/internal/kibana/synthetics"
10+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
11+
"github.com/hashicorp/terraform-plugin-framework/attr"
1012
"github.com/hashicorp/terraform-plugin-framework/diag"
1113
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
1214
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
1315
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
16+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listdefault"
1417
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
1518
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
19+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
1620
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1721
"github.com/hashicorp/terraform-plugin-framework/types"
1822
)
@@ -57,6 +61,8 @@ func parameterSchema() schema.Schema {
5761
},
5862
"description": schema.StringAttribute{
5963
Optional: true,
64+
Computed: true,
65+
Default: stringdefault.StaticString(""),
6066
MarkdownDescription: "A description of the parameter.",
6167
PlanModifiers: []planmodifier.String{
6268
stringplanmodifier.UseStateForUnknown(),
@@ -65,6 +71,8 @@ func parameterSchema() schema.Schema {
6571
"tags": schema.ListAttribute{
6672
ElementType: types.StringType,
6773
Optional: true,
74+
Computed: true,
75+
Default: listdefault.StaticValue(types.ListValueMust(types.StringType, []attr.Value{})),
6876
MarkdownDescription: "An array of tags to categorize the parameter.",
6977
PlanModifiers: []planmodifier.List{
7078
listplanmodifier.UseStateForUnknown(),
@@ -84,19 +92,20 @@ func parameterSchema() schema.Schema {
8492
}
8593
}
8694

87-
func (m *tfModelV0) toParameterConfig(forUpdate bool) kbapi.ParameterConfig {
95+
func (m *tfModelV0) toParameterRequest(forUpdate bool) kboapi.SyntheticsParameterRequest {
8896
// share_across_spaces is not allowed to be set when updating an existing
8997
// global parameter.
9098
var shareAcrossSpaces *bool = nil
9199
if !forUpdate {
92100
shareAcrossSpaces = m.ShareAcrossSpaces.ValueBoolPointer()
93101
}
94102

95-
return kbapi.ParameterConfig{
96-
Key: m.Key.ValueString(),
97-
Value: m.Value.ValueString(),
98-
Description: m.Description.ValueString(),
99-
Tags: synthetics.ValueStringSlice(m.Tags),
103+
return kboapi.SyntheticsParameterRequest{
104+
Key: m.Key.ValueString(),
105+
Value: m.Value.ValueString(),
106+
Description: utils.Pointer(m.Description.ValueString()),
107+
// We need this to marshal as an empty JSON array, not null.
108+
Tags: utils.Pointer(utils.NonNilSlice(synthetics.ValueStringSlice(m.Tags))),
100109
ShareAcrossSpaces: shareAcrossSpaces,
101110
}
102111
}
@@ -109,15 +118,17 @@ func tryReadCompositeId(id string) (*clients.CompositeId, diag.Diagnostics) {
109118
return nil, diag.Diagnostics{}
110119
}
111120

112-
func toModelV0(param kbapi.Parameter) tfModelV0 {
113-
allSpaces := slices.Equal(param.Namespaces, []string{"*"})
121+
func modelV0FromOAPI(param kboapi.SyntheticsGetParameterResponse) tfModelV0 {
122+
allSpaces := slices.Equal(*param.Namespaces, []string{"*"})
114123

115124
return tfModelV0{
116-
ID: types.StringValue(param.Id),
117-
Key: types.StringValue(param.Key),
118-
Value: types.StringValue(param.Value),
119-
Description: types.StringValue(param.Description),
120-
Tags: synthetics.StringSliceValue(param.Tags),
125+
ID: types.StringPointerValue(param.Id),
126+
Key: types.StringPointerValue(param.Key),
127+
Value: types.StringPointerValue(param.Value),
128+
Description: types.StringPointerValue(param.Description),
129+
// Terraform, like json.Marshal, treats empty slices as null. We need an
130+
// actual backing array of size 0.
131+
Tags: utils.NonNilSlice(synthetics.StringSliceValue(utils.DefaultIfNil(param.Tags))),
121132
ShareAcrossSpaces: types.BoolValue(allSpaces),
122133
}
123134
}

internal/kibana/synthetics/parameter/schema_test.go

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@ package parameter
33
import (
44
"testing"
55

6-
"github.com/disaster37/go-kibana-rest/v8/kbapi"
6+
kboapi "github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
7+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
78
"github.com/stretchr/testify/assert"
89
)
910

10-
func boolPointer(b bool) *bool {
11-
return &b
12-
}
13-
1411
func Test_roundtrip(t *testing.T) {
1512
tests := []struct {
1613
name string
1714
id string
1815
namespaces []string
19-
config kbapi.ParameterConfig
16+
request kboapi.SyntheticsParameterRequest
2017
}{
2118
{
2219
name: "only required fields",
2320
id: "id-1",
2421
namespaces: []string{"ns-1"},
25-
config: kbapi.ParameterConfig{
22+
request: kboapi.SyntheticsParameterRequest{
2623
Key: "key-1",
2724
Value: "value-1",
2825
},
@@ -31,61 +28,64 @@ func Test_roundtrip(t *testing.T) {
3128
name: "all fields",
3229
id: "id-2",
3330
namespaces: []string{"*"},
34-
config: kbapi.ParameterConfig{
31+
request: kboapi.SyntheticsParameterRequest{
3532
Key: "key-2",
3633
Value: "value-2",
37-
Description: "description-2",
38-
Tags: []string{"tag-1", "tag-2", "tag-3"},
39-
ShareAcrossSpaces: boolPointer(true),
34+
Description: utils.Pointer("description-2"),
35+
Tags: utils.Pointer([]string{"tag-1", "tag-2", "tag-3"}),
36+
ShareAcrossSpaces: utils.Pointer(true),
4037
},
4138
},
4239
{
4340
name: "only description",
4441
id: "id-3",
4542
namespaces: []string{"ns-3"},
46-
config: kbapi.ParameterConfig{
43+
request: kboapi.SyntheticsParameterRequest{
4744
Key: "key-3",
4845
Value: "value-3",
49-
Description: "description-3",
46+
Description: utils.Pointer("description-3"),
5047
},
5148
},
5249
{
5350
name: "only tags",
5451
id: "id-4",
5552
namespaces: []string{"ns-4"},
56-
config: kbapi.ParameterConfig{
53+
request: kboapi.SyntheticsParameterRequest{
5754
Key: "key-4",
5855
Value: "value-4",
59-
Description: "description-4",
56+
Description: utils.Pointer("description-4"),
6057
},
6158
},
6259
{
6360
name: "all namespaces",
6461
id: "id-5",
6562
namespaces: []string{"ns-5"},
66-
config: kbapi.ParameterConfig{
63+
request: kboapi.SyntheticsParameterRequest{
6764
Key: "key-5",
6865
Value: "value-5",
69-
Description: "description-5",
66+
Description: utils.Pointer("description-5"),
7067
},
7168
},
7269
}
7370
for _, tt := range tests {
7471
t.Run(tt.name, func(t *testing.T) {
75-
config := tt.config
76-
input := kbapi.Parameter{
77-
Id: tt.id,
78-
Namespaces: tt.namespaces,
79-
ParameterConfig: config,
72+
response := kboapi.SyntheticsGetParameterResponse{
73+
Id: &tt.id,
74+
Namespaces: &tt.namespaces,
75+
Key: &tt.request.Key,
76+
Value: &tt.request.Value,
77+
Description: tt.request.Description,
78+
Tags: tt.request.Tags,
8079
}
81-
modelV0 := toModelV0(input)
80+
modelV0 := modelV0FromOAPI(response)
8281

83-
actual := modelV0.toParameterConfig(false)
84-
if config.ShareAcrossSpaces == nil {
85-
// The conversion always sets ShareAcrossSpaces.
86-
config.ShareAcrossSpaces = boolPointer(false)
87-
}
88-
assert.Equal(t, config, actual)
82+
actual := modelV0.toParameterRequest(false)
83+
84+
assert.Equal(t, tt.request.Key, actual.Key)
85+
assert.Equal(t, tt.request.Value, actual.Value)
86+
assert.Equal(t, utils.DefaultIfNil(tt.request.Description), utils.DefaultIfNil(actual.Description))
87+
assert.Equal(t, utils.NonNilSlice(utils.DefaultIfNil(tt.request.Tags)), utils.NonNilSlice(utils.DefaultIfNil(actual.Tags)))
88+
assert.Equal(t, utils.DefaultIfNil(tt.request.ShareAcrossSpaces), utils.DefaultIfNil(actual.ShareAcrossSpaces))
8989
})
9090
}
9191
}

0 commit comments

Comments
 (0)