diff --git a/resource_elasticsearch_xpack_role.go b/resource_elasticsearch_xpack_role.go index 18e3c6f2..3047d08e 100644 --- a/resource_elasticsearch_xpack_role.go +++ b/resource_elasticsearch_xpack_role.go @@ -8,6 +8,7 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + elastic7 "github.com/olivere/elastic/v7" elastic5 "gopkg.in/olivere/elastic.v5" elastic6 "gopkg.in/olivere/elastic.v6" ) @@ -130,6 +131,11 @@ func resourceElasticsearchXpackRoleRead(d *schema.ResourceData, m interface{}) e role, err := xpackGetRole(d, m, d.Id()) if err != nil { fmt.Println("Error during read") + if elasticErr, ok := err.(*elastic7.Error); ok && elasticErr.Status == 404 { + fmt.Printf("[WARN] Role %s not found. Removing from state\n", d.Id()) + d.SetId("") + return nil + } if elasticErr, ok := err.(*elastic6.Error); ok && elasticErr.Status == 404 { fmt.Printf("[WARN] Role %s not found. Removing from state\n", d.Id()) d.SetId("") @@ -168,6 +174,11 @@ func resourceElasticsearchXpackRoleDelete(d *schema.ResourceData, m interface{}) err := xpackDeleteRole(d, m, d.Id()) if err != nil { fmt.Println("Error during destroy") + if elasticErr, ok := err.(*elastic7.Error); ok && elasticErr.Status == 404 { + fmt.Printf("[WARN] Role %s not found. Resource removed from state\n", d.Id()) + d.SetId("") + return nil + } if elasticErr, ok := err.(*elastic6.Error); ok && elasticErr.Status == 404 { fmt.Printf("[WARN] Role %s not found. Resource removed from state\n", d.Id()) d.SetId("") @@ -236,6 +247,9 @@ func buildPutRoleBody(d *schema.ResourceData, m interface{}) (string, error) { } func xpackPutRole(d *schema.ResourceData, m interface{}, name string, body string) error { + if client, ok := m.(*elastic7.Client); ok { + return elastic7PutRole(client, name, body) + } if client, ok := m.(*elastic6.Client); ok { return elastic6PutRole(client, name, body) } @@ -246,6 +260,9 @@ func xpackPutRole(d *schema.ResourceData, m interface{}, name string, body strin } func xpackGetRole(d *schema.ResourceData, m interface{}, name string) (XPackSecurityRole, error) { + if client, ok := m.(*elastic7.Client); ok { + return elastic7GetRole(client, name) + } if client, ok := m.(*elastic6.Client); ok { return elastic6GetRole(client, name) } @@ -256,6 +273,9 @@ func xpackGetRole(d *schema.ResourceData, m interface{}, name string) (XPackSecu } func xpackDeleteRole(d *schema.ResourceData, m interface{}, name string) error { + if client, ok := m.(*elastic7.Client); ok { + return elastic7DeleteRole(client, name) + } if client, ok := m.(*elastic6.Client); ok { return elastic6DeleteRole(client, name) } @@ -275,6 +295,12 @@ func elastic6PutRole(client *elastic6.Client, name string, body string) error { return err } +func elastic7PutRole(client *elastic7.Client, name string, body string) error { + _, err := client.XPackSecurityPutRole(name).Body(body).Do(context.Background()) + log.Printf("[INFO] put error: %+v", err) + return err +} + func elastic5GetRole(client *elastic5.Client, name string) (XPackSecurityRole, error) { err := errors.New("unsupported in elasticv5 client") return XPackSecurityRole{}, err @@ -320,6 +346,46 @@ func elastic6GetRole(client *elastic6.Client, name string) (XPackSecurityRole, e return role, err } +func elastic7GetRole(client *elastic7.Client, name string) (XPackSecurityRole, error) { + res, err := client.XPackSecurityGetRole(name).Do(context.Background()) + if err != nil { + return XPackSecurityRole{}, err + } + obj := (*res)[name] + role := XPackSecurityRole{} + role.Name = name + role.Cluster = obj.Cluster + if data, err := json.Marshal(obj.Indices); err == nil { + if err := json.Unmarshal(data, &role.Indices); err != nil { + fmt.Printf("Data : %s\n", data) + return role, err + } + } + + if data, err := json.Marshal(obj.Applications); err == nil { + if err := json.Unmarshal(data, &role.Applications); err != nil { + fmt.Printf("Data : %s\n", data) + return role, err + } + } + if global, err := json.Marshal(obj.Global); err != nil { + return role, err + } else { + // The Elastic API will not return the field unless it exists, which force us to check for null compared to Metadata + if string(global) == "null" { + role.Global = "" + } else { + role.Global = string(global) + } + } + if metadata, err := json.Marshal(obj.Metadata); err != nil { + return role, err + } else { + role.Metadata = string(metadata) + } + return role, err +} + func elastic5DeleteRole(client *elastic5.Client, name string) error { err := errors.New("unsupported in elasticv5 client") return err @@ -330,6 +396,11 @@ func elastic6DeleteRole(client *elastic6.Client, name string) error { return err } +func elastic7DeleteRole(client *elastic7.Client, name string) error { + _, err := client.XPackSecurityDeleteRole(name).Do(context.Background()) + return err +} + type PutRoleBody struct { Cluster []string `json:"cluster"` Applications []PutRoleApplicationPrivileges `json:"applications,omitempty"` diff --git a/resource_elasticsearch_xpack_role_mapping.go b/resource_elasticsearch_xpack_role_mapping.go index 969c5221..bf0ddc48 100644 --- a/resource_elasticsearch_xpack_role_mapping.go +++ b/resource_elasticsearch_xpack_role_mapping.go @@ -8,6 +8,7 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + elastic7 "github.com/olivere/elastic/v7" elastic5 "gopkg.in/olivere/elastic.v5" elastic6 "gopkg.in/olivere/elastic.v6" ) @@ -140,6 +141,9 @@ func buildPutRoleMappingBody(d *schema.ResourceData, m interface{}) (string, err } func xpackPutRoleMapping(d *schema.ResourceData, m interface{}, name string, body string) error { + if client, ok := m.(*elastic7.Client); ok { + return elastic7PutRoleMapping(client, name, body) + } if client, ok := m.(*elastic6.Client); ok { return elastic6PutRoleMapping(client, name, body) } @@ -150,6 +154,9 @@ func xpackPutRoleMapping(d *schema.ResourceData, m interface{}, name string, bod } func xpackGetRoleMapping(d *schema.ResourceData, m interface{}, name string) (XPackSecurityRoleMapping, error) { + if client, ok := m.(*elastic7.Client); ok { + return elastic7GetRoleMapping(client, name) + } if client, ok := m.(*elastic6.Client); ok { return elastic6GetRoleMapping(client, name) } @@ -160,6 +167,9 @@ func xpackGetRoleMapping(d *schema.ResourceData, m interface{}, name string) (XP } func xpackDeleteRoleMapping(d *schema.ResourceData, m interface{}, name string) error { + if client, ok := m.(*elastic7.Client); ok { + return elastic7DeleteRoleMapping(client, name) + } if client, ok := m.(*elastic6.Client); ok { return elastic6DeleteRoleMapping(client, name) } @@ -179,6 +189,12 @@ func elastic6PutRoleMapping(client *elastic6.Client, name string, body string) e return err } +func elastic7PutRoleMapping(client *elastic7.Client, name string, body string) error { + resp, err := client.XPackSecurityPutRoleMapping(name).Body(body).Do(context.Background()) + log.Printf("[INFO] put error: %+v, %+v", resp, err) + return err +} + func elastic5GetRoleMapping(client *elastic5.Client, name string) (XPackSecurityRoleMapping, error) { err := errors.New("unsupported in elasticv5 client") return XPackSecurityRoleMapping{}, err @@ -208,6 +224,30 @@ func elastic6GetRoleMapping(client *elastic6.Client, name string) (XPackSecurity return roleMapping, err } +func elastic7GetRoleMapping(client *elastic7.Client, name string) (XPackSecurityRoleMapping, error) { + res, err := client.XPackSecurityGetRoleMapping(name).Do(context.Background()) + if err != nil { + return XPackSecurityRoleMapping{}, err + } + obj := (*res)[name] + roleMapping := XPackSecurityRoleMapping{} + roleMapping.Name = name + roleMapping.Roles = obj.Roles + roleMapping.Enabled = obj.Enabled + if rules, err := json.Marshal(obj.Rules); err != nil { + return roleMapping, err + } else { + roleMapping.Rules = string(rules) + } + if metadata, err := json.Marshal(obj.Metadata); err != nil { + return roleMapping, err + } else { + roleMapping.Metadata = string(metadata) + } + + return roleMapping, err +} + func elastic5DeleteRoleMapping(client *elastic5.Client, name string) error { err := errors.New("unsupported in elasticv5 client") return err @@ -218,6 +258,11 @@ func elastic6DeleteRoleMapping(client *elastic6.Client, name string) error { return err } +func elastic7DeleteRoleMapping(client *elastic7.Client, name string) error { + _, err := client.XPackSecurityDeleteRoleMapping(name).Do(context.Background()) + return err +} + type PutRoleMappingBody struct { Roles []string `json:"roles"` Enabled bool `json:"enabled"` diff --git a/resource_elasticsearch_xpack_role_mapping_test.go b/resource_elasticsearch_xpack_role_mapping_test.go index 28c0c578..0c935822 100644 --- a/resource_elasticsearch_xpack_role_mapping_test.go +++ b/resource_elasticsearch_xpack_role_mapping_test.go @@ -5,6 +5,7 @@ import ( "fmt" "testing" + elastic7 "github.com/olivere/elastic/v7" elastic5 "gopkg.in/olivere/elastic.v5" elastic6 "gopkg.in/olivere/elastic.v6" @@ -100,7 +101,18 @@ func testAccCheckRoleMappingDestroy(s *terraform.State) error { meta := testAccXPackProvider.Meta() - if client, ok := meta.(*elastic6.Client); ok { + if client, ok := meta.(*elastic7.Client); ok { + if _, err := client.XPackSecurityGetRoleMapping(rs.Primary.ID).Do(context.TODO()); err != nil { + if elasticErr, ok := err.(*elastic7.Error); ok && elasticErr.Status == 404 { + return nil + } else { + return fmt.Errorf("Role mapping %q still exists", rs.Primary.ID) + } + } else { + return err + } + + } else if client, ok := meta.(*elastic6.Client); ok { if _, err := client.XPackSecurityGetRoleMapping(rs.Primary.ID).Do(context.TODO()); err != nil { if elasticErr, ok := err.(*elastic6.Error); ok && elasticErr.Status == 404 { return nil @@ -129,9 +141,13 @@ func testCheckRoleMappingExists(name string) resource.TestCheckFunc { } meta := testAccXPackProvider.Meta() - - client := meta.(*elastic6.Client) - _, err := client.XPackSecurityGetRoleMapping(rs.Primary.ID).Do(context.TODO()) + var err error + if client, ok := meta.(*elastic7.Client); ok { + _, err = client.XPackSecurityGetRoleMapping(rs.Primary.ID).Do(context.TODO()) + } else { + client := meta.(*elastic6.Client) + _, err = client.XPackSecurityGetRoleMapping(rs.Primary.ID).Do(context.TODO()) + } if err != nil { return err diff --git a/resource_elasticsearch_xpack_role_test.go b/resource_elasticsearch_xpack_role_test.go index ff2829cb..97b9921e 100644 --- a/resource_elasticsearch_xpack_role_test.go +++ b/resource_elasticsearch_xpack_role_test.go @@ -5,6 +5,7 @@ import ( "fmt" "testing" + elastic7 "github.com/olivere/elastic/v7" elastic5 "gopkg.in/olivere/elastic.v5" elastic6 "gopkg.in/olivere/elastic.v6" @@ -96,7 +97,18 @@ func testAccCheckRoleDestroy(s *terraform.State) error { meta := testAccXPackProvider.Meta() - if client, ok := meta.(*elastic6.Client); ok { + if client, ok := meta.(*elastic7.Client); ok { + if _, err := client.XPackSecurityGetRole(rs.Primary.ID).Do(context.TODO()); err != nil { + if elasticErr, ok := err.(*elastic7.Error); ok && elasticErr.Status == 404 { + return nil + } else { + return fmt.Errorf("Role %q still exists", rs.Primary.ID) + } + } else { + return err + } + + } else if client, ok := meta.(*elastic6.Client); ok { if _, err := client.XPackSecurityGetRole(rs.Primary.ID).Do(context.TODO()); err != nil { if elasticErr, ok := err.(*elastic6.Error); ok && elasticErr.Status == 404 { return nil @@ -126,8 +138,13 @@ func testCheckRoleExists(name string) resource.TestCheckFunc { meta := testAccXPackProvider.Meta() - client := meta.(*elastic6.Client) - _, err := client.XPackSecurityGetRole(rs.Primary.ID).Do(context.TODO()) + var err error + if client, ok := meta.(*elastic7.Client); ok { + _, err = client.XPackSecurityGetRole(rs.Primary.ID).Do(context.TODO()) + } else { + client := meta.(*elastic6.Client) + _, err = client.XPackSecurityGetRole(rs.Primary.ID).Do(context.TODO()) + } if err != nil { return err