Skip to content
Merged
59 changes: 3 additions & 56 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,62 +21,6 @@ jobs:
permissions:
# 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.
contents: read
env:
ELASTICSEARCH_ENDPOINTS: "http://localhost:9200"
ELASTICSEARCH_USERNAME: "elastic"
ELASTICSEARCH_PASSWORD: password
KIBANA_ENDPOINT: "http://localhost:5601"
KIBANA_USERNAME: "elastic"
KIBANA_PASSWORD: password
KIBANA_SYSTEM_USERNAME: kibana_system
KIBANA_SYSTEM_PASSWORD: password
TF_ACC: "1"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:9.0.3
env:
discovery.type: single-node
xpack.security.enabled: true
xpack.security.authc.api_key.enabled: true
xpack.security.authc.token.enabled: true
xpack.watcher.enabled: true
xpack.license.self_generated.type: trial
repositories.url.allowed_urls: https://example.com/*
path.repo: /tmp
ELASTIC_PASSWORD: ${{ env.ELASTICSEARCH_PASSWORD }}
ports:
- 9200:9200
options: --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=10
kibana:
image: docker.elastic.co/kibana/kibana:9.0.3
env:
SERVER_NAME: kibana
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
ELASTICSEARCH_USERNAME: ${{ env.KIBANA_SYSTEM_USERNAME }}
ELASTICSEARCH_PASSWORD: ${{ env.KIBANA_SYSTEM_PASSWORD }}
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: a7a6311933d3503b89bc2dbc36572c33a6c10925682e591bffcab6911c06786d
# LOGGING_ROOT_LEVEL: debug
ports:
- 5601:5601
options: --health-cmd="curl http://localhost:5601/api/status" --health-interval=10s --health-timeout=5s --health-retries=10
fleet:
image: docker.elastic.co/elastic-agent/elastic-agent:9.0.3
env:
SERVER_NAME: fleet
FLEET_ENROLL: "1"
FLEET_URL: https://fleet:8220
FLEET_INSECURE: "true"
FLEET_SERVER_ENABLE: "1"
FLEET_SERVER_POLICY_ID: fleet-server
FLEET_SERVER_ELASTICSEARCH_HOST: http://elasticsearch:9200
FLEET_SERVER_ELASTICSEARCH_INSECURE: "true"
FLEET_SERVER_INSECURE_HTTP: "true"
KIBANA_HOST: http://kibana:5601
KIBANA_FLEET_SETUP: "1"
KIBANA_FLEET_PASSWORD: ${{ env.ELASTICSEARCH_PASSWORD }}
ports:
- 8220:8220
options: --restart="unless-stopped"

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
Expand All @@ -88,6 +32,9 @@ jobs:
with:
terraform_wrapper: false

- name: Setup Elastic Stack
run: make docker-fleet

- name: Get dependencies
run: make setup

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ jobs:
- '8.15.5'
- '8.16.2'
- '8.17.0'
- '8.18.3'
- '9.0.0-SNAPSHOT'
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [Unreleased]

