Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [Unreleased]

- Fix secret handling `elasticstack_fleet_integration_policy` resource. ([#821](https://github.com/elastic/terraform-provider-elasticstack/pull/821))
- Add `description` attribute to `elasticstack_elasticsearch_security_role` resource. ([#824](https://github.com/elastic/terraform-provider-elasticstack/pull/824))

## [0.11.8] - 2024-10-02

Expand Down
6 changes: 4 additions & 2 deletions docs/resources/elasticsearch_security_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ provider "elasticstack" {
}

resource "elasticstack_elasticsearch_security_role" "role" {
name = "testrole"
cluster = ["all"]
name = "testrole"
description = "Role for testing"
cluster = ["all"]

indices {
names = ["index1", "index2"]
Expand Down Expand Up @@ -55,6 +56,7 @@ output "role" {

- `applications` (Block Set) A list of application privilege entries. (see [below for nested schema](#nestedblock--applications))
- `cluster` (Set of String) A list of cluster privileges. These privileges define the cluster level actions that users with this role are able to execute.
- `description` (String) The description of the role.
- `elasticsearch_connection` (Block List, Max: 1, Deprecated) Elasticsearch connection configuration block. This property will be removed in a future provider version. Configure the Elasticsearch connection via the provider configuration instead. (see [below for nested schema](#nestedblock--elasticsearch_connection))
- `global` (String) An object defining global privileges.
- `indices` (Block Set) A list of indices permissions entries. (see [below for nested schema](#nestedblock--indices))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ provider "elasticstack" {
}

resource "elasticstack_elasticsearch_security_role" "role" {
name = "testrole"
cluster = ["all"]
name = "testrole"
description = "Role for testing"
cluster = ["all"]

indices {
names = ["index1", "index2"]
Expand Down
63 changes: 41 additions & 22 deletions internal/elasticsearch/security/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func ResourceRole() *schema.Resource {
Required: true,
ForceNew: true,
},
"description": {
Description: "The description of the role.",
Type: schema.TypeString,
Optional: true,
},
"applications": {
Description: "A list of application privilege entries.",
Type: schema.TypeSet,
Expand Down Expand Up @@ -258,6 +263,13 @@ func resourceSecurityRolePut(ctx context.Context, d *schema.ResourceData, meta i
}
var role models.Role
role.Name = roleId

// Add description to the role
if v, ok := d.GetOk("description"); ok {
description := v.(string)
role.Description = &description
}

if v, ok := d.GetOk("applications"); ok {
definedApps := v.(*schema.Set)
applications := make([]models.Application, definedApps.Len())
Expand Down Expand Up @@ -364,37 +376,37 @@ func resourceSecurityRolePut(ctx context.Context, d *schema.ResourceData, meta i
if definedRemoteIndices.Len() > 0 && serverVersion.LessThan(minSupportedRemoteIndicesVersion) {
return diag.FromErr(fmt.Errorf("'remote_indices' is supported only for Elasticsearch v%s and above", minSupportedRemoteIndicesVersion.String()))
}
remote_indices := make([]models.RemoteIndexPerms, definedRemoteIndices.Len())
remoteIndices := make([]models.RemoteIndexPerms, definedRemoteIndices.Len())
for i, idx := range definedRemoteIndices.List() {
remote_index := idx.(map[string]interface{})
remoteIndex := idx.(map[string]interface{})

definedRemoteNames := remote_index["names"].(*schema.Set)
remote_names := make([]string, definedRemoteNames.Len())
definedRemoteNames := remoteIndex["names"].(*schema.Set)
remoteNames := make([]string, definedRemoteNames.Len())
for i, name := range definedRemoteNames.List() {
remote_names[i] = name.(string)
remoteNames[i] = name.(string)
}
definedRemoteClusters := remote_index["clusters"].(*schema.Set)
remote_clusters := make([]string, definedRemoteClusters.Len())
definedRemoteClusters := remoteIndex["clusters"].(*schema.Set)
remoteClusters := make([]string, definedRemoteClusters.Len())
for i, cluster := range definedRemoteClusters.List() {
remote_clusters[i] = cluster.(string)
remoteClusters[i] = cluster.(string)
}
definedRemotePrivs := remote_index["privileges"].(*schema.Set)
remote_privs := make([]string, definedRemotePrivs.Len())
definedRemotePrivs := remoteIndex["privileges"].(*schema.Set)
remotePrivs := make([]string, definedRemotePrivs.Len())
for i, pr := range definedRemotePrivs.List() {
remote_privs[i] = pr.(string)
remotePrivs[i] = pr.(string)
}

newRemoteIndex := models.RemoteIndexPerms{
Names: remote_names,
Clusters: remote_clusters,
Privileges: remote_privs,
Names: remoteNames,
Clusters: remoteClusters,
Privileges: remotePrivs,
}

if query := remote_index["query"].(string); query != "" {
if query := remoteIndex["query"].(string); query != "" {
newRemoteIndex.Query = &query
}
if fieldSec := remote_index["field_security"].([]interface{}); len(fieldSec) > 0 {
remote_fieldSecurity := models.FieldSecurity{}
if fieldSec := remoteIndex["field_security"].([]interface{}); len(fieldSec) > 0 {
remoteFieldSecurity := models.FieldSecurity{}
// there must be only 1 entry
definedRemoteFieldSec := fieldSec[0].(map[string]interface{})

Expand All @@ -404,22 +416,22 @@ func resourceSecurityRolePut(ctx context.Context, d *schema.ResourceData, meta i
for i, grant := range gr.List() {
grants[i] = grant.(string)
}
remote_fieldSecurity.Grant = grants
remoteFieldSecurity.Grant = grants
}
// except
if exp := definedRemoteFieldSec["except"].(*schema.Set); exp != nil {
excepts := make([]string, exp.Len())
for i, except := range exp.List() {
excepts[i] = except.(string)
}
remote_fieldSecurity.Except = excepts
remoteFieldSecurity.Except = excepts
}
newRemoteIndex.FieldSecurity = &remote_fieldSecurity
newRemoteIndex.FieldSecurity = &remoteFieldSecurity
}

remote_indices[i] = newRemoteIndex
remoteIndices[i] = newRemoteIndex
}
role.RemoteIndices = remote_indices
role.RemoteIndices = remoteIndices
}

if v, ok := d.GetOk("metadata"); ok {
Expand Down Expand Up @@ -473,6 +485,13 @@ func resourceSecurityRoleRead(ctx context.Context, d *schema.ResourceData, meta
return diag.FromErr(err)
}

// Set the description if it exists
if role.Description != nil {
if err := d.Set("description", *role.Description); err != nil {
return diag.FromErr(err)
}
}

apps := role.Applications
applications := flattenApplicationsData(&apps)
if err := d.Set("applications", applications); err != nil {
Expand Down
12 changes: 9 additions & 3 deletions internal/elasticsearch/security/role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestAccResourceSecurityRole(t *testing.T) {
Config: testAccResourceSecurityRoleCreate(roleName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_role.test", "name", roleName),
resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_role.test", "description", "test description"),
resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_role.test", "indices.0.allow_restricted_indices", "true"),
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_security_role.test", "indices.*.names.*", "index1"),
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_security_role.test", "indices.*.names.*", "index2"),
Expand All @@ -41,6 +42,7 @@ func TestAccResourceSecurityRole(t *testing.T) {
Config: testAccResourceSecurityRoleUpdate(roleName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_role.test", "name", roleName),
resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_role.test", "description", "updated test description"),
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_security_role.test", "indices.*.names.*", "index1"),
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_security_role.test", "indices.*.names.*", "index2"),
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_security_role.test", "cluster.*", "all"),
Expand Down Expand Up @@ -92,7 +94,9 @@ provider "elasticstack" {
}

resource "elasticstack_elasticsearch_security_role" "test" {
name = "%s"
name = "%s"
description = "test description"

cluster = ["all"]

indices {
Expand Down Expand Up @@ -123,7 +127,9 @@ provider "elasticstack" {
}

resource "elasticstack_elasticsearch_security_role" "test" {
name = "%s"
name = "%s"
description = "updated test description"

cluster = ["all"]

indices {
Expand Down Expand Up @@ -234,7 +240,7 @@ func checkResourceSecurityRoleDestroy(s *terraform.State) error {
}

if res.StatusCode != 404 {
return fmt.Errorf("Role (%s) still exists", compId.ResourceId)
return fmt.Errorf("role (%s) still exists", compId.ResourceId)
}
}
return nil
Expand Down
1 change: 1 addition & 0 deletions internal/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type UserPassword struct {

type Role struct {
Name string `json:"-"`
Description *string `json:"description,omitempty"`
Applications []Application `json:"applications,omitempty"`
Global map[string]interface{} `json:"global,omitempty"`
Cluster []string `json:"cluster,omitempty"`
Expand Down
Loading