Skip to content

Commit 85cf3f4

Browse files
Copilottobio
andauthored
Add support for solution field in elasticsearch_kibana_space resource and data source (#1210)
* Initial plan * Add solution field support to Kibana space resource and data source Co-authored-by: tobio <[email protected]> * Update documentation and changelog for solution field support Co-authored-by: tobio <[email protected]> * Add version checking for solution field in Kibana space resource Co-authored-by: tobio <[email protected]> * Add version 8.18.3 to test matrix and SkipFunc for solution field tests Co-authored-by: tobio <[email protected]> * Add Computed: true to disabled_features and solution fields in resource and data source Co-authored-by: tobio <[email protected]> * Regenerate documentation using make docs-generate Co-authored-by: tobio <[email protected]> * Use make target for acc test services --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: tobio <[email protected]> Co-authored-by: Toby Brain <[email protected]>
1 parent 36f0b42 commit 85cf3f4

File tree

12 files changed

+74
-58
lines changed

12 files changed

+74
-58
lines changed

.github/workflows/copilot-setup-steps.yml

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -21,62 +21,6 @@ jobs:
2121
permissions:
2222
# If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
2323
contents: read
24-
env:
25-
ELASTICSEARCH_ENDPOINTS: "http://localhost:9200"
26-
ELASTICSEARCH_USERNAME: "elastic"
27-
ELASTICSEARCH_PASSWORD: password
28-
KIBANA_ENDPOINT: "http://localhost:5601"
29-
KIBANA_USERNAME: "elastic"
30-
KIBANA_PASSWORD: password
31-
KIBANA_SYSTEM_USERNAME: kibana_system
32-
KIBANA_SYSTEM_PASSWORD: password
33-
TF_ACC: "1"
34-
services:
35-
elasticsearch:
36-
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.2@sha256:d1a8016cf55be8ffec635ed69f5a9acb0c459db35b46a4549ec5b2847a2f170a
37-
env:
38-
discovery.type: single-node
39-
xpack.security.enabled: true
40-
xpack.security.authc.api_key.enabled: true
41-
xpack.security.authc.token.enabled: true
42-
xpack.watcher.enabled: true
43-
xpack.license.self_generated.type: trial
44-
repositories.url.allowed_urls: https://example.com/*
45-
path.repo: /tmp
46-
ELASTIC_PASSWORD: ${{ env.ELASTICSEARCH_PASSWORD }}
47-
ports:
48-
- 9200:9200
49-
options: --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=10
50-
kibana:
51-
image: docker.elastic.co/kibana/kibana:9.1.3@sha256:26792c8e4a68ba0bff3efcc46755f60bf36bb16b2431014c210f2546ca1819ad
52-
env:
53-
SERVER_NAME: kibana
54-
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
55-
ELASTICSEARCH_USERNAME: ${{ env.KIBANA_SYSTEM_USERNAME }}
56-
ELASTICSEARCH_PASSWORD: ${{ env.KIBANA_SYSTEM_PASSWORD }}
57-
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: a7a6311933d3503b89bc2dbc36572c33a6c10925682e591bffcab6911c06786d
58-
# LOGGING_ROOT_LEVEL: debug
59-
ports:
60-
- 5601:5601
61-
options: --health-cmd="curl http://localhost:5601/api/status" --health-interval=10s --health-timeout=5s --health-retries=10
62-
fleet:
63-
image: docker.elastic.co/elastic-agent/elastic-agent:9.1.2@sha256:942aa0ffe94c268aab83881fc8be0ca0af079c395820ce8e7552f0ce97e0a760
64-
env:
65-
SERVER_NAME: fleet
66-
FLEET_ENROLL: "1"
67-
FLEET_URL: https://fleet:8220
68-
FLEET_INSECURE: "true"
69-
FLEET_SERVER_ENABLE: "1"
70-
FLEET_SERVER_POLICY_ID: fleet-server
71-
FLEET_SERVER_ELASTICSEARCH_HOST: http://elasticsearch:9200
72-
FLEET_SERVER_ELASTICSEARCH_INSECURE: "true"
73-
FLEET_SERVER_INSECURE_HTTP: "true"
74-
KIBANA_HOST: http://kibana:5601
75-
KIBANA_FLEET_SETUP: "1"
76-
KIBANA_FLEET_PASSWORD: ${{ env.ELASTICSEARCH_PASSWORD }}
77-
ports:
78-
- 8220:8220
79-
options: --restart="unless-stopped"
8024

8125
steps:
8226
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
@@ -88,6 +32,9 @@ jobs:
8832
with:
8933
terraform_wrapper: false
9034

35+
- name: Setup Elastic Stack
36+
run: make docker-fleet
37+
9138
- name: Get dependencies
9239
run: make setup
9340

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ jobs:
126126
- '8.15.5'
127127
- '8.16.2'
128128
- '8.17.0'
129+
- '8.18.3'
129130
- '9.0.3'
130131
steps:
131132
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## [Unreleased]
22

3+
- Add support for `solution` field in `elasticstack_kibana_space` resource and data source ([#1102](https://github.com/elastic/terraform-provider-elasticstack/issues/1102))
34
- Add `slo_id` validation to `elasticstack_kibana_slo` ([#1221](https://github.com/elastic/terraform-provider-elasticstack/pull/1221))
45
- Add `ignore_missing_component_templates` to `elasticstack_elasticsearch_index_template` ([#1206](https://github.com/elastic/terraform-provider-elasticstack/pull/1206))
56
- Prevent provider panic when a script exists in state, but not in Elasticsearch ([#1218](https://github.com/elastic/terraform-provider-elasticstack/pull/1218))

docs/data-sources/kibana_spaces.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ Required:
4141
Optional:
4242

4343
- `description` (String) The description for the space.
44-
- `disabled_features` (List of String) The list of disabled features for the space. To get a list of available feature IDs, use the Features API (https://www.elastic.co/guide/en/kibana/master/features-api-get.html).
4544
- `image_url` (String) The data-URL encoded image to display in the space avatar.
4645

4746
Read-Only:
4847

4948
- `color` (String) The hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name.
49+
- `disabled_features` (List of String) The list of disabled features for the space. To get a list of available feature IDs, use the Features API (https://www.elastic.co/guide/en/kibana/master/features-api-get.html).
5050
- `id` (String) Internal identifier of the resource.
5151
- `initials` (String) The initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters.
52+
- `solution` (String) The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.

docs/resources/kibana_space.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ resource "elasticstack_kibana_space" "example" {
4141
- `disabled_features` (Set of String) The list of disabled features for the space. To get a list of available feature IDs, use the Features API (https://www.elastic.co/guide/en/kibana/master/features-api-get.html).
4242
- `image_url` (String) The data-URL encoded image to display in the space avatar.
4343
- `initials` (String) The initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters.
44+
- `solution` (String) The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.
4445

4546
### Read-Only
4647

internal/kibana/space.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import (
66

77
"github.com/disaster37/go-kibana-rest/v8/kbapi"
88
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
9+
"github.com/hashicorp/go-version"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1213
)
1314

15+
var SpaceSolutionMinVersion = version.Must(version.NewVersion("8.18.0"))
16+
1417
func ResourceSpace() *schema.Resource {
1518
apikeySchema := map[string]*schema.Schema{
1619
"id": {
@@ -38,6 +41,7 @@ func ResourceSpace() *schema.Resource {
3841
Description: "The list of disabled features for the space. To get a list of available feature IDs, use the Features API (https://www.elastic.co/guide/en/kibana/master/features-api-get.html).",
3942
Type: schema.TypeSet,
4043
Optional: true,
44+
Computed: true,
4145
Elem: &schema.Schema{
4246
Type: schema.TypeString,
4347
},
@@ -61,6 +65,13 @@ func ResourceSpace() *schema.Resource {
6165
Optional: true,
6266
ValidateFunc: validation.StringMatch(regexp.MustCompile("^data:image/"), "must be a valid data-URL encoded image"),
6367
},
68+
"solution": {
69+
Description: "The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.",
70+
Type: schema.TypeString,
71+
Optional: true,
72+
Computed: true,
73+
ValidateFunc: validation.StringInSlice([]string{"security", "oblt", "es", "classic"}, false),
74+
},
6475
}
6576

6677
return &schema.Resource{
@@ -90,6 +101,18 @@ func resourceSpaceUpsert(ctx context.Context, d *schema.ResourceData, meta inter
90101
return diag.FromErr(err)
91102
}
92103

104+
// Check version compatibility for solution field
105+
if solution, ok := d.GetOk("solution"); ok && solution.(string) != "" {
106+
serverVersion, diags := client.ServerVersion(ctx)
107+
if diags.HasError() {
108+
return diags
109+
}
110+
111+
if !serverVersion.GreaterThanOrEqual(SpaceSolutionMinVersion) {
112+
return diag.Errorf("solution field is not supported in this version of the Elastic Stack. Solution field requires %s or higher", SpaceSolutionMinVersion)
113+
}
114+
}
115+
93116
space := kbapi.KibanaSpace{
94117
ID: d.Get("space_id").(string),
95118
Name: d.Get("name").(string),
@@ -120,6 +143,10 @@ func resourceSpaceUpsert(ctx context.Context, d *schema.ResourceData, meta inter
120143
space.ImageURL = imageUrl.(string)
121144
}
122145

146+
if solution, ok := d.GetOk("solution"); ok {
147+
space.Solution = solution.(string)
148+
}
149+
123150
var spaceResponse *kbapi.KibanaSpace
124151

125152
if d.IsNewResource() {
@@ -182,6 +209,9 @@ func resourceSpaceRead(ctx context.Context, d *schema.ResourceData, meta interfa
182209
if err := d.Set("color", space.Color); err != nil {
183210
return diag.FromErr(err)
184211
}
212+
if err := d.Set("solution", space.Solution); err != nil {
213+
return diag.FromErr(err)
214+
}
185215

186216
return diags
187217
}

internal/kibana/space_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66

77
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
88
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/kibana"
10+
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
911
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
1012
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1113
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
@@ -39,6 +41,16 @@ func TestAccResourceSpace(t *testing.T) {
3941
resource.TestCheckResourceAttrSet("elasticstack_kibana_space.test_space", "image_url"),
4042
),
4143
},
44+
{
45+
Config: testAccResourceSpaceWithSolution(spaceId),
46+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(kibana.SpaceSolutionMinVersion),
47+
Check: resource.ComposeTestCheckFunc(
48+
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "space_id", spaceId),
49+
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "name", fmt.Sprintf("Solution %s", spaceId)),
50+
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "description", "Test Space with Solution"),
51+
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "solution", "security"),
52+
),
53+
},
4254
{
4355
Config: testAccResourceSpaceCreate(spaceId),
4456
Check: resource.ComposeTestCheckFunc(
@@ -83,6 +95,21 @@ resource "elasticstack_kibana_space" "test_space" {
8395
`, id, fmt.Sprintf("Updated %s", id))
8496
}
8597

98+
func testAccResourceSpaceWithSolution(id string) string {
99+
return fmt.Sprintf(`
100+
provider "elasticstack" {
101+
kibana {}
102+
}
103+
104+
resource "elasticstack_kibana_space" "test_space" {
105+
space_id = "%s"
106+
name = "%s"
107+
description = "Test Space with Solution"
108+
solution = "security"
109+
}
110+
`, id, fmt.Sprintf("Solution %s", id))
111+
}
112+
86113
func checkResourceSpaceDestroy(s *terraform.State) error {
87114
client, err := clients.NewAcceptanceTestingClient()
88115
if err != nil {

internal/kibana/spaces/models.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ type model struct {
1717
Initials types.String `tfsdk:"initials"`
1818
Color types.String `tfsdk:"color"`
1919
ImageUrl types.String `tfsdk:"image_url"`
20+
Solution types.String `tfsdk:"solution"`
2021
}

internal/kibana/spaces/read.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (d *dataSource) Read(ctx context.Context, req datasource.ReadRequest, resp
2727
Initials: types.StringValue(space.Initials),
2828
Color: types.StringValue(space.Color),
2929
ImageUrl: types.StringValue(space.ImageURL),
30+
Solution: types.StringValue(space.Solution),
3031
}
3132

3233
disabledFeatures, diags := types.ListValueFrom(ctx, types.StringType, space.DisabledFeatures)

internal/kibana/spaces/schema.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func (d *dataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp
3737
"disabled_features": schema.ListAttribute{
3838
Description: "The list of disabled features for the space. To get a list of available feature IDs, use the Features API (https://www.elastic.co/guide/en/kibana/master/features-api-get.html).",
3939
ElementType: types.StringType,
40-
Optional: true,
40+
Computed: true,
4141
},
4242
"initials": schema.StringAttribute{
4343
Description: "The initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters.",
@@ -51,6 +51,10 @@ func (d *dataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp
5151
Description: "The data-URL encoded image to display in the space avatar.",
5252
Optional: true,
5353
},
54+
"solution": schema.StringAttribute{
55+
Description: "The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.",
56+
Computed: true,
57+
},
5458
},
5559
},
5660
},

0 commit comments

Comments
 (0)