package provider import ( "context" "fmt" "os" "testing" elastic7 "github.com/olivere/elastic/v7" elastic6 "gopkg.in/olivere/elastic.v6" "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" ) func TestAccOpensearchOpenDistroUser(t *testing.T) { provider := Provider() diags := provider.Configure(context.Background(), &terraform.ResourceConfig{}) if diags.HasError() { t.Skipf("err: %#v", diags) } meta := provider.Meta() esClient, err := getClient(meta.(*ProviderConf)) if err != nil { t.Skipf("err: %s", err) } var allowed bool switch esClient.(type) { case *elastic6.Client: allowed = false default: allowed = true } randomName := "test" + acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) if !allowed { t.Skip("Users only supported on ES >= 7") } }, Providers: testAccOpendistroProviders, CheckDestroy: testAccCheckOpensearchUserDestroy, Steps: []resource.TestStep{ { Config: testAccOpenDistroUserResource(randomName), Check: resource.ComposeTestCheckFunc( testCheckOpensearchUserExists("opensearch_user.test"), testCheckOpensearchUserConnects("opensearch_user.test"), resource.TestCheckResourceAttr( "opensearch_user.test", "id", randomName, ), resource.TestCheckResourceAttr( "opensearch_user.test", "backend_roles.#", "1", ), resource.TestCheckResourceAttr( "opensearch_user.test", "attributes.some_attribute", "alpha", ), resource.TestCheckResourceAttr( "opensearch_user.test", "description", "test", ), ), }, { Config: testAccOpenDistroUserResourceUpdated(randomName), Check: resource.ComposeTestCheckFunc( testCheckOpensearchUserExists("opensearch_user.test"), testCheckOpensearchUserConnects("opensearch_user.test"), resource.TestCheckResourceAttr( "opensearch_user.test", "backend_roles.#", "2", ), ), }, { Config: testAccOpenDistroUserResourceMinimal(randomName), Check: resource.ComposeTestCheckFunc( testCheckOpensearchUserExists("opensearch_user.test"), resource.TestCheckResourceAttr( "opensearch_user.test", "backend_roles.#", "0", ), ), }, { Config: testAccOpenDistroUserResourceHash(randomName), Check: resource.ComposeTestCheckFunc( testCheckOpensearchUserExists("opensearch_user.test"), resource.TestCheckResourceAttr( "opensearch_user.test", "id", randomName, ), ), }, }, }) } func TestAccOpensearchOpenDistroUserMultiple(t *testing.T) { provider := Provider() diags := provider.Configure(context.Background(), &terraform.ResourceConfig{}) if diags.HasError() { t.Skipf("err: %#v", diags) } meta := provider.Meta() esClient, err := getClient(meta.(*ProviderConf)) if err != nil { t.Skipf("err: %s", err) } var allowed bool switch esClient.(type) { case *elastic6.Client: allowed = false default: allowed = true } randomName := "test" + acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) if !allowed { t.Skip("Users only supported on ES >= 7") } }, Providers: testAccOpendistroProviders, CheckDestroy: testAccCheckOpensearchUserDestroy, Steps: []resource.TestStep{ { Config: testAccOpenDistroUserMultiple(randomName), Check: resource.ComposeTestCheckFunc( testCheckOpensearchUserExists("opensearch_user.testuser1"), ), }, }, }) } func testAccCheckOpensearchUserDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "opensearch_user" { continue } meta := testAccOpendistroProvider.Meta() var err error esClient, err := getClient(meta.(*ProviderConf)) if err != nil { return err } switch esClient.(type) { case *elastic7.Client: _, err = resourceOpensearchGetOpenDistroUser(rs.Primary.ID, meta.(*ProviderConf)) default: } if err != nil { return nil // should be not found error } return fmt.Errorf("User %q still exists", rs.Primary.ID) } return nil } func testCheckOpensearchUserExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "opensearch_user" { continue } meta := testAccOpendistroProvider.Meta() var err error esClient, err := getClient(meta.(*ProviderConf)) if err != nil { return err } switch esClient.(type) { case *elastic7.Client: _, err = resourceOpensearchGetOpenDistroUser(rs.Primary.ID, meta.(*ProviderConf)) default: } if err != nil { return err } return nil } return nil } } func testCheckOpensearchUserConnects(name string) resource.TestCheckFunc { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "opensearch_user" { continue } username := rs.Primary.Attributes["username"] password := rs.Primary.Attributes["password"] meta := testAccOpendistroProvider.Meta() var err error esClient, err := getClient(meta.(*ProviderConf)) if err != nil { return err } switch esClient.(type) { case *elastic7.Client: var client *elastic7.Client client, err = elastic7.NewClient( elastic7.SetURL(os.Getenv("OPENSEARCH_URL")), elastic7.SetBasicAuth(username, password)) if err == nil { _, err = client.ClusterHealth().Do(context.TODO()) } } if err != nil { return err } return nil } return nil } } func testAccOpenDistroUserResource(resourceName string) string { return fmt.Sprintf(` resource "opensearch_user" "test" { username = "%s" password = "passw0rd" description = "test" backend_roles = ["some_role"] attributes = { some_attribute = "alpha" } } `, resourceName) } func testAccOpenDistroUserResourceHash(resourceName string) string { return fmt.Sprintf(` resource "opensearch_user" "test" { username = "%s" password_hash = "$2a$04$jQcEXpODnTFoGDuA7DPdSevA84CuH/7MOYkb80M3XZIrH76YMWS9G" } `, resourceName) } func testAccOpenDistroUserResourceUpdated(resourceName string) string { return fmt.Sprintf(` resource "opensearch_user" "test" { username = "%s" password = "passw0rd" description = "test" backend_roles = ["some_role", "monitor_role"] attributes = { some_attribute = "alpha" other_attribute = "beta" } } resource "opensearch_role" "security_role" { role_name = "monitor_security_role" cluster_permissions = ["cluster_monitor"] } resource "opensearch_roles_mapping" "security_role" { role_name = "${opensearch_role.security_role.id}" backend_roles = ["monitor_role"] } `, resourceName) } func testAccOpenDistroUserResourceMinimal(resourceName string) string { return fmt.Sprintf(` resource "opensearch_user" "test" { username = "%s" password = "passw0rd" } `, resourceName) } func testAccOpenDistroUserMultiple(resourceName string) string { return fmt.Sprintf(` resource "opensearch_user" "testuser1" { username = "%s-testuser1" password = "testuser1" description = "testuser1" } resource "opensearch_user" "testuser2" { username = "%s-testuser2" password = "testuser2" description = "testuser2" } resource "opensearch_user" "testuser3" { username = "%s-testuser3" password = "testuser3" description = "testuser3" } `, resourceName, resourceName, resourceName) }