- Add support for `solution` field in `elasticstack_kibana_space` resource and data source ([#1102](https://github.com/elastic/terraform-provider-elasticstack/issues/1102))
- Add support for `timeslice_metric_indicator` in `elasticstack_kibana_slo` ([#1195](https://github.com/elastic/terraform-provider-elasticstack/pull/1195))
- Add `elasticstack_elasticsearch_ingest_processor_reroute` data source ([#678](https://github.com/elastic/terraform-provider-elasticstack/issues/678))
- Add support for `supports_agentless` to `elasticstack_fleet_agent_policy` ([#1197](https://github.com/elastic/terraform-provider-elasticstack/pull/1197))
Expand Down
3 changes: 2 additions & 1 deletion docs/data-sources/kibana_spaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ Required:
Optional:

- `description` (String) The description for the space.
- `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).
- `image_url` (String) The data-URL encoded image to display in the space avatar.

Read-Only:

- `color` (String) The hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name.
- `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).
- `id` (String) Internal identifier of the resource.
- `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.
- `solution` (String) The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.
1 change: 1 addition & 0 deletions docs/resources/kibana_space.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This document isn't correctly generated. Run make docs-generate and commit the result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the documentation generation by running make docs-generate. The schema is now properly generated with the correct field classifications. Commit 8cf1bf9

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ resource "elasticstack_kibana_space" "example" {
- `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).
- `image_url` (String) The data-URL encoded image to display in the space avatar.
- `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.
- `solution` (String) The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.

### Read-Only

Expand Down
30 changes: 30 additions & 0 deletions internal/kibana/space.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (

"github.com/disaster37/go-kibana-rest/v8/kbapi"
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

var SpaceSolutionMinVersion = version.Must(version.NewVersion("8.18.0"))

func ResourceSpace() *schema.Resource {
apikeySchema := map[string]*schema.Schema{
"id": {
Expand Down Expand Up @@ -38,6 +41,7 @@ func ResourceSpace() *schema.Resource {
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).",
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Expand All @@ -61,6 +65,13 @@ func ResourceSpace() *schema.Resource {
Optional: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile("^data:image/"), "must be a valid data-URL encoded image"),
},
"solution": {
Description: "The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.",
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{"security", "oblt", "es", "classic"}, false),
},
}

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

// Check version compatibility for solution field
if solution, ok := d.GetOk("solution"); ok && solution.(string) != "" {
serverVersion, diags := client.ServerVersion(ctx)
if diags.HasError() {
return diags
}

if !serverVersion.GreaterThanOrEqual(SpaceSolutionMinVersion) {
return diag.Errorf("solution field is not supported in this version of the Elastic Stack. Solution field requires %s or higher", SpaceSolutionMinVersion)
}
}

space := kbapi.KibanaSpace{
ID: d.Get("space_id").(string),
Name: d.Get("name").(string),
Expand Down Expand Up @@ -120,6 +143,10 @@ func resourceSpaceUpsert(ctx context.Context, d *schema.ResourceData, meta inter
space.ImageURL = imageUrl.(string)
}

if solution, ok := d.GetOk("solution"); ok {
space.Solution = solution.(string)
}

var spaceResponse *kbapi.KibanaSpace

if d.IsNewResource() {
Expand Down Expand Up @@ -182,6 +209,9 @@ func resourceSpaceRead(ctx context.Context, d *schema.ResourceData, meta interfa
if err := d.Set("color", space.Color); err != nil {
return diag.FromErr(err)
}
if err := d.Set("solution", space.Solution); err != nil {
return diag.FromErr(err)
}

return diags
}
Expand Down
27 changes: 27 additions & 0 deletions internal/kibana/space_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (

"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
"github.com/elastic/terraform-provider-elasticstack/internal/kibana"
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down Expand Up @@ -39,6 +41,16 @@ func TestAccResourceSpace(t *testing.T) {
resource.TestCheckResourceAttrSet("elasticstack_kibana_space.test_space", "image_url"),
),
},
{
Config: testAccResourceSpaceWithSolution(spaceId),
SkipFunc: versionutils.CheckIfVersionIsUnsupported(kibana.SpaceSolutionMinVersion),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "space_id", spaceId),
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "name", fmt.Sprintf("Solution %s", spaceId)),
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "description", "Test Space with Solution"),
resource.TestCheckResourceAttr("elasticstack_kibana_space.test_space", "solution", "security"),
),
},
{
Config: testAccResourceSpaceCreate(spaceId),
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -83,6 +95,21 @@ resource "elasticstack_kibana_space" "test_space" {
`, id, fmt.Sprintf("Updated %s", id))
}

func testAccResourceSpaceWithSolution(id string) string {
return fmt.Sprintf(`
provider "elasticstack" {
kibana {}
}

resource "elasticstack_kibana_space" "test_space" {
space_id = "%s"
name = "%s"
description = "Test Space with Solution"
solution = "security"
}
`, id, fmt.Sprintf("Solution %s", id))
}

func checkResourceSpaceDestroy(s *terraform.State) error {
client, err := clients.NewAcceptanceTestingClient()
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions internal/kibana/spaces/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ type model struct {
Initials types.String `tfsdk:"initials"`
Color types.String `tfsdk:"color"`
ImageUrl types.String `tfsdk:"image_url"`
Solution types.String `tfsdk:"solution"`
}
1 change: 1 addition & 0 deletions internal/kibana/spaces/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (d *dataSource) Read(ctx context.Context, req datasource.ReadRequest, resp
Initials: types.StringValue(space.Initials),
Color: types.StringValue(space.Color),
ImageUrl: types.StringValue(space.ImageURL),
Solution: types.StringValue(space.Solution),
}

disabledFeatures, diags := types.ListValueFrom(ctx, types.StringType, space.DisabledFeatures)
Expand Down
6 changes: 5 additions & 1 deletion internal/kibana/spaces/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (d *dataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp
"disabled_features": schema.ListAttribute{
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).",
ElementType: types.StringType,
Optional: true,
Computed: true,
},
"initials": schema.StringAttribute{
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.",
Expand All @@ -51,6 +51,10 @@ func (d *dataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp
Description: "The data-URL encoded image to display in the space avatar.",
Optional: true,
},
"solution": schema.StringAttribute{
Description: "The solution view for the space. Valid options are `security`, `oblt`, `es`, or `classic`.",
Computed: true,
},
},
},
},
Expand Down
1 change: 1 addition & 0 deletions libs/go-kibana-rest/kbapi/api.kibana_spaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type KibanaSpace struct {
Initials string `json:"initials,omitempty"`
Color string `json:"color,omitempty"`
ImageURL string `json:"imageUrl,omitempty"`
Solution string `json:"solution,omitempty"`
}

// KibanaSpaces is the list of KibanaSpace object
Expand Down
1 change: 1 addition & 0 deletions libs/go-kibana-rest/kbapi/api.kibana_spaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (s *KBAPITestSuite) TestKibanaSpaces() {
ID: "test",
Name: "test",
Description: "My test",
Solution: "security",
}
kibanaSpace, err = s.KibanaSpaces.Create(kibanaSpace)
assert.NoError(s.T(), err)
Expand Down
Loading