Skip to content

Commit 46b83f1

Browse files
Copilottobio
andcommitted
Add kibana_default_data_view resource with CRUD operations
Co-authored-by: tobio <444668+tobio@users.noreply.github.com>
1 parent b8b1081 commit 46b83f1

File tree

10 files changed

+462
-0
lines changed

10 files changed

+462
-0
lines changed

internal/clients/kibana_oapi/data_views.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,36 @@ func DeleteDataView(ctx context.Context, client *Client, spaceID string, viewID
8787
return reportUnknownError(resp.StatusCode(), resp.Body)
8888
}
8989
}
90+
91+
// GetDefaultDataView reads the default data view from the API.
92+
func GetDefaultDataView(ctx context.Context, client *Client) (*string, diag.Diagnostics) {
93+
resp, err := client.API.GetDefaultDataViewDefaultWithResponse(ctx)
94+
if err != nil {
95+
return nil, diagutil.FrameworkDiagFromError(err)
96+
}
97+
98+
switch resp.StatusCode() {
99+
case http.StatusOK:
100+
if resp.JSON200 != nil && resp.JSON200.DataViewId != nil {
101+
return resp.JSON200.DataViewId, nil
102+
}
103+
return nil, nil
104+
default:
105+
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
106+
}
107+
}
108+
109+
// SetDefaultDataView sets the default data view.
110+
func SetDefaultDataView(ctx context.Context, client *Client, req kbapi.SetDefaultDatailViewDefaultJSONRequestBody) diag.Diagnostics {
111+
resp, err := client.API.SetDefaultDatailViewDefaultWithResponse(ctx, req)
112+
if err != nil {
113+
return diagutil.FrameworkDiagFromError(err)
114+
}
115+
116+
switch resp.StatusCode() {
117+
case http.StatusOK:
118+
return nil
119+
default:
120+
return reportUnknownError(resp.StatusCode(), resp.Body)
121+
}
122+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package default_data_view_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
9+
"github.com/hashicorp/go-version"
10+
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
11+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
12+
)
13+
14+
var minDataViewAPISupport = version.Must(version.NewVersion("8.1.0"))
15+
16+
func TestAccResourceDefaultDataView(t *testing.T) {
17+
indexName1 := "my-index-" + sdkacctest.RandStringFromCharSet(4, sdkacctest.CharSetAlphaNum)
18+
indexName2 := "my-other-index-" + sdkacctest.RandStringFromCharSet(4, sdkacctest.CharSetAlphaNum)
19+
20+
resource.Test(t, resource.TestCase{
21+
PreCheck: func() { acctest.PreCheck(t) },
22+
ProtoV6ProviderFactories: acctest.Providers,
23+
Steps: []resource.TestStep{
24+
{
25+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minDataViewAPISupport),
26+
Config: testAccResourceDefaultDataViewBasic(indexName1),
27+
Check: resource.ComposeTestCheckFunc(
28+
resource.TestCheckResourceAttrSet("elasticstack_kibana_default_data_view.test", "id"),
29+
resource.TestCheckResourceAttrSet("elasticstack_kibana_default_data_view.test", "data_view_id"),
30+
resource.TestCheckResourceAttr("elasticstack_kibana_default_data_view.test", "force", "true"),
31+
resource.TestCheckResourceAttr("elasticstack_kibana_default_data_view.test", "skip_delete", "false"),
32+
),
33+
},
34+
{
35+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minDataViewAPISupport),
36+
Config: testAccResourceDefaultDataViewUpdate(indexName1, indexName2),
37+
Check: resource.ComposeTestCheckFunc(
38+
resource.TestCheckResourceAttrSet("elasticstack_kibana_default_data_view.test", "id"),
39+
resource.TestCheckResourceAttrSet("elasticstack_kibana_default_data_view.test", "data_view_id"),
40+
),
41+
},
42+
},
43+
})
44+
}
45+
46+
func TestAccResourceDefaultDataViewWithSkipDelete(t *testing.T) {
47+
indexName := "my-index-" + sdkacctest.RandStringFromCharSet(4, sdkacctest.CharSetAlphaNum)
48+
49+
resource.Test(t, resource.TestCase{
50+
PreCheck: func() { acctest.PreCheck(t) },
51+
ProtoV6ProviderFactories: acctest.Providers,
52+
Steps: []resource.TestStep{
53+
{
54+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minDataViewAPISupport),
55+
Config: testAccResourceDefaultDataViewWithSkipDelete(indexName),
56+
Check: resource.ComposeTestCheckFunc(
57+
resource.TestCheckResourceAttrSet("elasticstack_kibana_default_data_view.test", "id"),
58+
resource.TestCheckResourceAttr("elasticstack_kibana_default_data_view.test", "skip_delete", "true"),
59+
),
60+
},
61+
},
62+
})
63+
}
64+
65+
func testAccResourceDefaultDataViewBasic(indexName string) string {
66+
return fmt.Sprintf(`
67+
provider "elasticstack" {
68+
elasticsearch {}
69+
kibana {}
70+
}
71+
72+
resource "elasticstack_elasticsearch_index" "my_index" {
73+
name = "%s"
74+
deletion_protection = false
75+
}
76+
77+
resource "elasticstack_kibana_data_view" "dv" {
78+
data_view = {
79+
title = "%s*"
80+
}
81+
depends_on = [elasticstack_elasticsearch_index.my_index]
82+
}
83+
84+
resource "elasticstack_kibana_default_data_view" "test" {
85+
data_view_id = elasticstack_kibana_data_view.dv.data_view.id
86+
force = true
87+
}
88+
`, indexName, indexName)
89+
}
90+
91+
func testAccResourceDefaultDataViewUpdate(indexName1, indexName2 string) string {
92+
return fmt.Sprintf(`
93+
provider "elasticstack" {
94+
elasticsearch {}
95+
kibana {}
96+
}
97+
98+
resource "elasticstack_elasticsearch_index" "my_index" {
99+
name = "%s"
100+
deletion_protection = false
101+
}
102+
103+
resource "elasticstack_elasticsearch_index" "my_other_index" {
104+
name = "%s"
105+
deletion_protection = false
106+
}
107+
108+
resource "elasticstack_kibana_data_view" "dv" {
109+
data_view = {
110+
title = "%s*"
111+
}
112+
depends_on = [elasticstack_elasticsearch_index.my_index]
113+
}
114+
115+
resource "elasticstack_kibana_data_view" "dv2" {
116+
data_view = {
117+
title = "%s*"
118+
}
119+
depends_on = [elasticstack_elasticsearch_index.my_other_index]
120+
}
121+
122+
resource "elasticstack_kibana_default_data_view" "test" {
123+
data_view_id = elasticstack_kibana_data_view.dv2.data_view.id
124+
force = true
125+
}
126+
`, indexName1, indexName2, indexName1, indexName2)
127+
}
128+
129+
func testAccResourceDefaultDataViewWithSkipDelete(indexName string) string {
130+
return fmt.Sprintf(`
131+
provider "elasticstack" {
132+
elasticsearch {}
133+
kibana {}
134+
}
135+
136+
resource "elasticstack_elasticsearch_index" "my_index" {
137+
name = "%s"
138+
deletion_protection = false
139+
}
140+
141+
resource "elasticstack_kibana_data_view" "dv" {
142+
data_view = {
143+
title = "%s*"
144+
}
145+
depends_on = [elasticstack_elasticsearch_index.my_index]
146+
}
147+
148+
resource "elasticstack_kibana_default_data_view" "test" {
149+
data_view_id = elasticstack_kibana_data_view.dv.data_view.id
150+
force = true
151+
skip_delete = true
152+
}
153+
`, indexName, indexName)
154+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package default_data_view
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
9+
"github.com/hashicorp/terraform-plugin-framework/resource"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
)
12+
13+
func (r *DefaultDataViewResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
14+
var plan defaultDataViewModel
15+
diags := req.Plan.Get(ctx, &plan)
16+
resp.Diagnostics.Append(diags...)
17+
if resp.Diagnostics.HasError() {
18+
return
19+
}
20+
21+
client, err := r.client.GetKibanaOapiClient()
22+
if err != nil {
23+
resp.Diagnostics.AddError("unable to get kibana client", err.Error())
24+
return
25+
}
26+
27+
dataViewID := plan.DataViewID.ValueString()
28+
force := plan.Force.ValueBool()
29+
30+
setReq := kbapi.SetDefaultDatailViewDefaultJSONRequestBody{
31+
DataViewId: &dataViewID,
32+
Force: &force,
33+
}
34+
35+
diags = kibana_oapi.SetDefaultDataView(ctx, client, setReq)
36+
resp.Diagnostics.Append(diags...)
37+
if resp.Diagnostics.HasError() {
38+
return
39+
}
40+
41+
// Set the ID to the data view ID for state tracking
42+
plan.ID = types.StringValue(fmt.Sprintf("default-data-view:%s", dataViewID))
43+
44+
diags = resp.State.Set(ctx, plan)
45+
resp.Diagnostics.Append(diags...)
46+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package default_data_view
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
func (r *DefaultDataViewResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
12+
var state defaultDataViewModel
13+
diags := req.State.Get(ctx, &state)
14+
resp.Diagnostics.Append(diags...)
15+
if resp.Diagnostics.HasError() {
16+
return
17+
}
18+
19+
// If skip_delete is true, leave the default data view unchanged
20+
if state.SkipDelete.ValueBool() {
21+
return
22+
}
23+
24+
client, err := r.client.GetKibanaOapiClient()
25+
if err != nil {
26+
resp.Diagnostics.AddError("unable to get kibana client", err.Error())
27+
return
28+
}
29+
30+
// Unset the default data view by setting it to null
31+
var nullDataViewID *string = nil
32+
force := true
33+
34+
setReq := kbapi.SetDefaultDatailViewDefaultJSONRequestBody{
35+
DataViewId: nullDataViewID,
36+
Force: &force,
37+
}
38+
39+
diags = kibana_oapi.SetDefaultDataView(ctx, client, setReq)
40+
resp.Diagnostics.Append(diags...)
41+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package default_data_view
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework/types"
5+
)
6+
7+
type defaultDataViewModel struct {
8+
ID types.String `tfsdk:"id"`
9+
DataViewID types.String `tfsdk:"data_view_id"`
10+
Force types.Bool `tfsdk:"force"`
11+
SkipDelete types.Bool `tfsdk:"skip_delete"`
12+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package default_data_view
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
)
11+
12+
func (r *DefaultDataViewResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
13+
var state defaultDataViewModel
14+
diags := req.State.Get(ctx, &state)
15+
resp.Diagnostics.Append(diags...)
16+
if resp.Diagnostics.HasError() {
17+
return
18+
}
19+
20+
client, err := r.client.GetKibanaOapiClient()
21+
if err != nil {
22+
resp.Diagnostics.AddError("unable to get kibana client", err.Error())
23+
return
24+
}
25+
26+
defaultDataViewID, diags := kibana_oapi.GetDefaultDataView(ctx, client)
27+
resp.Diagnostics.Append(diags...)
28+
if resp.Diagnostics.HasError() {
29+
return
30+
}
31+
32+
// If no default data view is set, remove from state
33+
if defaultDataViewID == nil || *defaultDataViewID == "" {
34+
resp.State.RemoveResource(ctx)
35+
return
36+
}
37+
38+
// Update state with current default data view
39+
state.DataViewID = types.StringValue(*defaultDataViewID)
40+
state.ID = types.StringValue(fmt.Sprintf("default-data-view:%s", *defaultDataViewID))
41+
42+
diags = resp.State.Set(ctx, state)
43+
resp.Diagnostics.Append(diags...)
44+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package default_data_view
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
var (
12+
_ resource.Resource = &DefaultDataViewResource{}
13+
_ resource.ResourceWithConfigure = &DefaultDataViewResource{}
14+
)
15+
16+
// NewResource is a helper function to simplify the provider implementation.
17+
func NewResource() resource.Resource {
18+
return &DefaultDataViewResource{}
19+
}
20+
21+
type DefaultDataViewResource struct {
22+
client *clients.ApiClient
23+
}
24+
25+
func (r *DefaultDataViewResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
26+
client, diags := clients.ConvertProviderData(req.ProviderData)
27+
resp.Diagnostics.Append(diags...)
28+
r.client = client
29+
}
30+
31+
func (r *DefaultDataViewResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
32+
resp.TypeName = fmt.Sprintf("%s_%s", req.ProviderTypeName, "kibana_default_data_view")
33+
}

0 commit comments

Comments
 (0)