diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d581d9c8..d84909d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Remove `space_id` parameter from private locations to fix inconsistent state for `elasticstack_kibana_synthetics_private_location` `space_id` ([#733](https://github.com/elastic/terraform-provider-elasticstack/pull/733)) - Add the `Frequency` field to the Create Rule API ([#753](https://github.com/elastic/terraform-provider-elasticstack/pull/753)) - Prevent a provider panic when the repository referenced in an `elasticstack_elasticsearch_snapshot_repository` does not exist ([#758](https://github.com/elastic/terraform-provider-elasticstack/pull/758)) +- Add support for `remote_indicies` to `elasticstack_elasticsearch_security_api_key` (#766)[https://github.com/elastic/terraform-provider-elasticstack/pull/766] ## [0.11.6] - 2024-08-20 diff --git a/internal/elasticsearch/security/api_key_test.go b/internal/elasticsearch/security/api_key_test.go index 14b433927..519e1d6cc 100644 --- a/internal/elasticsearch/security/api_key_test.go +++ b/internal/elasticsearch/security/api_key_test.go @@ -4,16 +4,18 @@ import ( "context" "encoding/json" "fmt" - "github.com/hashicorp/go-version" "reflect" "regexp" "testing" + "github.com/hashicorp/go-version" + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" "github.com/elastic/terraform-provider-elasticstack/internal/clients" "github.com/elastic/terraform-provider-elasticstack/internal/clients/elasticsearch" "github.com/elastic/terraform-provider-elasticstack/internal/elasticsearch/security" "github.com/elastic/terraform-provider-elasticstack/internal/models" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" "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" @@ -40,14 +42,65 @@ func TestAccResourceSecurityApiKey(t *testing.T) { return err } - allowRestrictedIndices := false expectedRoleDescriptor := map[string]models.ApiKeyRoleDescriptor{ "role-a": { Cluster: []string{"all"}, Indices: []models.IndexPerms{{ Names: []string{"index-a*"}, Privileges: []string{"read"}, - AllowRestrictedIndices: &allowRestrictedIndices, + AllowRestrictedIndices: utils.Pointer(false), + }}, + }, + } + + if !reflect.DeepEqual(testRoleDescriptor, expectedRoleDescriptor) { + return fmt.Errorf("%v doesn't match %v", testRoleDescriptor, expectedRoleDescriptor) + } + + return nil + }), + resource.TestCheckResourceAttrSet("elasticstack_elasticsearch_security_api_key.test", "expiration"), + resource.TestCheckResourceAttrSet("elasticstack_elasticsearch_security_api_key.test", "api_key"), + resource.TestCheckResourceAttrSet("elasticstack_elasticsearch_security_api_key.test", "encoded"), + ), + }, + }, + }) +} + +func TestAccResourceSecurityApiKeyWithRemoteIndices(t *testing.T) { + // generate a random name + apiKeyName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + CheckDestroy: checkResourceSecurityApiKeyDestroy, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minSupportedRemoteIndicesVersion), + Config: testAccResourceSecurityApiKeyRemoteIndices(apiKeyName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_api_key.test", "name", apiKeyName), + resource.TestCheckResourceAttrWith("elasticstack_elasticsearch_security_api_key.test", "role_descriptors", func(testValue string) error { + var testRoleDescriptor map[string]models.ApiKeyRoleDescriptor + if err := json.Unmarshal([]byte(testValue), &testRoleDescriptor); err != nil { + return err + } + + expectedRoleDescriptor := map[string]models.ApiKeyRoleDescriptor{ + "role-a": { + Cluster: []string{"all"}, + Indices: []models.IndexPerms{{ + Names: []string{"index-a*"}, + Privileges: []string{"read"}, + AllowRestrictedIndices: utils.Pointer(false), + }}, + RemoteIndices: []models.RemoteIndexPerms{{ + Clusters: []string{"*"}, + Names: []string{"index-a*"}, + Privileges: []string{"read"}, + AllowRestrictedIndices: utils.Pointer(true), }}, }, } @@ -165,7 +218,38 @@ resource "elasticstack_elasticsearch_security_api_key" "test" { privileges = ["read"] allow_restricted_indices = false }] - } + } + }) + + expiration = "1d" +} + `, apiKeyName) +} + +func testAccResourceSecurityApiKeyRemoteIndices(apiKeyName string) string { + return fmt.Sprintf(` +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_api_key" "test" { + name = "%s" + + role_descriptors = jsonencode({ + role-a = { + cluster = ["all"] + indices = [{ + names = ["index-a*"] + privileges = ["read"] + allow_restricted_indices = false + }] + remote_indices = [{ + clusters = ["*"] + names = ["index-a*"] + privileges = ["read"] + allow_restricted_indices = true + }] + } }) expiration = "1d" @@ -190,8 +274,8 @@ resource "elasticstack_elasticsearch_security_api_key" "test" { privileges = ["read"] allow_restricted_indices = false }], - restriction = { - workflows = [ "search_application_query"] + restriction = { + workflows = [ "search_application_query"] } } }) diff --git a/internal/elasticsearch/security/role_test.go b/internal/elasticsearch/security/role_test.go index 2afb4cc81..40d9da263 100644 --- a/internal/elasticsearch/security/role_test.go +++ b/internal/elasticsearch/security/role_test.go @@ -13,11 +13,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) +var minSupportedRemoteIndicesVersion = version.Must(version.NewSemver("8.10.0")) + func TestAccResourceSecurityRole(t *testing.T) { // generate a random username roleName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum) roleNameRemoteIndices := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum) - minSupportedRemoteIndicesVersion := version.Must(version.NewSemver("8.10.0")) resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -202,7 +203,7 @@ resource "elasticstack_elasticsearch_security_role" "test" { names = ["sample2"] privileges = ["create", "read", "write"] } - + metadata = jsonencode({ version = 1 }) diff --git a/internal/models/models.go b/internal/models/models.go index 9ef5e0b22..67b083975 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -84,14 +84,15 @@ type Role struct { } type ApiKeyRoleDescriptor struct { - Name string `json:"-"` - Applications []Application `json:"applications,omitempty"` - Global map[string]interface{} `json:"global,omitempty"` - Cluster []string `json:"cluster,omitempty"` - Indices []IndexPerms `json:"indices,omitempty"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - RusAs []string `json:"run_as,omitempty"` - Restriction *Restriction `json:"restriction,omitempty"` + Name string `json:"-"` + Applications []Application `json:"applications,omitempty"` + Global map[string]interface{} `json:"global,omitempty"` + Cluster []string `json:"cluster,omitempty"` + Indices []IndexPerms `json:"indices,omitempty"` + RemoteIndices []RemoteIndexPerms `json:"remote_indices,omitempty"` + Metadata map[string]interface{} `json:"metadata,omitempty"` + RusAs []string `json:"run_as,omitempty"` + Restriction *Restriction `json:"restriction,omitempty"` } type Restriction struct { @@ -133,11 +134,12 @@ type IndexPerms struct { } type RemoteIndexPerms struct { - FieldSecurity *FieldSecurity `json:"field_security,omitempty"` - Names []string `json:"names"` - Clusters []string `json:"clusters"` - Privileges []string `json:"privileges"` - Query *string `json:"query,omitempty"` + FieldSecurity *FieldSecurity `json:"field_security,omitempty"` + Names []string `json:"names"` + Clusters []string `json:"clusters"` + Privileges []string `json:"privileges"` + Query *string `json:"query,omitempty"` + AllowRestrictedIndices *bool `json:"allow_restricted_indices,omitempty"` } type FieldSecurity struct {