From d4f0f2fc16e60c986db578d920f74cc5fad93ce8 Mon Sep 17 00:00:00 2001 From: Ludwig Patte Date: Fri, 2 Sep 2022 15:12:33 +0000 Subject: [PATCH] Kafka and opensearch lifecycle --- ovh/data_cloud_project_database.go | 4 +- ...d_project_database_ip_restrictions_test.go | 4 + ovh/data_cloud_project_database_kafka_acl.go | 80 ++++ ...a_cloud_project_database_kafka_acl_test.go | 90 ++++ ovh/data_cloud_project_database_kafka_acls.go | 62 +++ ..._cloud_project_database_kafka_acls_test.go | 87 ++++ ...oud_project_database_kafka_certificates.go | 62 +++ ...roject_database_kafka_certificates_test.go | 71 +++ ...data_cloud_project_database_kafka_topic.go | 95 ++++ ...cloud_project_database_kafka_topic_test.go | 91 ++++ ...ata_cloud_project_database_kafka_topics.go | 62 +++ ...loud_project_database_kafka_topics_test.go | 81 ++++ ...loud_project_database_kafka_user_access.go | 75 +++ ...project_database_kafka_user_access_test.go | 83 ++++ ...loud_project_database_mongodb_user_test.go | 4 + ...oud_project_database_opensearch_pattern.go | 75 +++ ...roject_database_opensearch_pattern_test.go | 78 +++ ...ud_project_database_opensearch_patterns.go | 62 +++ ...oject_database_opensearch_patterns_test.go | 76 +++ ..._cloud_project_database_opensearch_user.go | 110 +++++ ...d_project_database_opensearch_user_test.go | 87 ++++ ..._cloud_project_database_postgresql_user.go | 2 +- ...d_project_database_postgresql_user_test.go | 4 + ovh/data_cloud_project_database_redis_user.go | 8 +- ..._cloud_project_database_redis_user_test.go | 4 + ovh/data_cloud_project_database_test.go | 4 +- ovh/data_cloud_project_database_user_test.go | 4 + ovh/data_cloud_project_database_users_test.go | 4 + ovh/data_cloud_project_databases_test.go | 26 +- ...ud_project_database_ip_restriction_test.go | 1 + ...t_cloud_project_database_kafka_acl_test.go | 70 +++ ...cloud_project_database_kafka_topic_test.go | 68 +++ ...loud_project_database_mongodb_user_test.go | 3 + ...roject_database_opensearch_pattern_test.go | 66 +++ ...d_project_database_opensearch_user_test.go | 65 +++ ...d_project_database_postgresql_user_test.go | 3 + ..._cloud_project_database_redis_user_test.go | 3 + ovh/import_cloud_project_database_test.go | 2 +- ...import_cloud_project_database_user_test.go | 3 + ovh/provider.go | 21 +- ...e_cloud_project_database_ip_restriction.go | 2 +- ...ud_project_database_ip_restriction_test.go | 2 + ...source_cloud_project_database_kafka_acl.go | 151 ++++++ ...e_cloud_project_database_kafka_acl_test.go | 84 ++++ ...urce_cloud_project_database_kafka_topic.go | 202 ++++++++ ...cloud_project_database_kafka_topic_test.go | 110 +++++ ...rce_cloud_project_database_mongodb_user.go | 4 +- ...loud_project_database_mongodb_user_test.go | 4 + ...oud_project_database_opensearch_pattern.go | 159 ++++++ ...roject_database_opensearch_pattern_test.go | 72 +++ ..._cloud_project_database_opensearch_user.go | 221 +++++++++ ...d_project_database_opensearch_user_test.go | 83 ++++ ..._cloud_project_database_postgresql_user.go | 4 +- ...d_project_database_postgresql_user_test.go | 4 + ...ource_cloud_project_database_redis_user.go | 10 +- ..._cloud_project_database_redis_user_test.go | 4 + ovh/resource_cloud_project_database_test.go | 8 +- ...source_cloud_project_database_user_test.go | 4 + ovh/types_cloud_project_database.go | 451 +++++++++++++++++- .../d/cloud_project_database.html.markdown | 8 +- ...ect_database_ip_restrictions.html.markdown | 6 +- ...d_project_database_kafka_acl.html.markdown | 46 ++ ..._project_database_kafka_acls.html.markdown | 40 ++ ..._database_kafka_certificates.html.markdown | 43 ++ ...project_database_kafka_topic.html.markdown | 49 ++ ...roject_database_kafka_topics.html.markdown | 40 ++ ...t_database_kafka_user_access.html.markdown | 46 ++ ...roject_database_mongodb_user.html.markdown | 6 +- ..._database_opensearch_pattern.html.markdown | 45 ++ ...database_opensearch_patterns.html.markdown | 40 ++ ...ect_database_opensearch_user.html.markdown | 48 ++ ...ect_database_postgresql_user.html.markdown | 6 +- ..._project_database_redis_user.html.markdown | 6 +- .../cloud_project_database_user.html.markdown | 8 +- ...cloud_project_database_users.html.markdown | 9 +- .../d/cloud_project_databases.html.markdown | 4 +- website/docs/index.html.markdown | 4 + .../r/cloud_project_database.html.markdown | 117 ++++- ...ject_database_ip_restriction.html.markdown | 8 +- ...d_project_database_kafka_acl.html.markdown | 66 +++ ...project_database_kafka_topic.html.markdown | 76 +++ ...roject_database_mongodb_user.html.markdown | 8 +- ..._database_opensearch_pattern.html.markdown | 58 +++ ...ect_database_opensearch_user.html.markdown | 77 +++ ...ect_database_postgresql_user.html.markdown | 8 +- ..._project_database_redis_user.html.markdown | 16 +- .../cloud_project_database_user.html.markdown | 10 +- 87 files changed, 4169 insertions(+), 108 deletions(-) create mode 100644 ovh/data_cloud_project_database_kafka_acl.go create mode 100644 ovh/data_cloud_project_database_kafka_acl_test.go create mode 100644 ovh/data_cloud_project_database_kafka_acls.go create mode 100644 ovh/data_cloud_project_database_kafka_acls_test.go create mode 100644 ovh/data_cloud_project_database_kafka_certificates.go create mode 100644 ovh/data_cloud_project_database_kafka_certificates_test.go create mode 100644 ovh/data_cloud_project_database_kafka_topic.go create mode 100644 ovh/data_cloud_project_database_kafka_topic_test.go create mode 100644 ovh/data_cloud_project_database_kafka_topics.go create mode 100644 ovh/data_cloud_project_database_kafka_topics_test.go create mode 100644 ovh/data_cloud_project_database_kafka_user_access.go create mode 100644 ovh/data_cloud_project_database_kafka_user_access_test.go create mode 100644 ovh/data_cloud_project_database_opensearch_pattern.go create mode 100644 ovh/data_cloud_project_database_opensearch_pattern_test.go create mode 100644 ovh/data_cloud_project_database_opensearch_patterns.go create mode 100644 ovh/data_cloud_project_database_opensearch_patterns_test.go create mode 100644 ovh/data_cloud_project_database_opensearch_user.go create mode 100644 ovh/data_cloud_project_database_opensearch_user_test.go create mode 100644 ovh/import_cloud_project_database_kafka_acl_test.go create mode 100644 ovh/import_cloud_project_database_kafka_topic_test.go create mode 100644 ovh/import_cloud_project_database_opensearch_pattern_test.go create mode 100644 ovh/import_cloud_project_database_opensearch_user_test.go create mode 100644 ovh/resource_cloud_project_database_kafka_acl.go create mode 100644 ovh/resource_cloud_project_database_kafka_acl_test.go create mode 100644 ovh/resource_cloud_project_database_kafka_topic.go create mode 100644 ovh/resource_cloud_project_database_kafka_topic_test.go create mode 100644 ovh/resource_cloud_project_database_opensearch_pattern.go create mode 100644 ovh/resource_cloud_project_database_opensearch_pattern_test.go create mode 100644 ovh/resource_cloud_project_database_opensearch_user.go create mode 100644 ovh/resource_cloud_project_database_opensearch_user_test.go create mode 100644 website/docs/d/cloud_project_database_kafka_acl.html.markdown create mode 100644 website/docs/d/cloud_project_database_kafka_acls.html.markdown create mode 100644 website/docs/d/cloud_project_database_kafka_certificates.html.markdown create mode 100644 website/docs/d/cloud_project_database_kafka_topic.html.markdown create mode 100644 website/docs/d/cloud_project_database_kafka_topics.html.markdown create mode 100644 website/docs/d/cloud_project_database_kafka_user_access.html.markdown create mode 100644 website/docs/d/cloud_project_database_opensearch_pattern.html.markdown create mode 100644 website/docs/d/cloud_project_database_opensearch_patterns.html.markdown create mode 100644 website/docs/d/cloud_project_database_opensearch_user.html.markdown create mode 100644 website/docs/r/cloud_project_database_kafka_acl.html.markdown create mode 100644 website/docs/r/cloud_project_database_kafka_topic.html.markdown create mode 100644 website/docs/r/cloud_project_database_opensearch_pattern.html.markdown create mode 100644 website/docs/r/cloud_project_database_opensearch_user.html.markdown diff --git a/ovh/data_cloud_project_database.go b/ovh/data_cloud_project_database.go index fe82ae792..a29239b2d 100644 --- a/ovh/data_cloud_project_database.go +++ b/ovh/data_cloud_project_database.go @@ -22,7 +22,7 @@ func dataSourceCloudProjectDatabase() *schema.Resource { Description: "Name of the engine of the service", Required: true, }, - "cluster_id": { + "id": { Type: schema.TypeString, Description: "Cluster ID", Required: true, @@ -155,7 +155,7 @@ func dataSourceCloudProjectDatabaseRead(d *schema.ResourceData, meta interface{} config := meta.(*Config) serviceName := d.Get("service_name").(string) engine := d.Get("engine").(string) - id := d.Get("cluster_id").(string) + id := d.Get("id").(string) serviceEndpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s", url.PathEscape(serviceName), diff --git a/ovh/data_cloud_project_database_ip_restrictions_test.go b/ovh/data_cloud_project_database_ip_restrictions_test.go index d495c070a..0577ddc98 100644 --- a/ovh/data_cloud_project_database_ip_restrictions_test.go +++ b/ovh/data_cloud_project_database_ip_restrictions_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "%s" version = "%s" plan = "essential" @@ -41,10 +43,12 @@ func TestAccCloudProjectDatabaseIpRestrictionsDataSource_basic(t *testing.T) { region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") ip := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_IP_RESTRICTION_IP_TEST") + description := acctest.RandomWithPrefix(test_prefix) config := fmt.Sprintf( testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic, serviceName, + description, engine, version, region, diff --git a/ovh/data_cloud_project_database_kafka_acl.go b/ovh/data_cloud_project_database_kafka_acl.go new file mode 100644 index 000000000..9816b9e18 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_acl.go @@ -0,0 +1,80 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func dataSourceCloudProjectDatabaseKafkaAcl() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaAclRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + "id": { + Type: schema.TypeString, + Description: "Acl ID", + Required: true, + }, + + // Computed + "permission": { + Type: schema.TypeString, + Description: "Permission to give to this username on this topic", + Computed: true, + }, + "topic": { + Type: schema.TypeString, + Description: "Topic affected by this acl", + Computed: true, + }, + "username": { + Type: schema.TypeString, + Description: "Username affected by this acl", + Computed: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaAclRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Get("id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/acl/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseKafkaAclResponse{} + + log.Printf("[DEBUG] Will read acl %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read acl %+v", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_acl_test.go b/ovh/data_cloud_project_database_kafka_acl_test.go new file mode 100644 index 000000000..fe611c5ce --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_acl_test.go @@ -0,0 +1,90 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaAclDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + permission = "%s" + topic = "%s" + username = "%s" +} + +data "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = ovh_cloud_project_database_kafka_acl.acl.service_name + cluster_id = ovh_cloud_project_database_kafka_acl.acl.cluster_id + id = ovh_cloud_project_database_kafka_acl.acl.id +} +` + +func TestAccCloudProjectDatabaseKafkaAclDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + permission := "read" + topic := "myTopic" + username := "johnDoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaAclDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + permission, + topic, + username, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_acl.acl", "permission", permission), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_acl.acl", "topic", topic), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_acl.acl", "username", username), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_kafka_acls.go b/ovh/data_cloud_project_database_kafka_acls.go new file mode 100644 index 000000000..e0457fcb6 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_acls.go @@ -0,0 +1,62 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" + "github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode" +) + +func dataSourceCloudProjectDatabaseKafkaAcls() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaAclsRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + + // Computed + "acl_ids": { + Type: schema.TypeList, + Description: "List of acl ids", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaAclsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/acl", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + res := make([]string, 0) + + log.Printf("[DEBUG] Will read acls from cluster %s from project %s", clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, &res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + // sort.Strings sorts in place, returns nothing + sort.Strings(res) + + d.SetId(hashcode.Strings(res)) + d.Set("acl_ids", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_acls_test.go b/ovh/data_cloud_project_database_kafka_acls_test.go new file mode 100644 index 000000000..502c89987 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_acls_test.go @@ -0,0 +1,87 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaAclsDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + permission = "%s" + topic = "%s" + username = "%s" +} + +data "ovh_cloud_project_database_kafka_acls" "acls" { + service_name = ovh_cloud_project_database_kafka_acl.acl.service_name + cluster_id = ovh_cloud_project_database_kafka_acl.acl.cluster_id +} +` + +func TestAccCloudProjectDatabaseKafkaAclsDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + permission := "read" + topic := "myTopic" + username := "johnDoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaAclsDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + permission, + topic, + username, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_kafka_acls.acls", + "acl_ids.#", + ), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_kafka_certificates.go b/ovh/data_cloud_project_database_kafka_certificates.go new file mode 100644 index 000000000..9d88fc94b --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_certificates.go @@ -0,0 +1,62 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" + "github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode" +) + +func dataSourceCloudProjectDatabaseKafkaCertificates() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaCertificatesRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + + // Computed + "ca": { + Type: schema.TypeString, + Description: "CA certificate used for the service", + Computed: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaCertificatesRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/certificates/", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + res := &CloudProjectDatabaseKafkaCertificatesResponse{} + + log.Printf("[DEBUG] Will read certificates from cluster %s from project %s", clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + d.SetId(strconv.Itoa(hashcode.String(res.Ca))) + for k, v := range res.ToMap() { + d.Set(k, v) + } + + log.Printf("[DEBUG] Read certificates %+v", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_certificates_test.go b/ovh/data_cloud_project_database_kafka_certificates_test.go new file mode 100644 index 000000000..be0cc7db0 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_certificates_test.go @@ -0,0 +1,71 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaCertificatesDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +data "ovh_cloud_project_database_kafka_certificates" "certificates" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id +} +` + +func TestAccCloudProjectDatabaseKafkaCertificatesDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaCertificatesDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_kafka_certificates.certificates", "ca"), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_kafka_topic.go b/ovh/data_cloud_project_database_kafka_topic.go new file mode 100644 index 000000000..787cddbb2 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_topic.go @@ -0,0 +1,95 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func dataSourceCloudProjectDatabaseKafkaTopic() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaTopicRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + "id": { + Type: schema.TypeString, + Description: "Topic ID", + Required: true, + }, + + // Computed + "min_insync_replicas": { + Type: schema.TypeInt, + Description: "Minimum insync replica accepted for this topic", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Name of the topic", + Computed: true, + }, + "partitions": { + Type: schema.TypeInt, + Description: "Number of partitions for this topic", + Computed: true, + }, + "replication": { + Type: schema.TypeInt, + Description: "Number of replication for this topic", + Computed: true, + }, + "retention_bytes": { + Type: schema.TypeInt, + Description: "Number of bytes for the retention of the data for this topic", + Computed: true, + }, + "retention_hours": { + Type: schema.TypeInt, + Description: "Number of hours for the retention of the data for this topic", + Computed: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaTopicRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Get("id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseKafkaTopicResponse{} + + log.Printf("[DEBUG] Will read topic %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read topic %+v", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_topic_test.go b/ovh/data_cloud_project_database_kafka_topic_test.go new file mode 100644 index 000000000..9f4411815 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_topic_test.go @@ -0,0 +1,91 @@ +package ovh + +import ( + "fmt" + "os" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaTopicDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_topic" "topic" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" +} + +data "ovh_cloud_project_database_kafka_topic" "topic" { + service_name = ovh_cloud_project_database_kafka_topic.topic.service_name + cluster_id = ovh_cloud_project_database_kafka_topic.topic.cluster_id + id = ovh_cloud_project_database_kafka_topic.topic.id +} +` + +func TestAccCloudProjectDatabaseKafkaTopicDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "myTopic" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaTopicDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "name", name), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "min_insync_replicas", strconv.Itoa(1)), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "partitions", strconv.Itoa(1)), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "replication", strconv.Itoa(2)), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "retention_bytes", strconv.Itoa(-1)), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_kafka_topic.topic", "retention_hours", strconv.Itoa(168)), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_kafka_topics.go b/ovh/data_cloud_project_database_kafka_topics.go new file mode 100644 index 000000000..307d1253b --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_topics.go @@ -0,0 +1,62 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" + "github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode" +) + +func dataSourceCloudProjectDatabaseKafkaTopics() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaTopicsRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + + // Computed + "topic_ids": { + Type: schema.TypeList, + Description: "List of topic ids", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaTopicsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + res := make([]string, 0) + + log.Printf("[DEBUG] Will read topics from cluster %s from project %s", clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, &res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + // sort.Strings sorts in place, returns nothing + sort.Strings(res) + + d.SetId(hashcode.Strings(res)) + d.Set("topic_ids", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_topics_test.go b/ovh/data_cloud_project_database_kafka_topics_test.go new file mode 100644 index 000000000..4e4c60ad6 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_topics_test.go @@ -0,0 +1,81 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaTopicsDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_topic" "topic" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" +} + +data "ovh_cloud_project_database_kafka_topics" "topics" { + service_name = ovh_cloud_project_database_kafka_topic.topic.service_name + cluster_id = ovh_cloud_project_database_kafka_topic.topic.cluster_id +} +` + +func TestAccCloudProjectDatabaseKafkaTopicsDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAKFA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "myTopic" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaTopicsDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_kafka_topics.topics", + "topic_ids.#", + ), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_kafka_user_access.go b/ovh/data_cloud_project_database_kafka_user_access.go new file mode 100644 index 000000000..716c04d46 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_user_access.go @@ -0,0 +1,75 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" + "github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode" +) + +func dataSourceCloudProjectDatabaseKafkaUserAccess() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseKafkaUserAccessRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + "user_id": { + Type: schema.TypeString, + Description: "Id of the user", + Required: true, + }, + + // Computed + "cert": { + Type: schema.TypeString, + Description: "User cert", + Computed: true, + }, + "key": { + Type: schema.TypeString, + Description: "User key for the cert", + Computed: true, + Sensitive: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseKafkaUserAccessRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + userId := d.Get("user_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/user/%s/access", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(userId), + ) + res := &CloudProjectDatabaseKafkaUserAccessResponse{} + + log.Printf("[DEBUG] Will read certificates of user %s from cluster %s from project %s", userId, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + d.SetId(strconv.Itoa(hashcode.String(res.Cert))) + for k, v := range res.ToMap() { + d.Set(k, v) + } + + log.Printf("[DEBUG] Read certificates %+v", res) + return nil +} diff --git a/ovh/data_cloud_project_database_kafka_user_access_test.go b/ovh/data_cloud_project_database_kafka_user_access_test.go new file mode 100644 index 000000000..8dbc16c50 --- /dev/null +++ b/ovh/data_cloud_project_database_kafka_user_access_test.go @@ -0,0 +1,83 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaUserAccessDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_user" "user" { + service_name = ovh_cloud_project_database.db.service_name + engine = ovh_cloud_project_database.db.engine + cluster_id = ovh_cloud_project_database.db.id + name = "%s" +} + +data "ovh_cloud_project_database_kafka_user_access" "access" { + service_name = ovh_cloud_project_database_user.user.service_name + cluster_id = ovh_cloud_project_database_user.user.cluster_id + user_id = ovh_cloud_project_database_user.user.id +} +` + +func TestAccCloudProjectDatabaseKafkaUserAccessDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "johndoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaUserAccessDatasourceConfig_Basic, + serviceName, + description, + version, + region, + region, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_kafka_user_access.access", "cert"), + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_kafka_user_access.access", "key"), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_mongodb_user_test.go b/ovh/data_cloud_project_database_mongodb_user_test.go index 6ba4762a6..8dff1aaca 100644 --- a/ovh/data_cloud_project_database_mongodb_user_test.go +++ b/ovh/data_cloud_project_database_mongodb_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseMongodbUserDatasourceConfig_Basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "mongodb" version = "%s" plan = "essential" @@ -42,6 +44,7 @@ func TestAccCloudProjectDatabaseMongodbUserDataSource_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" rolesBackup := "backup" rolesReadAnyDatabase := "readAnyDatabase" @@ -49,6 +52,7 @@ func TestAccCloudProjectDatabaseMongodbUserDataSource_basic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseMongodbUserDatasourceConfig_Basic, serviceName, + description, version, region, flavor, diff --git a/ovh/data_cloud_project_database_opensearch_pattern.go b/ovh/data_cloud_project_database_opensearch_pattern.go new file mode 100644 index 000000000..1ce942fbf --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_pattern.go @@ -0,0 +1,75 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func dataSourceCloudProjectDatabaseOpensearchPattern() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseOpensearchPatternRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + "id": { + Type: schema.TypeString, + Description: "Pattern ID", + Required: true, + }, + + // Computed + "max_index_count": { + Type: schema.TypeInt, + Description: "Maximum number of index for this pattern", + Computed: true, + }, + "pattern": { + Type: schema.TypeString, + Description: "Pattern format", + Computed: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseOpensearchPatternRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Get("id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseOpensearchPatternResponse{} + + log.Printf("[DEBUG] Will read pattern %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read pattern %+v", res) + return nil +} diff --git a/ovh/data_cloud_project_database_opensearch_pattern_test.go b/ovh/data_cloud_project_database_opensearch_pattern_test.go new file mode 100644 index 000000000..1f39d29ae --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_pattern_test.go @@ -0,0 +1,78 @@ +package ovh + +import ( + "fmt" + "os" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseOpensearchPatternDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "opensearch" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + max_index_count = %d + pattern = "%s" +} + +data "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = ovh_cloud_project_database_opensearch_pattern.pattern.service_name + cluster_id = ovh_cloud_project_database_opensearch_pattern.pattern.cluster_id + id = ovh_cloud_project_database_opensearch_pattern.pattern.id +} +` + +func TestAccCloudProjectDatabaseOpensearchPatternDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + maxIndexCount := 2 + pattern := "logs_*" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchPatternDatasourceConfig_Basic, + serviceName, + description, + version, + region, + flavor, + maxIndexCount, + pattern, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_opensearch_pattern.pattern", "max_index_count", strconv.Itoa(maxIndexCount)), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_opensearch_pattern.pattern", "pattern", pattern), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_opensearch_patterns.go b/ovh/data_cloud_project_database_opensearch_patterns.go new file mode 100644 index 000000000..3da987498 --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_patterns.go @@ -0,0 +1,62 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" + "github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode" +) + +func dataSourceCloudProjectDatabaseOpensearchPatterns() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseOpensearchPatternsRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + + // Computed + "pattern_ids": { + Type: schema.TypeList, + Description: "List of pattern ids", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseOpensearchPatternsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + res := make([]string, 0) + + log.Printf("[DEBUG] Will read patterns from cluster %s from project %s", clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, &res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + // sort.Strings sorts in place, returns nothing + sort.Strings(res) + + d.SetId(hashcode.Strings(res)) + d.Set("pattern_ids", res) + return nil +} diff --git a/ovh/data_cloud_project_database_opensearch_patterns_test.go b/ovh/data_cloud_project_database_opensearch_patterns_test.go new file mode 100644 index 000000000..d72b1d646 --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_patterns_test.go @@ -0,0 +1,76 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseOpensearchPatternsDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "opensearch" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + max_index_count = %d + pattern = "%s" +} + +data "ovh_cloud_project_database_opensearch_patterns" "patterns" { + service_name = ovh_cloud_project_database_opensearch_pattern.pattern.service_name + cluster_id = ovh_cloud_project_database_opensearch_pattern.pattern.cluster_id +} +` + +func TestAccCloudProjectDatabaseOpensearchPatternsDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + maxIndexCount := 2 + pattern := "logs_*" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchPatternsDatasourceConfig_Basic, + serviceName, + description, + version, + region, + flavor, + maxIndexCount, + pattern, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_opensearch_patterns.patterns", + "pattern_ids.#", + ), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_opensearch_user.go b/ovh/data_cloud_project_database_opensearch_user.go new file mode 100644 index 000000000..9af1d15a0 --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_user.go @@ -0,0 +1,110 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceCloudProjectDatabaseOpensearchUser() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCloudProjectDatabaseOpensearchUserRead, + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + Required: true, + }, + "name": { + Type: schema.TypeString, + Description: "Name of the user", + Required: true, + }, + + //Computed + "acls": { + Type: schema.TypeSet, + Description: "Acls of the user", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pattern": { + Type: schema.TypeString, + Description: "Pattern of the ACL", + Computed: true, + }, + "permission": { + Type: schema.TypeString, + Description: "Permission of the ACL", + Computed: true, + }, + }, + }, + }, + "created_at": { + Type: schema.TypeString, + Description: "Date of the creation of the user", + Computed: true, + }, + "status": { + Type: schema.TypeString, + Description: "Current status of the user", + Computed: true, + }, + }, + } +} + +func dataSourceCloudProjectDatabaseOpensearchUserRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + name := d.Get("name").(string) + + listEndpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + + listRes := make([]string, 0) + + log.Printf("[DEBUG] Will read users from cluster %s from project %s", clusterId, serviceName) + if err := config.OVHClient.Get(listEndpoint, &listRes); err != nil { + return fmt.Errorf("Error calling GET %s:\n\t %q", listEndpoint, err) + } + + for _, id := range listRes { + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseOpensearchUserResponse{} + + log.Printf("[DEBUG] Will read user %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return fmt.Errorf("Error calling GET %s:\n\t %q", endpoint, err) + } + + if res.Username == name { + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + log.Printf("[DEBUG] Read user %+v", res) + return nil + } + } + + return fmt.Errorf("User name %s not found for cluster %s from project %s", name, clusterId, serviceName) +} diff --git a/ovh/data_cloud_project_database_opensearch_user_test.go b/ovh/data_cloud_project_database_opensearch_user_test.go new file mode 100644 index 000000000..67b69e124 --- /dev/null +++ b/ovh/data_cloud_project_database_opensearch_user_test.go @@ -0,0 +1,87 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseOpensearchUserDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "opensearch" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_opensearch_user" "user" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" + acls { + pattern = "logs_*" + permission = "read" + } + acls { + pattern = "toto_*" + permission = "deny" + } +} + +data "ovh_cloud_project_database_opensearch_user" "user" { + service_name = ovh_cloud_project_database_opensearch_user.user.service_name + cluster_id = ovh_cloud_project_database_opensearch_user.user.cluster_id + name = ovh_cloud_project_database_opensearch_user.user.name +} +` + +func TestAccCloudProjectDatabaseOpensearchUserDataSource_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "johndoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchUserDatasourceConfig_Basic, + serviceName, + description, + version, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_opensearch_user.user", "created_at"), + resource.TestCheckResourceAttrSet( + "ovh_cloud_project_database_opensearch_user.user", "acls.#"), + resource.TestCheckResourceAttrSet( + "data.ovh_cloud_project_database_opensearch_user.user", "status"), + resource.TestCheckResourceAttr( + "data.ovh_cloud_project_database_opensearch_user.user", "name", name, + ), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_database_postgresql_user.go b/ovh/data_cloud_project_database_postgresql_user.go index e523b25b1..1de7a708d 100644 --- a/ovh/data_cloud_project_database_postgresql_user.go +++ b/ovh/data_cloud_project_database_postgresql_user.go @@ -35,7 +35,7 @@ func dataSourceCloudProjectDatabasePostgresqlUser() *schema.Resource { Computed: true, }, "roles": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Roles the user belongs to", Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, diff --git a/ovh/data_cloud_project_database_postgresql_user_test.go b/ovh/data_cloud_project_database_postgresql_user_test.go index 4394ac0ba..3996610d9 100644 --- a/ovh/data_cloud_project_database_postgresql_user_test.go +++ b/ovh/data_cloud_project_database_postgresql_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabasePostgresqlUserDatasourceConfig_Basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "postgresql" version = "%s" plan = "essential" @@ -42,12 +44,14 @@ func TestAccCloudProjectDatabasePostgresqlUserDataSource_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" replication := "replication" config := fmt.Sprintf( testAccCloudProjectDatabasePostgresqlUserDatasourceConfig_Basic, serviceName, + description, version, region, flavor, diff --git a/ovh/data_cloud_project_database_redis_user.go b/ovh/data_cloud_project_database_redis_user.go index a92ff7fdb..c2352df1a 100644 --- a/ovh/data_cloud_project_database_redis_user.go +++ b/ovh/data_cloud_project_database_redis_user.go @@ -30,19 +30,19 @@ func dataSourceCloudProjectDatabaseRedisUser() *schema.Resource { //Computed "categories": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Categories of the user", Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "channels": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Channels of the user", Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "commands": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Commands of the user", Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, @@ -53,7 +53,7 @@ func dataSourceCloudProjectDatabaseRedisUser() *schema.Resource { Computed: true, }, "keys": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Keys of the user", Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, diff --git a/ovh/data_cloud_project_database_redis_user_test.go b/ovh/data_cloud_project_database_redis_user_test.go index fc970f920..3e01ab84a 100644 --- a/ovh/data_cloud_project_database_redis_user_test.go +++ b/ovh/data_cloud_project_database_redis_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseRedisUserDatasourceConfig = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "redis" version = "%s" plan = "essential" @@ -45,6 +47,7 @@ func TestAccCloudProjectDatabaseRedisUserDataSource_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) categoriesSet := "+@set" categoriesSortedset := "+@sortedset" channels := "*" @@ -57,6 +60,7 @@ func TestAccCloudProjectDatabaseRedisUserDataSource_basic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseRedisUserDatasourceConfig, serviceName, + description, version, region, flavor, diff --git a/ovh/data_cloud_project_database_test.go b/ovh/data_cloud_project_database_test.go index 65250005d..f2c71240f 100644 --- a/ovh/data_cloud_project_database_test.go +++ b/ovh/data_cloud_project_database_test.go @@ -25,7 +25,7 @@ resource "ovh_cloud_project_database" "db" { data "ovh_cloud_project_database" "db" { service_name = ovh_cloud_project_database.db.service_name engine = ovh_cloud_project_database.db.engine - cluster_id = ovh_cloud_project_database.db.id + id = ovh_cloud_project_database.db.id } ` @@ -68,8 +68,6 @@ func TestAccCloudProjectDatabaseDataSource_basic(t *testing.T) { "data.ovh_cloud_project_database.db", "endpoints.0.domain"), resource.TestCheckResourceAttrSet( "data.ovh_cloud_project_database.db", "endpoints.0.ssl"), - resource.TestCheckResourceAttrSet( - "data.ovh_cloud_project_database.db", "endpoints.0.ssl_mode"), resource.TestCheckResourceAttr( "data.ovh_cloud_project_database.db", "engine", engine), resource.TestCheckResourceAttr( diff --git a/ovh/data_cloud_project_database_user_test.go b/ovh/data_cloud_project_database_user_test.go index 76036b761..f0b1904d6 100644 --- a/ovh/data_cloud_project_database_user_test.go +++ b/ovh/data_cloud_project_database_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseUserDatasourceConfig_Basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "%s" version = "%s" plan = "essential" @@ -41,11 +43,13 @@ func TestAccCloudProjectDatabaseUserDataSource_basic(t *testing.T) { version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" config := fmt.Sprintf( testAccCloudProjectDatabaseUserDatasourceConfig_Basic, serviceName, + description, engine, version, region, diff --git a/ovh/data_cloud_project_database_users_test.go b/ovh/data_cloud_project_database_users_test.go index 1ddbb3616..94dfdbb50 100644 --- a/ovh/data_cloud_project_database_users_test.go +++ b/ovh/data_cloud_project_database_users_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseUsersDatasourceConfig_Basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "%s" version = "%s" plan = "essential" @@ -40,10 +42,12 @@ func TestAccCloudProjectDatabaseUsersDataSource_basic(t *testing.T) { version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) config := fmt.Sprintf( testAccCloudProjectDatabaseUsersDatasourceConfig_Basic, serviceName, + description, engine, version, region, diff --git a/ovh/data_cloud_project_databases_test.go b/ovh/data_cloud_project_databases_test.go index 0e9b2d747..3a1a92865 100644 --- a/ovh/data_cloud_project_databases_test.go +++ b/ovh/data_cloud_project_databases_test.go @@ -5,23 +5,45 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabasesDatasourceConfig_Basic = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "%s" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + data "ovh_cloud_project_databases" "dbs" { - service_name = "%s" - engine = "%s" + service_name = ovh_cloud_project_database.db.service_name + engine = ovh_cloud_project_database.db.engine } ` func TestAccCloudProjectDatabasesDataSource_basic(t *testing.T) { serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") engine := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_ENGINE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + config := fmt.Sprintf( testAccCloudProjectDatabasesDatasourceConfig_Basic, serviceName, + description, engine, + version, + region, + flavor, ) resource.Test(t, resource.TestCase{ diff --git a/ovh/import_cloud_project_database_ip_restriction_test.go b/ovh/import_cloud_project_database_ip_restriction_test.go index 80706b83b..ddd2a550e 100644 --- a/ovh/import_cloud_project_database_ip_restriction_test.go +++ b/ovh/import_cloud_project_database_ip_restriction_test.go @@ -22,6 +22,7 @@ func TestAccCloudProjectDatabaseIpRestriction_importBasic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseIpRestrictionConfig, serviceName, + description, engine, version, region, diff --git a/ovh/import_cloud_project_database_kafka_acl_test.go b/ovh/import_cloud_project_database_kafka_acl_test.go new file mode 100644 index 000000000..d881eefde --- /dev/null +++ b/ovh/import_cloud_project_database_kafka_acl_test.go @@ -0,0 +1,70 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "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 TestAccCloudProjectDatabaseKafkaAcl_importBasic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + permission := "read" + topic := "myTopic" + username := "johnDoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaAclConfig, + serviceName, + description, + version, + region, + region, + region, + flavor, + permission, + topic, + username, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "ovh_cloud_project_database_kafka_acl.acl", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccCloudProjectDatabaseKafkaAclImportId("ovh_cloud_project_database_kafka_acl.acl"), + }, + }, + }) +} + +func testAccCloudProjectDatabaseKafkaAclImportId(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + testKafkaAcl, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("ovh_cloud_project_database_kafka_acl not found: %s", resourceName) + } + return fmt.Sprintf( + "%s/%s/%s", + testKafkaAcl.Primary.Attributes["service_name"], + testKafkaAcl.Primary.Attributes["cluster_id"], + testKafkaAcl.Primary.Attributes["id"], + ), nil + } +} diff --git a/ovh/import_cloud_project_database_kafka_topic_test.go b/ovh/import_cloud_project_database_kafka_topic_test.go new file mode 100644 index 000000000..8d765a241 --- /dev/null +++ b/ovh/import_cloud_project_database_kafka_topic_test.go @@ -0,0 +1,68 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "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 TestAccCloudProjectDatabaseKafkaTopic_importBasic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name1 := "myTopic1" + name2 := "myTopic2" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaTopicConfig, + serviceName, + description, + version, + region, + region, + region, + flavor, + name1, + name2, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "ovh_cloud_project_database_kafka_topic.topic1", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccCloudProjectDatabaseKafkaTopicImportId("ovh_cloud_project_database_kafka_topic.topic1"), + }, + }, + }) +} + +func testAccCloudProjectDatabaseKafkaTopicImportId(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + testKafkaTopic, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("ovh_cloud_project_database_kafka_topic not found: %s", resourceName) + } + return fmt.Sprintf( + "%s/%s/%s", + testKafkaTopic.Primary.Attributes["service_name"], + testKafkaTopic.Primary.Attributes["cluster_id"], + testKafkaTopic.Primary.Attributes["id"], + ), nil + } +} diff --git a/ovh/import_cloud_project_database_mongodb_user_test.go b/ovh/import_cloud_project_database_mongodb_user_test.go index 11fea8c6a..67efc88f8 100644 --- a/ovh/import_cloud_project_database_mongodb_user_test.go +++ b/ovh/import_cloud_project_database_mongodb_user_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "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" ) @@ -17,6 +18,7 @@ func TestAccCloudProjectDatabaseMongodbUser_importBasic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" rolesBackup := "backup" rolesReadAnyDatabase := "readAnyDatabase" @@ -24,6 +26,7 @@ func TestAccCloudProjectDatabaseMongodbUser_importBasic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseMongodbUserConfig_basic, serviceName, + description, version, region, flavor, diff --git a/ovh/import_cloud_project_database_opensearch_pattern_test.go b/ovh/import_cloud_project_database_opensearch_pattern_test.go new file mode 100644 index 000000000..93608bcb0 --- /dev/null +++ b/ovh/import_cloud_project_database_opensearch_pattern_test.go @@ -0,0 +1,66 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "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 TestAccCloudProjectDatabaseOpensearchPattern_importBasic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + maxIndexCount := 2 + pattern := "logs_*" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchPatternConfig, + serviceName, + description, + version, + region, + flavor, + maxIndexCount, + pattern, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "ovh_cloud_project_database_opensearch_pattern.pattern", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccCloudProjectDatabaseOpensearchPatternImportId("ovh_cloud_project_database_opensearch_pattern.pattern"), + }, + }, + }) +} + +func testAccCloudProjectDatabaseOpensearchPatternImportId(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + testOpensearchPattern, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("ovh_cloud_project_database_opensearch_pattern not found: %s", resourceName) + } + return fmt.Sprintf( + "%s/%s/%s", + testOpensearchPattern.Primary.Attributes["service_name"], + testOpensearchPattern.Primary.Attributes["cluster_id"], + testOpensearchPattern.Primary.Attributes["id"], + ), nil + } +} diff --git a/ovh/import_cloud_project_database_opensearch_user_test.go b/ovh/import_cloud_project_database_opensearch_user_test.go new file mode 100644 index 000000000..d0f77525a --- /dev/null +++ b/ovh/import_cloud_project_database_opensearch_user_test.go @@ -0,0 +1,65 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "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 TestAccCloudProjectDatabaseOpensearchUser_importBasic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "johndoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchUserConfig, + serviceName, + description, + version, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "ovh_cloud_project_database_opensearch_user.user", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccCloudProjectDatabaseOpensearchUserImportId("ovh_cloud_project_database_opensearch_user.user"), + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func testAccCloudProjectDatabaseOpensearchUserImportId(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + testOpensearchUser, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("ovh_cloud_project_database_opensearch_user not found: %s", resourceName) + } + return fmt.Sprintf( + "%s/%s/%s", + testOpensearchUser.Primary.Attributes["service_name"], + testOpensearchUser.Primary.Attributes["cluster_id"], + testOpensearchUser.Primary.Attributes["id"], + ), nil + } +} diff --git a/ovh/import_cloud_project_database_postgresql_user_test.go b/ovh/import_cloud_project_database_postgresql_user_test.go index b9818b563..4ac27f373 100644 --- a/ovh/import_cloud_project_database_postgresql_user_test.go +++ b/ovh/import_cloud_project_database_postgresql_user_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "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" ) @@ -17,12 +18,14 @@ func TestAccCloudProjectDatabasePostgresqlUser_importBasic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" replication := "replication" config := fmt.Sprintf( testAccCloudProjectDatabasePostgresqlUserConfig, serviceName, + description, version, region, flavor, diff --git a/ovh/import_cloud_project_database_redis_user_test.go b/ovh/import_cloud_project_database_redis_user_test.go index b4849f342..884c8e5bd 100644 --- a/ovh/import_cloud_project_database_redis_user_test.go +++ b/ovh/import_cloud_project_database_redis_user_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "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" ) @@ -17,6 +18,7 @@ func TestAccCloudProjectDatabaseRedisUser_importBasic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) categoriesSet := "+@set" categoriesSortedset := "+@sortedset" channels := "*" @@ -29,6 +31,7 @@ func TestAccCloudProjectDatabaseRedisUser_importBasic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseRedisUserConfig, serviceName, + description, version, region, flavor, diff --git a/ovh/import_cloud_project_database_test.go b/ovh/import_cloud_project_database_test.go index 34f21c8a5..43196a49d 100644 --- a/ovh/import_cloud_project_database_test.go +++ b/ovh/import_cloud_project_database_test.go @@ -11,11 +11,11 @@ import ( ) func TestAccCloudProjectDatabase_importBasic(t *testing.T) { - description := acctest.RandomWithPrefix(test_prefix) engine := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_ENGINE_TEST") version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) config := fmt.Sprintf( testAccCloudProjectDatabaseConfig, diff --git a/ovh/import_cloud_project_database_user_test.go b/ovh/import_cloud_project_database_user_test.go index 940577b5b..f92dcdf37 100644 --- a/ovh/import_cloud_project_database_user_test.go +++ b/ovh/import_cloud_project_database_user_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "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" ) @@ -15,11 +16,13 @@ func TestAccCloudProjectDatabaseUser_importBasic(t *testing.T) { version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" config := fmt.Sprintf( testAccCloudProjectDatabaseUserConfig, serviceName, + description, engine, version, region, diff --git a/ovh/provider.go b/ovh/provider.go index 73fca3f84..26b1cf91f 100644 --- a/ovh/provider.go +++ b/ovh/provider.go @@ -49,10 +49,19 @@ func Provider() *schema.Provider { "ovh_cloud_project_database": dataSourceCloudProjectDatabase(), "ovh_cloud_project_databases": dataSourceCloudProjectDatabases(), "ovh_cloud_project_database_ip_restrictions": dataSourceCloudProjectDatabaseIpRestrictions(), - "ovh_cloud_project_database_user": dataSourceCloudProjectDatabaseUser(), + "ovh_cloud_project_database_kafka_acl": dataSourceCloudProjectDatabaseKafkaAcl(), + "ovh_cloud_project_database_kafka_acls": dataSourceCloudProjectDatabaseKafkaAcls(), + "ovh_cloud_project_database_kafka_certificates": dataSourceCloudProjectDatabaseKafkaCertificates(), + "ovh_cloud_project_database_kafka_topic": dataSourceCloudProjectDatabaseKafkaTopic(), + "ovh_cloud_project_database_kafka_topics": dataSourceCloudProjectDatabaseKafkaTopics(), + "ovh_cloud_project_database_kafka_user_access": dataSourceCloudProjectDatabaseKafkaUserAccess(), "ovh_cloud_project_database_mongodb_user": dataSourceCloudProjectDatabaseMongodbUser(), + "ovh_cloud_project_database_opensearch_pattern": dataSourceCloudProjectDatabaseOpensearchPattern(), + "ovh_cloud_project_database_opensearch_patterns": dataSourceCloudProjectDatabaseOpensearchPatterns(), + "ovh_cloud_project_database_opensearch_user": dataSourceCloudProjectDatabaseOpensearchUser(), "ovh_cloud_project_database_postgresql_user": dataSourceCloudProjectDatabasePostgresqlUser(), "ovh_cloud_project_database_redis_user": dataSourceCloudProjectDatabaseRedisUser(), + "ovh_cloud_project_database_user": dataSourceCloudProjectDatabaseUser(), "ovh_cloud_project_database_users": dataSourceCloudProjectDatabaseUsers(), "ovh_cloud_project_failover_ip_attach": dataSourceCloudProjectFailoverIpAttach(), "ovh_cloud_project_kube": dataSourceCloudProjectKube(), @@ -100,10 +109,14 @@ func Provider() *schema.Provider { "ovh_cloud_project_containerregistry_user": resourceCloudProjectContainerRegistryUser(), "ovh_cloud_project_database": resourceCloudProjectDatabase(), "ovh_cloud_project_database_ip_restriction": resourceCloudProjectDatabaseIpRestriction(), + "ovh_cloud_project_database_kafka_acl": resourceCloudProjectDatabaseKafkaAcl(), + "ovh_cloud_project_database_kafka_topic": resourceCloudProjectDatabaseKafkaTopic(), + "ovh_cloud_project_database_mongodb_user": resourceCloudProjectDatabaseMongodbUser(), + "ovh_cloud_project_database_opensearch_pattern": resourceCloudProjectDatabaseOpensearchPattern(), + "ovh_cloud_project_database_opensearch_user": resourceCloudProjectDatabaseOpensearchUser(), + "ovh_cloud_project_database_postgresql_user": resourceCloudProjectDatabasePostgresqlUser(), + "ovh_cloud_project_database_redis_user": resourceCloudProjectDatabaseRedisUser(), "ovh_cloud_project_database_user": resourceCloudProjectDatabaseUser(), - "ovh_cloud_project_database_mongodb_user": resourceCloudProjectDatabasepMongodbUser(), - "ovh_cloud_project_database_postgresql_user": resourceCloudProjectDatabasepPostgresqlUser(), - "ovh_cloud_project_database_redis_user": resourceCloudProjectDatabasepRedisUser(), "ovh_cloud_project_failover_ip_attach": resourceCloudProjectFailoverIpAttach(), "ovh_cloud_project_kube": resourceCloudProjectKube(), "ovh_cloud_project_kube_nodepool": resourceCloudProjectKubeNodePool(), diff --git a/ovh/resource_cloud_project_database_ip_restriction.go b/ovh/resource_cloud_project_database_ip_restriction.go index 2277ecd5d..bd1b3e889 100644 --- a/ovh/resource_cloud_project_database_ip_restriction.go +++ b/ovh/resource_cloud_project_database_ip_restriction.go @@ -213,7 +213,7 @@ func resourceCloudProjectDatabaseIpRestrictionDelete(d *schema.ResourceData, met } err = helpers.CheckDeleted(d, err, endpoint) if err != nil { - resource.NonRetryableError(err) + return resource.NonRetryableError(err) } return nil } diff --git a/ovh/resource_cloud_project_database_ip_restriction_test.go b/ovh/resource_cloud_project_database_ip_restriction_test.go index 1d326e541..94b35e7f4 100644 --- a/ovh/resource_cloud_project_database_ip_restriction_test.go +++ b/ovh/resource_cloud_project_database_ip_restriction_test.go @@ -12,6 +12,7 @@ import ( const testAccCloudProjectDatabaseIpRestrictionConfig = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "%s" version = "%s" plan = "essential" @@ -42,6 +43,7 @@ func TestAccCloudProjectDatabaseIpRestriction_basic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseIpRestrictionConfig, serviceName, + description, engine, version, region, diff --git a/ovh/resource_cloud_project_database_kafka_acl.go b/ovh/resource_cloud_project_database_kafka_acl.go new file mode 100644 index 000000000..f31b3c7f8 --- /dev/null +++ b/ovh/resource_cloud_project_database_kafka_acl.go @@ -0,0 +1,151 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func resourceCloudProjectDatabaseKafkaAcl() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudProjectDatabaseKafkaAclCreate, + Read: resourceCloudProjectDatabaseKafkaAclRead, + Delete: resourceCloudProjectDatabaseKafkaAclDelete, + + Importer: &schema.ResourceImporter{ + State: resourceCloudProjectDatabaseKafkaAclImportState, + }, + + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + ForceNew: true, + Required: true, + }, + "permission": { + Type: schema.TypeString, + Description: "Permission to give to this username on this topic", + ForceNew: true, + Required: true, + }, + "topic": { + Type: schema.TypeString, + Description: "Topic affected by this acl", + ForceNew: true, + Required: true, + }, + "username": { + Type: schema.TypeString, + Description: "Username affected by this acl", + ForceNew: true, + Required: true, + }, + }, + } +} + +func resourceCloudProjectDatabaseKafkaAclImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + givenId := d.Id() + n := 3 + splitId := strings.SplitN(givenId, "/", n) + if len(splitId) != n { + return nil, fmt.Errorf("Import Id is not service_name/cluster_id/id formatted") + } + serviceName := splitId[0] + clusterId := splitId[1] + id := splitId[2] + d.SetId(id) + d.Set("cluster_id", clusterId) + d.Set("service_name", serviceName) + + results := make([]*schema.ResourceData, 1) + results[0] = d + return results, nil +} + +func resourceCloudProjectDatabaseKafkaAclCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/acl", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + params := (&CloudProjectDatabaseKafkaAclCreateOpts{}).FromResource(d) + res := &CloudProjectDatabaseKafkaAclResponse{} + + log.Printf("[DEBUG] Will create acl: %+v for cluster %s from project %s", params, clusterId, serviceName) + err := config.OVHClient.Post(endpoint, params, res) + if err != nil { + return fmt.Errorf("calling Post %s with params %+v:\n\t %q", endpoint, params, err) + } + + d.SetId(res.Id) + + return resourceCloudProjectDatabaseKafkaAclRead(d, meta) +} + +func resourceCloudProjectDatabaseKafkaAclRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/acl/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseKafkaAclResponse{} + + log.Printf("[DEBUG] Will read acl %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read acl %+v", res) + return nil +} + +func resourceCloudProjectDatabaseKafkaAclDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/acl/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + + log.Printf("[DEBUG] Will delete acl %s from cluster %s from project %s", id, clusterId, serviceName) + err := config.OVHClient.Delete(endpoint, nil) + if err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + d.SetId("") + + return nil +} diff --git a/ovh/resource_cloud_project_database_kafka_acl_test.go b/ovh/resource_cloud_project_database_kafka_acl_test.go new file mode 100644 index 000000000..86869e349 --- /dev/null +++ b/ovh/resource_cloud_project_database_kafka_acl_test.go @@ -0,0 +1,84 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaAclConfig = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + permission = "%s" + topic = "%s" + username = "%s" +} +` + +func TestAccCloudProjectDatabaseKafkaAcl_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + permission := "read" + topic := "myTopic" + username := "johnDoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaAclConfig, + serviceName, + description, + version, + region, + region, + region, + flavor, + permission, + topic, + username, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_acl.acl", "permission", permission), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_acl.acl", "topic", topic), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_acl.acl", "username", username), + ), + }, + }, + }) +} diff --git a/ovh/resource_cloud_project_database_kafka_topic.go b/ovh/resource_cloud_project_database_kafka_topic.go new file mode 100644 index 000000000..adb042e92 --- /dev/null +++ b/ovh/resource_cloud_project_database_kafka_topic.go @@ -0,0 +1,202 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func resourceCloudProjectDatabaseKafkaTopic() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudProjectDatabaseKafkaTopicCreate, + Read: resourceCloudProjectDatabaseKafkaTopicRead, + Delete: resourceCloudProjectDatabaseKafkaTopicDelete, + + Importer: &schema.ResourceImporter{ + State: resourceCloudProjectDatabaseKafkaTopicImportState, + }, + + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + ForceNew: true, + Required: true, + }, + "name": { + Type: schema.TypeString, + Description: "Name of the topic", + ForceNew: true, + Required: true, + }, + + //Optional/Computed + "min_insync_replicas": { + Type: schema.TypeInt, + Description: "Minimum insync replica accepted for this topic", + ForceNew: true, + Optional: true, + Computed: true, + ValidateFunc: validateCloudProjectDatabaseKafkaTopicMinInsyncReplicasFunc, + }, + "partitions": { + Type: schema.TypeInt, + Description: "Number of partitions for this topic", + ForceNew: true, + Optional: true, + Computed: true, + ValidateFunc: validateCloudProjectDatabaseKafkaTopicPartitionsFunc, + }, + "replication": { + Type: schema.TypeInt, + Description: "Number of replication for this topic", + ForceNew: true, + Optional: true, + Computed: true, + ValidateFunc: validateCloudProjectDatabaseKafkaTopicReplicationFunc, + }, + "retention_bytes": { + Type: schema.TypeInt, + Description: "Number of bytes for the retention of the data for this topic", + ForceNew: true, + Optional: true, + Computed: true, + }, + "retention_hours": { + Type: schema.TypeInt, + Description: "Number of hours for the retention of the data for this topic", + ForceNew: true, + Optional: true, + Computed: true, + ValidateFunc: validateCloudProjectDatabaseKafkaTopicRetentionHoursFunc, + }, + }, + } +} + +func resourceCloudProjectDatabaseKafkaTopicImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + givenId := d.Id() + n := 3 + splitId := strings.SplitN(givenId, "/", n) + if len(splitId) != n { + return nil, fmt.Errorf("Import Id is not service_name/cluster_id/id formatted") + } + serviceName := splitId[0] + clusterId := splitId[1] + id := splitId[2] + d.SetId(id) + d.Set("cluster_id", clusterId) + d.Set("service_name", serviceName) + + results := make([]*schema.ResourceData, 1) + results[0] = d + return results, nil +} + +func resourceCloudProjectDatabaseKafkaTopicCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + params := (&CloudProjectDatabaseKafkaTopicCreateOpts{}).FromResource(d) + res := &CloudProjectDatabaseKafkaTopicResponse{} + + log.Printf("[DEBUG] Will create topic: %+v for cluster %s from project %s", params, clusterId, serviceName) + err := config.OVHClient.Post(endpoint, params, res) + if err != nil { + return err + } + + log.Printf("[DEBUG] Waiting for topic %s to be READY", res.Id) + err = waitForCloudProjectDatabaseKafkaTopicReady(config.OVHClient, serviceName, clusterId, res.Id, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("timeout while waiting topic %s to be READY: %w", res.Id, err) + } + log.Printf("[DEBUG] topic %s is READY", res.Id) + + d.SetId(res.Id) + + err = resourceCloudProjectDatabaseKafkaTopicRead(d, meta) + if err != nil { + return err + } + return nil +} + +func resourceCloudProjectDatabaseKafkaTopicRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseKafkaTopicResponse{} + + log.Printf("[DEBUG] Will read topic %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read topic %+v", res) + return nil +} + +func resourceCloudProjectDatabaseKafkaTopicDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + + log.Printf("[DEBUG] Will delete topic %s from cluster %s from project %s", id, clusterId, serviceName) + err := config.OVHClient.Delete(endpoint, nil) + if err != nil { + err = helpers.CheckDeleted(d, err, endpoint) + if err != nil { + return err + } + return nil + } + + log.Printf("[DEBUG] Waiting for topic %s to be DELETED", id) + err = waitForCloudProjectDatabaseKafkaTopicDeleted(config.OVHClient, serviceName, clusterId, id, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return fmt.Errorf("timeout while waiting topic %s to be DELETED: %w", id, err) + } + log.Printf("[DEBUG] topic %s is DELETED", id) + + d.SetId("") + + return nil +} diff --git a/ovh/resource_cloud_project_database_kafka_topic_test.go b/ovh/resource_cloud_project_database_kafka_topic_test.go new file mode 100644 index 000000000..baa5a185a --- /dev/null +++ b/ovh/resource_cloud_project_database_kafka_topic_test.go @@ -0,0 +1,110 @@ +package ovh + +import ( + "fmt" + "os" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseKafkaTopicConfig = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "kafka" + version = "%s" + plan = "business" + nodes { + region = "%s" + } + nodes { + region = "%s" + } + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_kafka_topic" "topic1" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" +} + +resource "ovh_cloud_project_database_kafka_topic" "topic2" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" + min_insync_replicas = 1 + partitions = 3 + replication = 2 + retention_bytes = 4 + retention_hours = 5 +} +` + +func TestAccCloudProjectDatabaseKafkaTopic_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name1 := "myTopic1" + name2 := "myTopic2" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseKafkaTopicConfig, + serviceName, + description, + version, + region, + region, + region, + flavor, + name1, + name2, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "name", name1), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "min_insync_replicas", strconv.Itoa(1)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "partitions", strconv.Itoa(1)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "replication", strconv.Itoa(2)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "retention_bytes", strconv.Itoa(-1)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic1", "retention_hours", strconv.Itoa(168)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "name", name2), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "min_insync_replicas", strconv.Itoa(1)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "partitions", strconv.Itoa(3)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "replication", strconv.Itoa(2)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "retention_bytes", strconv.Itoa(4)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_kafka_topic.topic2", "retention_hours", strconv.Itoa(5)), + ), + }, + }, + }) +} diff --git a/ovh/resource_cloud_project_database_mongodb_user.go b/ovh/resource_cloud_project_database_mongodb_user.go index c1a26107c..2a4767beb 100644 --- a/ovh/resource_cloud_project_database_mongodb_user.go +++ b/ovh/resource_cloud_project_database_mongodb_user.go @@ -12,7 +12,7 @@ import ( "github.com/ovh/terraform-provider-ovh/ovh/helpers" ) -func resourceCloudProjectDatabasepMongodbUser() *schema.Resource { +func resourceCloudProjectDatabaseMongodbUser() *schema.Resource { return &schema.Resource{ Create: resourceCloudProjectDatabaseMongodbUserCreate, Read: resourceCloudProjectDatabaseMongodbUserRead, @@ -223,7 +223,7 @@ func resourceCloudProjectDatabaseMongodbUserDelete(d *schema.ResourceData, meta } err = helpers.CheckDeleted(d, err, endpoint) if err != nil { - resource.NonRetryableError(err) + return resource.NonRetryableError(err) } return nil } diff --git a/ovh/resource_cloud_project_database_mongodb_user_test.go b/ovh/resource_cloud_project_database_mongodb_user_test.go index abcf8e618..cbaee212b 100644 --- a/ovh/resource_cloud_project_database_mongodb_user_test.go +++ b/ovh/resource_cloud_project_database_mongodb_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseMongodbUserConfig_basic = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "mongodb" version = "%s" plan = "essential" @@ -36,6 +38,7 @@ func TestAccCloudProjectDatabaseMongodbUser_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" rolesBackup := "backup" rolesReadAnyDatabase := "readAnyDatabase" @@ -43,6 +46,7 @@ func TestAccCloudProjectDatabaseMongodbUser_basic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseMongodbUserConfig_basic, serviceName, + description, version, region, flavor, diff --git a/ovh/resource_cloud_project_database_opensearch_pattern.go b/ovh/resource_cloud_project_database_opensearch_pattern.go new file mode 100644 index 000000000..723f22758 --- /dev/null +++ b/ovh/resource_cloud_project_database_opensearch_pattern.go @@ -0,0 +1,159 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func resourceCloudProjectDatabaseOpensearchPattern() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudProjectDatabaseOpensearchPatternCreate, + Read: resourceCloudProjectDatabaseOpensearchPatternRead, + Delete: resourceCloudProjectDatabaseOpensearchPatternDelete, + + Importer: &schema.ResourceImporter{ + State: resourceCloudProjectDatabaseOpensearchPatternImportState, + }, + + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + ForceNew: true, + Required: true, + }, + "max_index_count": { + Type: schema.TypeInt, + Description: "Maximum number of index for this pattern", + ForceNew: true, + Optional: true, + }, + "pattern": { + Type: schema.TypeString, + Description: "Pattern format", + ForceNew: true, + Required: true, + }, + }, + } +} + +func resourceCloudProjectDatabaseOpensearchPatternImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + givenId := d.Id() + n := 3 + splitId := strings.SplitN(givenId, "/", n) + if len(splitId) != n { + return nil, fmt.Errorf("Import Id is not service_name/cluster_id/id formatted") + } + serviceName := splitId[0] + clusterId := splitId[1] + id := splitId[2] + d.SetId(id) + d.Set("cluster_id", clusterId) + d.Set("service_name", serviceName) + + results := make([]*schema.ResourceData, 1) + results[0] = d + return results, nil +} + +func resourceCloudProjectDatabaseOpensearchPatternCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + params := (&CloudProjectDatabaseOpensearchPatternCreateOpts{}).FromResource(d) + res := &CloudProjectDatabaseOpensearchPatternResponse{} + + log.Printf("[DEBUG] Will create pattern: %+v for cluster %s from project %s", params, clusterId, serviceName) + err := config.OVHClient.Post(endpoint, params, res) + if err != nil { + return fmt.Errorf("calling Post %s with params %+v:\n\t %q", endpoint, params, err) + } + + log.Printf("[DEBUG] Waiting for topic %s to be READY", res.Id) + err = waitForCloudProjectDatabaseOpensearchPatternReady(config.OVHClient, serviceName, clusterId, res.Id, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("timeout while waiting topic %s to be READY: %w", res.Id, err) + } + log.Printf("[DEBUG] topic %s is READY", res.Id) + + d.SetId(res.Id) + + return resourceCloudProjectDatabaseOpensearchPatternRead(d, meta) +} + +func resourceCloudProjectDatabaseOpensearchPatternRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseOpensearchPatternResponse{} + + log.Printf("[DEBUG] Will read pattern %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read pattern %+v", res) + return nil +} + +func resourceCloudProjectDatabaseOpensearchPatternDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + + log.Printf("[DEBUG] Will delete pattern %s from cluster %s from project %s", id, clusterId, serviceName) + err := config.OVHClient.Delete(endpoint, nil) + if err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + log.Printf("[DEBUG] Waiting for pattern %s to be DELETED", id) + err = waitForCloudProjectDatabaseOpensearchPatternDeleted(config.OVHClient, serviceName, clusterId, id, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return fmt.Errorf("timeout while waiting pattern %s to be DELETED: %w", id, err) + } + log.Printf("[DEBUG] pattern %s is DELETED", id) + + d.SetId("") + + return nil +} diff --git a/ovh/resource_cloud_project_database_opensearch_pattern_test.go b/ovh/resource_cloud_project_database_opensearch_pattern_test.go new file mode 100644 index 000000000..fc28b1703 --- /dev/null +++ b/ovh/resource_cloud_project_database_opensearch_pattern_test.go @@ -0,0 +1,72 @@ +package ovh + +import ( + "fmt" + "os" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseOpensearchPatternConfig = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "opensearch" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + max_index_count = %d + pattern = "%s" +} +` + +func TestAccCloudProjectDatabaseOpensearchPattern_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + maxIndexCount := 2 + pattern := "logs_*" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchPatternConfig, + serviceName, + description, + version, + region, + flavor, + maxIndexCount, + pattern, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_opensearch_pattern.pattern", "max_index_count", strconv.Itoa(maxIndexCount)), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_opensearch_pattern.pattern", "pattern", pattern), + ), + }, + }, + }) +} diff --git a/ovh/resource_cloud_project_database_opensearch_user.go b/ovh/resource_cloud_project_database_opensearch_user.go new file mode 100644 index 000000000..0a1e38512 --- /dev/null +++ b/ovh/resource_cloud_project_database_opensearch_user.go @@ -0,0 +1,221 @@ +package ovh + +import ( + "fmt" + "log" + "net/url" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/ovh/terraform-provider-ovh/ovh/helpers" +) + +func resourceCloudProjectDatabaseOpensearchUser() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudProjectDatabaseOpensearchUserCreate, + Read: resourceCloudProjectDatabaseOpensearchUserRead, + Delete: resourceCloudProjectDatabaseOpensearchUserDelete, + Update: resourceCloudProjectDatabaseOpensearchUserUpdate, + + Importer: &schema.ResourceImporter{ + State: resourceCloudProjectDatabaseOpensearchUserImportState, + }, + + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil), + }, + "cluster_id": { + Type: schema.TypeString, + Description: "Id of the database cluster", + ForceNew: true, + Required: true, + }, + "acls": { + Type: schema.TypeSet, + Description: "Acls of the user", + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pattern": { + Type: schema.TypeString, + Description: "Pattern of the ACL", + Required: true, + }, + "permission": { + Type: schema.TypeString, + Description: "Permission of the ACL", + Required: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Description: "Name of the user", + ForceNew: true, + Required: true, + }, + + //Computed + "created_at": { + Type: schema.TypeString, + Description: "Date of the creation of the user", + Computed: true, + }, + "password": { + Type: schema.TypeString, + Description: "Password of the user", + Sensitive: true, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Description: "Current status of the user", + Computed: true, + }, + }, + } +} + +func resourceCloudProjectDatabaseOpensearchUserImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + givenId := d.Id() + n := 3 + splitId := strings.SplitN(givenId, "/", n) + if len(splitId) != n { + return nil, fmt.Errorf("Import Id is not service_name/cluster_id/id formatted") + } + serviceName := splitId[0] + clusterId := splitId[1] + id := splitId[2] + d.SetId(id) + d.Set("cluster_id", clusterId) + d.Set("service_name", serviceName) + + results := make([]*schema.ResourceData, 1) + results[0] = d + return results, nil +} + +func resourceCloudProjectDatabaseOpensearchUserCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + ) + params := (&CloudProjectDatabaseOpensearchUserCreateOpts{}).FromResource(d) + res := &CloudProjectDatabaseOpensearchUserResponse{} + + log.Printf("[DEBUG] Will create user: %+v for cluster %s from project %s", params, clusterId, serviceName) + err := config.OVHClient.Post(endpoint, params, res) + if err != nil { + return fmt.Errorf("calling Post %s with params %+v:\n\t %q", endpoint, params, err) + } + + log.Printf("[DEBUG] Waiting for user %s to be READY", res.Id) + err = waitForCloudProjectDatabaseUserReady(config.OVHClient, serviceName, "opensearch", clusterId, res.Id, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("timeout while waiting user %s to be READY: %w", res.Id, err) + } + log.Printf("[DEBUG] user %s is READY", res.Id) + + d.SetId(res.Id) + d.Set("password", res.Password) + + return resourceCloudProjectDatabaseOpensearchUserRead(d, meta) +} + +func resourceCloudProjectDatabaseOpensearchUserRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + res := &CloudProjectDatabaseOpensearchUserResponse{} + + log.Printf("[DEBUG] Will read user %s from cluster %s from project %s", id, clusterId, serviceName) + if err := config.OVHClient.Get(endpoint, res); err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + for k, v := range res.ToMap() { + if k != "id" { + d.Set(k, v) + } else { + d.SetId(fmt.Sprint(v)) + } + } + + log.Printf("[DEBUG] Read user %+v", res) + return nil +} + +func resourceCloudProjectDatabaseOpensearchUserUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + params := (&CloudProjectDatabaseOpensearchUserUpdateOpts{}).FromResource(d) + + log.Printf("[DEBUG] Will update user: %+v from cluster %s from project %s", params, clusterId, serviceName) + err := config.OVHClient.Put(endpoint, params, nil) + if err != nil { + return fmt.Errorf("calling Put %s with params %+v:\n\t %q", endpoint, params, err) + } + + log.Printf("[DEBUG] Waiting for user %s to be READY", id) + err = waitForCloudProjectDatabaseUserReady(config.OVHClient, serviceName, "opensearch", clusterId, id, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return fmt.Errorf("timeout while waiting user %s to be READY: %w", id, err) + } + log.Printf("[DEBUG] user %s is READY", id) + + return resourceCloudProjectDatabaseOpensearchUserRead(d, meta) +} + +func resourceCloudProjectDatabaseOpensearchUserDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + serviceName := d.Get("service_name").(string) + clusterId := d.Get("cluster_id").(string) + id := d.Id() + + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(clusterId), + url.PathEscape(id), + ) + + log.Printf("[DEBUG] Will delete useruser %s from cluster %s from project %s", id, clusterId, serviceName) + err := config.OVHClient.Delete(endpoint, nil) + if err != nil { + return helpers.CheckDeleted(d, err, endpoint) + } + + log.Printf("[DEBUG] Waiting for user %s to be DELETED", id) + err = waitForCloudProjectDatabaseUserDeleted(config.OVHClient, serviceName, "opensearch", clusterId, id, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return fmt.Errorf("timeout while waiting user %s to be DELETED: %w", id, err) + } + log.Printf("[DEBUG] user %s is DELETED", id) + + d.SetId("") + + return nil +} diff --git a/ovh/resource_cloud_project_database_opensearch_user_test.go b/ovh/resource_cloud_project_database_opensearch_user_test.go new file mode 100644 index 000000000..1852fb7d2 --- /dev/null +++ b/ovh/resource_cloud_project_database_opensearch_user_test.go @@ -0,0 +1,83 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const testAccCloudProjectDatabaseOpensearchUserConfig = ` +resource "ovh_cloud_project_database" "db" { + service_name = "%s" + description = "%s" + engine = "opensearch" + version = "%s" + plan = "essential" + nodes { + region = "%s" + } + flavor = "%s" +} + +resource "ovh_cloud_project_database_opensearch_user" "user" { + service_name = ovh_cloud_project_database.db.service_name + cluster_id = ovh_cloud_project_database.db.id + name = "%s" + acls { + pattern = "logs_*" + permission = "read" + } + acls { + pattern = "toto_*" + permission = "deny" + } +} +` + +func TestAccCloudProjectDatabaseOpensearchUser_basic(t *testing.T) { + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") + version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST") + if version == "" { + version = os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") + } + region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") + flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + name := "johndoe" + + config := fmt.Sprintf( + testAccCloudProjectDatabaseOpensearchUserConfig, + serviceName, + description, + version, + region, + flavor, + name, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloudDatabaseNoEngine(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "ovh_cloud_project_database_opensearch_user.user", "created_at"), + resource.TestCheckResourceAttrSet( + "ovh_cloud_project_database_opensearch_user.user", "password"), + resource.TestCheckResourceAttrSet( + "ovh_cloud_project_database_opensearch_user.user", "acls.#"), + resource.TestCheckResourceAttrSet( + "ovh_cloud_project_database_opensearch_user.user", "status"), + resource.TestCheckResourceAttr( + "ovh_cloud_project_database_opensearch_user.user", "name", name, + ), + ), + }, + }, + }) +} diff --git a/ovh/resource_cloud_project_database_postgresql_user.go b/ovh/resource_cloud_project_database_postgresql_user.go index 4d7bd1231..b0ea8f7a4 100644 --- a/ovh/resource_cloud_project_database_postgresql_user.go +++ b/ovh/resource_cloud_project_database_postgresql_user.go @@ -10,7 +10,7 @@ import ( "github.com/ovh/terraform-provider-ovh/ovh/helpers" ) -func resourceCloudProjectDatabasepPostgresqlUser() *schema.Resource { +func resourceCloudProjectDatabasePostgresqlUser() *schema.Resource { return &schema.Resource{ Create: resourceCloudProjectDatabasePostgresqlUserCreate, Read: resourceCloudProjectDatabasePostgresqlUserRead, @@ -41,7 +41,7 @@ func resourceCloudProjectDatabasepPostgresqlUser() *schema.Resource { Required: true, }, "roles": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Roles the user belongs to", Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, diff --git a/ovh/resource_cloud_project_database_postgresql_user_test.go b/ovh/resource_cloud_project_database_postgresql_user_test.go index 4c6eb5405..c5d5f3ad4 100644 --- a/ovh/resource_cloud_project_database_postgresql_user_test.go +++ b/ovh/resource_cloud_project_database_postgresql_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabasePostgresqlUserConfig = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "postgresql" version = "%s" plan = "essential" @@ -36,12 +38,14 @@ func TestAccCloudProjectDatabasePostgresqlUser_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" replication := "replication" config := fmt.Sprintf( testAccCloudProjectDatabasePostgresqlUserConfig, serviceName, + description, version, region, flavor, diff --git a/ovh/resource_cloud_project_database_redis_user.go b/ovh/resource_cloud_project_database_redis_user.go index c24afa92b..aab0b1db8 100644 --- a/ovh/resource_cloud_project_database_redis_user.go +++ b/ovh/resource_cloud_project_database_redis_user.go @@ -10,7 +10,7 @@ import ( "github.com/ovh/terraform-provider-ovh/ovh/helpers" ) -func resourceCloudProjectDatabasepRedisUser() *schema.Resource { +func resourceCloudProjectDatabaseRedisUser() *schema.Resource { return &schema.Resource{ Create: resourceCloudProjectDatabaseRedisUserCreate, Read: resourceCloudProjectDatabaseRedisUserRead, @@ -35,19 +35,19 @@ func resourceCloudProjectDatabasepRedisUser() *schema.Resource { Required: true, }, "categories": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Categories of the user", Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "commands": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Commands of the user", Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "keys": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Keys of the user", Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, @@ -61,7 +61,7 @@ func resourceCloudProjectDatabasepRedisUser() *schema.Resource { //Optional/Computed "channels": { - Type: schema.TypeList, + Type: schema.TypeSet, Description: "Channels of the user", Optional: true, // If no channels list, channels = ["*"] is computed at creation diff --git a/ovh/resource_cloud_project_database_redis_user_test.go b/ovh/resource_cloud_project_database_redis_user_test.go index b31a1b8e3..5ead77e25 100644 --- a/ovh/resource_cloud_project_database_redis_user_test.go +++ b/ovh/resource_cloud_project_database_redis_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseRedisUserConfig = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "redis" version = "%s" plan = "essential" @@ -39,6 +41,7 @@ func TestAccCloudProjectDatabaseRedisUser_basic(t *testing.T) { } region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) categoriesSet := "+@set" categoriesSortedset := "+@sortedset" channels := "*" @@ -51,6 +54,7 @@ func TestAccCloudProjectDatabaseRedisUser_basic(t *testing.T) { config := fmt.Sprintf( testAccCloudProjectDatabaseRedisUserConfig, serviceName, + description, version, region, flavor, diff --git a/ovh/resource_cloud_project_database_test.go b/ovh/resource_cloud_project_database_test.go index f57d4e123..e28188150 100644 --- a/ovh/resource_cloud_project_database_test.go +++ b/ovh/resource_cloud_project_database_test.go @@ -82,14 +82,16 @@ resource "ovh_cloud_project_database" "db" { ` func TestAccCloudProjectDatabase_basic(t *testing.T) { - description := acctest.RandomWithPrefix(test_prefix) + serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST") engine := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_ENGINE_TEST") version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) + config := fmt.Sprintf( testAccCloudProjectDatabaseConfig, - os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST"), + serviceName, description, engine, version, @@ -118,8 +120,6 @@ func TestAccCloudProjectDatabase_basic(t *testing.T) { "ovh_cloud_project_database.db", "endpoints.0.domain"), resource.TestCheckResourceAttrSet( "ovh_cloud_project_database.db", "endpoints.0.ssl"), - resource.TestCheckResourceAttrSet( - "ovh_cloud_project_database.db", "endpoints.0.ssl_mode"), resource.TestCheckResourceAttr( "ovh_cloud_project_database.db", "engine", engine), resource.TestCheckResourceAttr( diff --git a/ovh/resource_cloud_project_database_user_test.go b/ovh/resource_cloud_project_database_user_test.go index cc2e5fd1d..fc5ccdeaa 100644 --- a/ovh/resource_cloud_project_database_user_test.go +++ b/ovh/resource_cloud_project_database_user_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) const testAccCloudProjectDatabaseUserConfig = ` resource "ovh_cloud_project_database" "db" { service_name = "%s" + description = "%s" engine = "%s" version = "%s" plan = "essential" @@ -34,11 +36,13 @@ func TestAccCloudProjectDatabaseUser_basic(t *testing.T) { version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST") region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST") flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST") + description := acctest.RandomWithPrefix(test_prefix) name := "johndoe" config := fmt.Sprintf( testAccCloudProjectDatabaseUserConfig, serviceName, + description, engine, version, region, diff --git a/ovh/types_cloud_project_database.go b/ovh/types_cloud_project_database.go index a9bba45b6..8372506ab 100644 --- a/ovh/types_cloud_project_database.go +++ b/ovh/types_cloud_project_database.go @@ -357,7 +357,7 @@ func waitForCloudProjectDatabaseIpRestrictionDeleted(client *ovh.Client, service Pending: []string{"DELETING"}, Target: []string{"DELETED"}, Refresh: func() (interface{}, string, error) { - res := &CloudProjectDatabaseResponse{} + res := &CloudProjectDatabaseIpRestrictionResponse{} endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/ipRestriction/%s", url.PathEscape(serviceName), url.PathEscape(engine), @@ -436,6 +436,65 @@ func validateCloudProjectDatabaseUserEngineFunc(v interface{}, k string) (ws []s return } +func waitForCloudProjectDatabaseUserReady(client *ovh.Client, serviceName, engine string, databaseId string, userId string, timeOut time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"PENDING", "CREATING", "UPDATING"}, + Target: []string{"READY"}, + Refresh: func() (interface{}, string, error) { + res := &CloudProjectDatabaseUserResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(engine), + url.PathEscape(databaseId), + url.PathEscape(userId), + ) + err := client.Get(endpoint, res) + if err != nil { + return res, "", err + } + + return res, res.Status, nil + }, + Timeout: timeOut, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err := stateConf.WaitForState() + return err +} + +func waitForCloudProjectDatabaseUserDeleted(client *ovh.Client, serviceName, engine string, databaseId string, userId string, timeOut time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"DELETING"}, + Target: []string{"DELETED"}, + Refresh: func() (interface{}, string, error) { + res := &CloudProjectDatabaseUserResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/user/%s", + url.PathEscape(serviceName), + url.PathEscape(engine), + url.PathEscape(databaseId), + url.PathEscape(userId), + ) + err := client.Get(endpoint, res) + if err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && errOvh.Code == 404 { + return res, "DELETED", nil + } + return res, "", err + } + + return res, res.Status, nil + }, + Timeout: timeOut, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err := stateConf.WaitForState() + return err +} + // PostgresqlUser type CloudProjectDatabasePostgresqlUserResponse struct { @@ -475,7 +534,7 @@ type CloudProjectDatabasePostgresqlUserCreateOpts struct { func (opts *CloudProjectDatabasePostgresqlUserCreateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabasePostgresqlUserCreateOpts { opts.Name = d.Get("name").(string) - roles := d.Get("roles").([]interface{}) + roles := d.Get("roles").(*schema.Set).List() opts.Roles = make([]string, len(roles)) for i, e := range roles { if e != nil { @@ -490,7 +549,7 @@ type CloudProjectDatabasePostgresqlUserUpdateOpts struct { } func (opts *CloudProjectDatabasePostgresqlUserUpdateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabasePostgresqlUserUpdateOpts { - roles := d.Get("roles").([]interface{}) + roles := d.Get("roles").(*schema.Set).List() opts.Roles = make([]string, len(roles)) for i, e := range roles { opts.Roles[i] = e.(string) @@ -625,7 +684,7 @@ type CloudProjectDatabaseRedisUserCreateOpts struct { } func getStringSlice(i interface{}) []string { - iarr := i.([]interface{}) + iarr := i.(*schema.Set).List() arr := make([]string, len(iarr)) for i, e := range iarr { if e != nil { @@ -660,24 +719,183 @@ func (opts *CloudProjectDatabaseRedisUserUpdateOpts) FromResource(d *schema.Reso return opts } -func waitForCloudProjectDatabaseUserReady(client *ovh.Client, serviceName, engine string, databaseId string, userId string, timeOut time.Duration) error { +// Opensearch + +// // User + +type CloudProjectDatabaseOpensearchUserAcl struct { + Pattern string `json:"pattern"` + Permission string `json:"permission"` +} + +func (v CloudProjectDatabaseOpensearchUserAcl) ToMap() map[string]string { + obj := make(map[string]string) + + obj["pattern"] = v.Pattern + obj["permission"] = v.Permission + + return obj +} + +type CloudProjectDatabaseOpensearchUserResponse struct { + Acls []CloudProjectDatabaseOpensearchUserAcl `json:"acls"` + CreatedAt string `json:"createdAt"` + Id string `json:"id"` + Password string `json:"password"` + Status string `json:"status"` + Username string `json:"username"` +} + +func (p *CloudProjectDatabaseOpensearchUserResponse) String() string { + return fmt.Sprintf( + "Id: %s, User: %s, Status: %s", + p.Id, + p.Username, + p.Status, + ) +} + +func (v CloudProjectDatabaseOpensearchUserResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + var acls []map[string]string + for _, e := range v.Acls { + acls = append(acls, e.ToMap()) + } + + obj["acls"] = acls + obj["created_at"] = v.CreatedAt + obj["id"] = v.Id + obj["name"] = v.Username + obj["status"] = v.Status + + return obj +} + +type CloudProjectDatabaseOpensearchUserCreateOpts struct { + Acls []CloudProjectDatabaseOpensearchUserAcl `json:"acls,omitempty"` + Name string `json:"name"` +} + +func (opts *CloudProjectDatabaseOpensearchUserCreateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabaseOpensearchUserCreateOpts { + opts.Name = d.Get("name").(string) + acls := d.Get("acls").(*schema.Set).List() + opts.Acls = make([]CloudProjectDatabaseOpensearchUserAcl, len(acls)) + for i, e := range acls { + aclMap := e.(map[string]interface{}) + opts.Acls[i] = CloudProjectDatabaseOpensearchUserAcl{ + Pattern: aclMap["pattern"].(string), + Permission: aclMap["permission"].(string), + } + } + return opts +} + +type CloudProjectDatabaseOpensearchUserUpdateOpts struct { + Acls []CloudProjectDatabaseOpensearchUserAcl `json:"acls,omitempty"` +} + +func (opts *CloudProjectDatabaseOpensearchUserUpdateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabaseOpensearchUserUpdateOpts { + acls := d.Get("acls").(*schema.Set).List() + opts.Acls = make([]CloudProjectDatabaseOpensearchUserAcl, len(acls)) + for i, e := range acls { + aclMap := e.(map[string]interface{}) + opts.Acls[i] = CloudProjectDatabaseOpensearchUserAcl{ + Pattern: aclMap["pattern"].(string), + Permission: aclMap["permission"].(string), + } + } + return opts +} + +// // Pattern + +type CloudProjectDatabaseOpensearchPatternResponse struct { + Id string `json:"id"` + MaxIndexCount int `json:"maxIndexCount"` + Pattern string `json:"pattern"` +} + +func (p *CloudProjectDatabaseOpensearchPatternResponse) String() string { + return fmt.Sprintf( + "Id: %s, Pattern: %s, MaxIndexCount: %d", + p.Id, + p.Pattern, + p.MaxIndexCount, + ) +} + +func (v CloudProjectDatabaseOpensearchPatternResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + obj["id"] = v.Id + obj["max_index_count"] = v.MaxIndexCount + obj["pattern"] = v.Pattern + + return obj +} + +type CloudProjectDatabaseOpensearchPatternCreateOpts struct { + MaxIndexCount int `json:"maxIndexCount,omitempty"` + Pattern string `json:"pattern"` +} + +func (opts *CloudProjectDatabaseOpensearchPatternCreateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabaseOpensearchPatternCreateOpts { + opts.MaxIndexCount = d.Get("max_index_count").(int) + opts.Pattern = d.Get("pattern").(string) + + return opts +} + +func waitForCloudProjectDatabaseOpensearchPatternReady(client *ovh.Client, serviceName, databaseId string, patternId string, timeOut time.Duration) error { stateConf := &resource.StateChangeConf{ - Pending: []string{"PENDING", "CREATING", "UPDATING"}, + Pending: []string{"PENDING"}, Target: []string{"READY"}, Refresh: func() (interface{}, string, error) { - res := &CloudProjectDatabaseUserResponse{} - endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/user/%s", + res := &CloudProjectDatabaseOpensearchPatternResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern/%s", url.PathEscape(serviceName), - url.PathEscape(engine), url.PathEscape(databaseId), - url.PathEscape(userId), + url.PathEscape(patternId), ) err := client.Get(endpoint, res) if err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && errOvh.Code == 404 { + return res, "PENDING", nil + } return res, "", err } + return res, "READY", nil + }, + Timeout: timeOut, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } - return res, res.Status, nil + _, err := stateConf.WaitForState() + return err +} + +func waitForCloudProjectDatabaseOpensearchPatternDeleted(client *ovh.Client, serviceName, databaseId string, patternId string, timeOut time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"DELETING"}, + Target: []string{"DELETED"}, + Refresh: func() (interface{}, string, error) { + res := &CloudProjectDatabaseOpensearchPatternResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/opensearch/%s/pattern/%s", + url.PathEscape(serviceName), + url.PathEscape(databaseId), + url.PathEscape(patternId), + ) + err := client.Get(endpoint, res) + if err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && errOvh.Code == 404 { + return res, "DELETED", nil + } + return res, "", err + } + + return res, "DELETING", nil }, Timeout: timeOut, Delay: 10 * time.Second, @@ -688,17 +906,149 @@ func waitForCloudProjectDatabaseUserReady(client *ovh.Client, serviceName, engin return err } -func waitForCloudProjectDatabaseUserDeleted(client *ovh.Client, serviceName, engine string, databaseId string, userId string, timeOut time.Duration) error { +// Kafka + +// // Certificates + +type CloudProjectDatabaseKafkaCertificatesResponse struct { + Ca string `json:"ca"` +} + +func (p *CloudProjectDatabaseKafkaCertificatesResponse) String() string { + return fmt.Sprintf( + "Ca: %s", + p.Ca, + ) +} + +func (v CloudProjectDatabaseKafkaCertificatesResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + obj["ca"] = v.Ca + + return obj +} + +// // Topic + +type CloudProjectDatabaseKafkaTopicResponse struct { + Id string `json:"id"` + MinInsyncReplicas int `json:"minInsyncReplicas"` + Name string `json:"name"` + Partitions int `json:"partitions"` + Replication int `json:"replication"` + RetentionBytes int `json:"retentionBytes"` + RetentionHours int `json:"retentionHours"` +} + +func (p *CloudProjectDatabaseKafkaTopicResponse) String() string { + return fmt.Sprintf( + "Id: %s, Name: %s", + p.Id, + p.Name, + ) +} + +func (v CloudProjectDatabaseKafkaTopicResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + obj["id"] = v.Id + obj["min_insync_replicas"] = v.MinInsyncReplicas + obj["name"] = v.Name + obj["partitions"] = v.Partitions + obj["replication"] = v.Replication + obj["retention_bytes"] = v.RetentionBytes + obj["retention_hours"] = v.RetentionHours + + return obj +} + +type CloudProjectDatabaseKafkaTopicCreateOpts struct { + MinInsyncReplicas int `json:"minInsyncReplicas"` + Name string `json:"name,omitempty"` + Partitions int `json:"partitions"` + Replication int `json:"replication"` + RetentionBytes int `json:"retentionBytes"` + RetentionHours int `json:"retentionHours"` +} + +func (opts *CloudProjectDatabaseKafkaTopicCreateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabaseKafkaTopicCreateOpts { + opts.MinInsyncReplicas = d.Get("min_insync_replicas").(int) + opts.Name = d.Get("name").(string) + opts.Partitions = d.Get("partitions").(int) + opts.Replication = d.Get("replication").(int) + opts.RetentionBytes = d.Get("retention_bytes").(int) + opts.RetentionHours = d.Get("retention_hours").(int) + + return opts +} + +func validateIsSupEqual(v, min int) (errors []error) { + if v < min { + errors = append(errors, fmt.Errorf("Value %d is inferior of min value %d", v, min)) + } + return +} + +func validateCloudProjectDatabaseKafkaTopicMinInsyncReplicasFunc(v interface{}, k string) (ws []string, errors []error) { + errors = validateIsSupEqual(v.(int), 1) + return +} + +func validateCloudProjectDatabaseKafkaTopicPartitionsFunc(v interface{}, k string) (ws []string, errors []error) { + errors = validateIsSupEqual(v.(int), 1) + return +} + +func validateCloudProjectDatabaseKafkaTopicReplicationFunc(v interface{}, k string) (ws []string, errors []error) { + errors = validateIsSupEqual(v.(int), 2) + return +} + +func validateCloudProjectDatabaseKafkaTopicRetentionHoursFunc(v interface{}, k string) (ws []string, errors []error) { + errors = validateIsSupEqual(v.(int), -1) + return +} + +func waitForCloudProjectDatabaseKafkaTopicReady(client *ovh.Client, serviceName, databaseId string, topicId string, timeOut time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"PENDING"}, + Target: []string{"READY"}, + Refresh: func() (interface{}, string, error) { + res := &CloudProjectDatabaseKafkaTopicResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic/%s", + url.PathEscape(serviceName), + url.PathEscape(databaseId), + url.PathEscape(topicId), + ) + err := client.Get(endpoint, res) + if err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && errOvh.Code == 404 { + return res, "PENDING", nil + } + return res, "", err + } + return res, "READY", nil + }, + Timeout: timeOut, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err := stateConf.WaitForState() + return err +} + +func waitForCloudProjectDatabaseKafkaTopicDeleted(client *ovh.Client, serviceName, databaseId string, topicId string, timeOut time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"DELETING"}, Target: []string{"DELETED"}, Refresh: func() (interface{}, string, error) { - res := &CloudProjectDatabaseResponse{} - endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/user/%s", + res := &CloudProjectDatabaseKafkaTopicResponse{} + endpoint := fmt.Sprintf("/cloud/project/%s/database/kafka/%s/topic/%s", url.PathEscape(serviceName), - url.PathEscape(engine), url.PathEscape(databaseId), - url.PathEscape(userId), + url.PathEscape(topicId), ) err := client.Get(endpoint, res) if err != nil { @@ -708,7 +1058,7 @@ func waitForCloudProjectDatabaseUserDeleted(client *ovh.Client, serviceName, eng return res, "", err } - return res, res.Status, nil + return res, "DELETING", nil }, Timeout: timeOut, Delay: 10 * time.Second, @@ -718,3 +1068,70 @@ func waitForCloudProjectDatabaseUserDeleted(client *ovh.Client, serviceName, eng _, err := stateConf.WaitForState() return err } + +// // ACL + +type CloudProjectDatabaseKafkaAclResponse struct { + Id string `json:"id"` + Permission string `json:"permission"` + Topic string `json:"topic"` + Username string `json:"username"` +} + +func (p *CloudProjectDatabaseKafkaAclResponse) String() string { + return fmt.Sprintf( + "Id: %s, Permission: %s, affected User: %s, affected Topic %s", + p.Id, + p.Permission, + p.Username, + p.Topic, + ) +} + +func (v CloudProjectDatabaseKafkaAclResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + obj["id"] = v.Id + obj["permission"] = v.Permission + obj["topic"] = v.Topic + obj["username"] = v.Username + + return obj +} + +type CloudProjectDatabaseKafkaAclCreateOpts struct { + Permission string `json:"permission"` + Topic string `json:"topic"` + Username string `json:"username"` +} + +func (opts *CloudProjectDatabaseKafkaAclCreateOpts) FromResource(d *schema.ResourceData) *CloudProjectDatabaseKafkaAclCreateOpts { + opts.Permission = d.Get("permission").(string) + opts.Topic = d.Get("topic").(string) + opts.Username = d.Get("username").(string) + + return opts +} + +// // User Access + +type CloudProjectDatabaseKafkaUserAccessResponse struct { + Cert string `json:"cert"` + Key string `json:"key"` +} + +func (p *CloudProjectDatabaseKafkaUserAccessResponse) String() string { + return fmt.Sprintf( + "Cert: %s", + p.Cert, + ) +} + +func (v CloudProjectDatabaseKafkaUserAccessResponse) ToMap() map[string]interface{} { + obj := make(map[string]interface{}) + + obj["cert"] = v.Cert + obj["key"] = v.Key + + return obj +} diff --git a/website/docs/d/cloud_project_database.html.markdown b/website/docs/d/cloud_project_database.html.markdown index cc12995e6..58e26db9b 100644 --- a/website/docs/d/cloud_project_database.html.markdown +++ b/website/docs/d/cloud_project_database.html.markdown @@ -28,13 +28,13 @@ output "cluster_id" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The database engine you want to get information. To get a full list of available engine visit. +* `engine` - (Required) The database engine you want to get information. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). -* `cluster_id` - Cluster ID +* `id` - (Required) Cluster ID ## Attributes Reference @@ -42,7 +42,7 @@ output "cluster_id" { The following attributes are exported: -* `id` - Public Cloud Database Service ID +* `id` - See Argument Reference above. * `service_name` - See Argument Reference above. * `backup_time` - Time on which backups start every day. * `created_at` - Date of the creation of the cluster. diff --git a/website/docs/d/cloud_project_database_ip_restrictions.html.markdown b/website/docs/d/cloud_project_database_ip_restrictions.html.markdown index 27e84747a..ab6bcfd76 100644 --- a/website/docs/d/cloud_project_database_ip_restrictions.html.markdown +++ b/website/docs/d/cloud_project_database_ip_restrictions.html.markdown @@ -27,13 +27,13 @@ output "ips" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The engine of the database cluster you want to list IP restrictions. To get a full list of available engine visit. +* `engine` - (Required) The engine of the database cluster you want to list IP restrictions. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID ## Attributes Reference diff --git a/website/docs/d/cloud_project_database_kafka_acl.html.markdown b/website/docs/d/cloud_project_database_kafka_acl.html.markdown new file mode 100644 index 000000000..a5885319c --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_acl.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_acl" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-acl" +description: |- + Get information about an ACL of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_acl (Data Source) + +Use this data source to get information about an ACL of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = "XXX" + cluster_id = "YYY" + id = "ZZZ" +} + +output "acl_permission" { + value = data.ovh_cloud_project_database_kafka_acl.acl.permission +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +* `id` - (Required) ACL ID + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - See Argument Reference above. +* `permission` - Permission to give to this username on this topic. +* `service_name` - See Argument Reference above. +* `topic` - Topic affected by this ACL. +* `username` - Username affected by this ACL. + diff --git a/website/docs/d/cloud_project_database_kafka_acls.html.markdown b/website/docs/d/cloud_project_database_kafka_acls.html.markdown new file mode 100644 index 000000000..6387b844e --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_acls.html.markdown @@ -0,0 +1,40 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_acls" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-acls" +description: |- + Get the list of ACLS of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_acls (Data Source) + +Use this data source to get the list of ACLs of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_acls" "acls" { + service_name = "XXX" + cluster_id = "YYY" +} + +output "acl_ids" { + value = data.ovh_cloud_project_database_kafka_acls.acls.acl_ids +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +## Attributes Reference + +`id` is set to the md5 sum of the list of all ACL ids. In addition, +the following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `service_name` - See Argument Reference above. +* `acl_ids` - The list of ACLs ids of the kafka cluster associated with the project. diff --git a/website/docs/d/cloud_project_database_kafka_certificates.html.markdown b/website/docs/d/cloud_project_database_kafka_certificates.html.markdown new file mode 100644 index 000000000..09bbb9ffa --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_certificates.html.markdown @@ -0,0 +1,43 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_certificates" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-certificates" +description: |- + Get information about certificates of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_certificates (Data Source) + +Use this data source to get information about certificates of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_certificates" "certificates" { + service_name = "XXX" + cluster_id = "YYY" +} + +output "certificates_ca" { + value = data.ovh_cloud_project_database_kafka_certificates.certificates.ca +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +## Attributes Reference + +The following attributes are exported: + +`id` is set to the md5 sum of the CA. In addition, +the following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `service_name` - See Argument Reference above. +* `ca` - CA certificate used for the service. + diff --git a/website/docs/d/cloud_project_database_kafka_topic.html.markdown b/website/docs/d/cloud_project_database_kafka_topic.html.markdown new file mode 100644 index 000000000..b705e862c --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_topic.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_topic" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-topic" +description: |- + Get information about a topic of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_topic (Data Source) + +Use this data source to get information about a topic of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_topic" "topic" { + service_name = "XXX" + cluster_id = "YYY" + id = "ZZZ" +} + +output "topic_name" { + value = data.ovh_cloud_project_database_kafka_topic.topic.name +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +* `id` - (Required) Topic ID + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - See Argument Reference above. +* `min_insync_replicas` - Minimum insync replica accepted for this topic. +* `name` - Name of the topic. +* `partitions` - Number of partitions for this topic. +* `replication` - Number of replication for this topic. +* `retention_bytes` - Number of bytes for the retention of the data for this topic. Inferior to 0 mean Unlimited +* `retention_hours` - Number of hours for the retention of the data for this topic. Inferior to 0 mean Unlimited +* `service_name` - See Argument Reference above. + diff --git a/website/docs/d/cloud_project_database_kafka_topics.html.markdown b/website/docs/d/cloud_project_database_kafka_topics.html.markdown new file mode 100644 index 000000000..b65de4fef --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_topics.html.markdown @@ -0,0 +1,40 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_topics" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-topics" +description: |- + Get the list of topics of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_topics (Data Source) + +Use this data source to get the list of topics of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_topics" "topics" { + service_name = "XXX" + cluster_id = "YYY" +} + +output "topic_ids" { + value = data.ovh_cloud_project_database_kafka_topics.topics.topic_ids +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +## Attributes Reference + +`id` is set to the md5 sum of the list of all topics ids. In addition, +the following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `service_name` - See Argument Reference above. +* `topic_ids` - The list of topics ids of the kafka cluster associated with the project. diff --git a/website/docs/d/cloud_project_database_kafka_user_access.html.markdown b/website/docs/d/cloud_project_database_kafka_user_access.html.markdown new file mode 100644 index 000000000..fbb369ed1 --- /dev/null +++ b/website/docs/d/cloud_project_database_kafka_user_access.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_user_acces" +sidebar_current: "docs-ovh-datasource-cloud-project-database-kafka-user-acces" +description: |- + Get information about user acces of a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_user_acces (Data Source) + +Use this data source to get information about user acces of a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_kafka_user_access" "access" { + service_name = "XXX" + cluster_id = "YYY" + user_id = "ZZZ" +} + +output "access_cert" { + value = data.ovh_cloud_project_database_kafka_user_access.access.cert +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +* `user_id` - (Required) User ID + +## Attributes Reference + +`id` is set to the md5 sum of the Cert. In addition, +the following attributes are exported: + +* `cert` - User cert. +* `cluster_id` - See Argument Reference above. +* `key` - (Sensitive) User key for the cert. +* `service_name` - See Argument Reference above. +* `user_id` - See Argument Reference above. + diff --git a/website/docs/d/cloud_project_database_mongodb_user.html.markdown b/website/docs/d/cloud_project_database_mongodb_user.html.markdown index 749203d1b..807429d08 100644 --- a/website/docs/d/cloud_project_database_mongodb_user.html.markdown +++ b/website/docs/d/cloud_project_database_mongodb_user.html.markdown @@ -26,12 +26,12 @@ output "mongouser_roles" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID -* `name` - Name of the user with the authentication database in the format name@authDB, for example: johndoe@admin +* `name` - (Required) Name of the user with the authentication database in the format name@authDB, for example: johndoe@admin ## Attributes Reference diff --git a/website/docs/d/cloud_project_database_opensearch_pattern.html.markdown b/website/docs/d/cloud_project_database_opensearch_pattern.html.markdown new file mode 100644 index 000000000..a8225ff9f --- /dev/null +++ b/website/docs/d/cloud_project_database_opensearch_pattern.html.markdown @@ -0,0 +1,45 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_opensearch_pattern" +sidebar_current: "docs-ovh-datasource-cloud-project-database-opensearch-pattern" +description: |- + Get information about a pattern of a opensearch cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_opensearch_pattern (Data Source) + +Use this data source to get information about a pattern of a opensearch cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = "XXX" + cluster_id = "YYY" + id = "ZZZ" +} + +output "pattern_pattern" { + value = data.ovh_cloud_project_database_opensearch_pattern.pattern.pattern +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +* `id` - (Required) Pattern ID. + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - See Argument Reference above. +* `max_index_count` - Maximum number of index for this pattern. +* `pattern` - Pattern format. +* `service_name` - Current status of the pattern. + diff --git a/website/docs/d/cloud_project_database_opensearch_patterns.html.markdown b/website/docs/d/cloud_project_database_opensearch_patterns.html.markdown new file mode 100644 index 000000000..347760634 --- /dev/null +++ b/website/docs/d/cloud_project_database_opensearch_patterns.html.markdown @@ -0,0 +1,40 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_opensearch_patterns" +sidebar_current: "docs-ovh-datasource-cloud-project-database-opensearch-patterns" +description: |- + Get the list of patterns of a opensearch cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_opensearch_patterns (Data Source) + +Use this data source to get the list of pattern of a opensearch cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_opensearch_patterns" "patterns" { + service_name = "XXX" + cluster_id = "YYY" +} + +output "pattern_ids" { + value = data.ovh_cloud_project_database_opensearch_patterns.patterns.pattern_ids +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +## Attributes Reference + +`id` is set to the md5 sum of the list of all patterns ids. In addition, +the following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `service_name` - See Argument Reference above. +* `pattern_ids` - The list of patterns ids of the opensearch cluster associated with the project. diff --git a/website/docs/d/cloud_project_database_opensearch_user.html.markdown b/website/docs/d/cloud_project_database_opensearch_user.html.markdown new file mode 100644 index 000000000..6fa132d17 --- /dev/null +++ b/website/docs/d/cloud_project_database_opensearch_user.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_opensearch_user" +sidebar_current: "docs-ovh-datasource-cloud-project-database-opensearch-user" +description: |- + Get information about a user of a opensearch cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_opensearch_user (Data Source) + +Use this data source to get information about a user of a opensearch cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database_opensearch_user" "osuser" { + service_name = "XXX" + cluster_id = "YYY" + name = "ZZZ" +} + +output "osuser_acls" { + value = data.ovh_cloud_project_database_opensearch_user.osuser.acls +} +``` + +## Argument Reference + +* `service_name` - (Required) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required) Cluster ID + +* `name` - (Required) Name of the user. + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `created_at` - Date of the creation of the user. +* `id` - ID of the user. +* `acls` - Acls of the user. + * `pattern` - Pattern of the ACL. + * `permission` - Permission of the ACL. +* `service_name` - Current status of the user. +* `status` - Current status of the user. +* `name` - Name of the user. diff --git a/website/docs/d/cloud_project_database_postgresql_user.html.markdown b/website/docs/d/cloud_project_database_postgresql_user.html.markdown index f26e1ea1e..75b88b4c1 100644 --- a/website/docs/d/cloud_project_database_postgresql_user.html.markdown +++ b/website/docs/d/cloud_project_database_postgresql_user.html.markdown @@ -26,12 +26,12 @@ output "pguser_roles" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID -* `name` - Name of the user. +* `name` - (Required) Name of the user. ## Attributes Reference diff --git a/website/docs/d/cloud_project_database_redis_user.html.markdown b/website/docs/d/cloud_project_database_redis_user.html.markdown index f608c06d9..ab9c2974f 100644 --- a/website/docs/d/cloud_project_database_redis_user.html.markdown +++ b/website/docs/d/cloud_project_database_redis_user.html.markdown @@ -26,12 +26,12 @@ output "redisuser_commands" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID -* `name` - Name of the user +* `name` - (Required) Name of the user ## Attributes Reference diff --git a/website/docs/d/cloud_project_database_user.html.markdown b/website/docs/d/cloud_project_database_user.html.markdown index 2d412f9fe..8b6c8fd2a 100644 --- a/website/docs/d/cloud_project_database_user.html.markdown +++ b/website/docs/d/cloud_project_database_user.html.markdown @@ -27,10 +27,10 @@ output "user_name" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The engine of the database cluster you want user information. To get a full list of available engine visit : +* `engine` - (Required) The engine of the database cluster you want user information. To get a full list of available engine visit : [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases).\ Available engines for this resource (other have specific resource): * `cassandra` @@ -38,9 +38,9 @@ Available engines for this resource (other have specific resource): * `kafkaConnect` * `mysql` -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID -* `name` - Name of the user. +* `name` - (Required) Name of the user. ## Attributes Reference diff --git a/website/docs/d/cloud_project_database_users.html.markdown b/website/docs/d/cloud_project_database_users.html.markdown index 40e265bfa..f5fc92de8 100644 --- a/website/docs/d/cloud_project_database_users.html.markdown +++ b/website/docs/d/cloud_project_database_users.html.markdown @@ -26,17 +26,18 @@ output "user_ids" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The engine of the database cluster you want to list users. To get a full list of available engine visit. +* `engine` - (Required) The engine of the database cluster you want to list users. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). -* `cluster_id` - Cluster ID +* `cluster_id` - (Required) Cluster ID ## Attributes Reference -The following attributes are exported: +`id` is set to the md5 sum of the list of all user ids. In addition, +the following attributes are exported: * `cluster_id` - See Argument Reference above. * `service_name` - See Argument Reference above. diff --git a/website/docs/d/cloud_project_databases.html.markdown b/website/docs/d/cloud_project_databases.html.markdown index c30f6ba04..6f82e7a28 100644 --- a/website/docs/d/cloud_project_databases.html.markdown +++ b/website/docs/d/cloud_project_databases.html.markdown @@ -27,10 +27,10 @@ output "cluster_ids" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The database engine you want to list. To get a full list of available engine visit. +* `engine` - (Required) The database engine you want to list. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index a94c635bb..098ae3de0 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -125,8 +125,12 @@ variables must also be set: * `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` - The version of the database engine to test. +* `OVH_CLOUD_PROJECT_DATABASE_KAFKA_VERSION_TEST` - The version of the kafka to test. if not set `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` is use. + * `OVH_CLOUD_PROJECT_DATABASE_MONGODB_VERSION_TEST` - The version of the mongodb to test. if not set `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` is use. +* `OVH_CLOUD_PROJECT_DATABASE_OPENSEARCH_VERSION_TEST` - The version of the opensearch to test. if not set `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` is use. + * `OVH_CLOUD_PROJECT_DATABASE_POSTGRESQL_VERSION_TEST` - The version of the postgresql to test. if not set `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` is use. * `OVH_CLOUD_PROJECT_DATABASE_REDIS_VERSION_TEST` - The version of the redis to test. if not set `OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST` is use. diff --git a/website/docs/r/cloud_project_database.html.markdown b/website/docs/r/cloud_project_database.html.markdown index 63bfe626f..730b10ccf 100644 --- a/website/docs/r/cloud_project_database.html.markdown +++ b/website/docs/r/cloud_project_database.html.markdown @@ -24,6 +24,105 @@ interact directly with the team that builds our databases services and terraform ## Example Usage +Minimum settings for each engine (region choice is up to the user): +```hcl +resource "ovh_cloud_project_database" "cassandradb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-cassandra" + engine = "cassandra" + version = "4.0" + plan = "essential" + nodes { + region = "BHS" + } + nodes { + region = "BHS" + } + nodes { + region = "BHS" + } + flavor = "db1-4" +} + +resource "ovh_cloud_project_database" "kafkadb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-kafka" + engine = "kafka" + version = "3.1" + plan = "business" + nodes { + region = "DE" + } + nodes { + region = "DE" + } + nodes { + region = "DE" + } + flavor = "db1-4" +} + +resource "ovh_cloud_project_database" "mongodb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-mongodb" + engine = "mongodb" + version = "5.0" + plan = "essential" + nodes { + region = "GRA" + } + flavor = "db1-2" +} + +resource "ovh_cloud_project_database" "mysqldb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-mysql" + engine = "mysql" + version = "8" + plan = "essential" + nodes { + region = "SBG" + } + flavor = "db1-4" +} + +resource "ovh_cloud_project_database" "opensearchdb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-opensearch" + engine = "opensearch" + version = "1" + plan = "essential" + nodes { + region = "UK" + } + flavor = "db1-4" +} + +resource "ovh_cloud_project_database" "pgsqldb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-postgresql" + engine = "postgresql" + version = "14" + plan = "essential" + nodes { + region = "WAW" + } + flavor = "db1-4" +} + +resource "ovh_cloud_project_database" "redisdb" { + service_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + description = "my-first-redis" + engine = "redis" + version = "6.2" + plan = "essential" + nodes { + region = "BHS" + } + flavor = "db1-4" +} +``` + To deploy a business PostgreSQL service with two nodes on public network: ```hcl resource "ovh_cloud_project_database" "postgresql" { @@ -74,29 +173,29 @@ resource "ovh_cloud_project_database" "mongodb" { The following arguments are supported: -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. * `description` - (Optional) Small description of the database service. -* `engine` - The database engine you want to deploy. To get a full list of available engine visit. +* `engine` - (Required, Forces new resource) The database engine you want to deploy. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). -* `flavor` - a valid OVH public cloud database flavor name in which the nodes will be started. +* `flavor` - (Required) A valid OVH public cloud database flavor name in which the nodes will be started. Ex: "db1-7". Changing this value upgrade the nodes with the new flavor. You can find the list of flavor names: https://www.ovhcloud.com/fr/public-cloud/prices/ -* `nodes` - List of nodes object. +* `nodes` - (Required, Minimum Items: 1) List of nodes object. Multi region cluster are not yet available, all node should be identical. - * `network_id` - Private network id in which the node should be deployed. - * `region` - Public cloud region in which the node should be deployed. + * `network_id` - (Optional, Forces new resource) Private network id in which the node should be deployed. + * `region` - (Required, Forces new resource) Public cloud region in which the node should be deployed. Ex: "GRA'. - * `subnet_id` - Private subnet ID in which the node is. + * `subnet_id` - (Optional, Forces new resource) Private subnet ID in which the node is. -* `plan` - List of nodes object. +* `plan` - (Required) List of nodes object. Enum: "essential", "business", "enterprise". -* `version` - The version of the engine in which the service should be deployed +* `version` - (Required) The version of the engine in which the service should be deployed ## Attributes Reference diff --git a/website/docs/r/cloud_project_database_ip_restriction.html.markdown b/website/docs/r/cloud_project_database_ip_restriction.html.markdown index b95853947..a7a52b338 100644 --- a/website/docs/r/cloud_project_database_ip_restriction.html.markdown +++ b/website/docs/r/cloud_project_database_ip_restriction.html.markdown @@ -29,15 +29,15 @@ resource "ovh_cloud_project_database_ip_restriction" "iprestriction" { ## Argument Reference -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The engine of the database cluster you want to add an IP restriction. To get a full list of available engine visit. +* `engine` - (Required, Forces new resource) The engine of the database cluster you want to add an IP restriction. To get a full list of available engine visit. [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases). -* `cluster_id` - Cluster ID. +* `cluster_id` - (Required, Forces new resource) Cluster ID. -* `ip` - Authorized IP. +* `ip` - (Required, Forces new resource) Authorized IP. * `description` - (Optional) Description of the IP restriction. diff --git a/website/docs/r/cloud_project_database_kafka_acl.html.markdown b/website/docs/r/cloud_project_database_kafka_acl.html.markdown new file mode 100644 index 000000000..33688c60c --- /dev/null +++ b/website/docs/r/cloud_project_database_kafka_acl.html.markdown @@ -0,0 +1,66 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_acl" +sidebar_current: "docs-ovh-resource-cloud-project-database-kafka-acl" +description: |- + Creates an ACL for a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_acl + +Creates an ACL for a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database" "kafka" { + service_name = "XXX" + engine = "kafka" + cluster_id = "ZZZ" +} + +resource "ovh_cloud_project_database_kafka_acl" "acl" { + service_name = ovh_cloud_project_database.kafka.service_name + cluster_id = ovh_cloud_project_database.kafka.id + permission = "read" + topic = "mytopic" + username = "johndoe" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required, Forces new resource) Cluster ID. + +* `permission` - (Required, Forces new resource) Permission to give to this username on this topic: + * `admin` + * `read` + * `write` + * `readwrite` + +* `topic` - (Required, Forces new resource) Topic affected by this ACL. + +* `username` - (Required, Forces new resource) Username affected by this ACL. + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - ID of the ACL. +* `permission` - See Argument Reference above. +* `service_name` - See Argument Reference above. +* `topic` - See Argument Reference above. +* `username` - See Argument Reference above. + +## Import + +OVHcloud Managed kafka clusters ACLs can be imported using the `service_name`, `cluster_id` and `id` of the acl, separated by "/" E.g., + +``` +$ terraform import ovh_cloud_project_database_kafka_acl.my_acl // \ No newline at end of file diff --git a/website/docs/r/cloud_project_database_kafka_topic.html.markdown b/website/docs/r/cloud_project_database_kafka_topic.html.markdown new file mode 100644 index 000000000..1394a906d --- /dev/null +++ b/website/docs/r/cloud_project_database_kafka_topic.html.markdown @@ -0,0 +1,76 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_kafka_topic" +sidebar_current: "docs-ovh-resource-cloud-project-database-kafka-topic" +description: |- + Creates a topic for a kafka cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_kafka_topic + +Creates a topic for a kafka cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database" "kafka" { + service_name = "XXX" + engine = "kafka" + cluster_id = "ZZZ" +} + +resource "ovh_cloud_project_database_kafka_topic" "topic" { + service_name = ovh_cloud_project_database.kafka.service_name + cluster_id = ovh_cloud_project_database.kafka.id + name = "mytopic" + min_insync_replicas = 1 + partitions = 3 + replication = 2 + retention_bytes = 4 + retention_hours = 5 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required, Forces new resource) Cluster ID. + +* `name` - (Required, Forces new resource) Name of the topic. No spaces allowed. + +* `min_insync_replicas` - (Optional, Forces new resource) Minimum insync replica accepted for this topic. Should be superior to 0 + +* `partitions` - (Optional, Forces new resource) Number of partitions for this topic. Should be superior to 0 + +* `replication` - (Optional, Forces new resource) Number of replication for this topic. Should be superior to 1 + +* `retention_bytes` - (Optional, Forces new resource) Number of bytes for the retention of the data for this topic. Inferior to 0 means unlimited + +* `retention_hours` - (Optional, Forces new resource) Number of hours for the retention of the data for this topic. Should be superior to -2. Inferior to 0 means unlimited + + + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - ID of the topic. +* `min_insync_replicas` - See Argument Reference above. +* `name` - See Argument Reference above. +* `partitions` - See Argument Reference above. +* `replication` - See Argument Reference above. +* `retention_bytes` - See Argument Reference above. +* `retention_hours` - See Argument Reference above. +* `service_name` - See Argument Reference above. + +## Import + +OVHcloud Managed kafka clusters topics can be imported using the `service_name`, `cluster_id` and `id` of the topic, separated by "/" E.g., + +``` +$ terraform import ovh_cloud_project_database_kafka_topic.my_topic // \ No newline at end of file diff --git a/website/docs/r/cloud_project_database_mongodb_user.html.markdown b/website/docs/r/cloud_project_database_mongodb_user.html.markdown index d15260b8d..3e6b35c67 100644 --- a/website/docs/r/cloud_project_database_mongodb_user.html.markdown +++ b/website/docs/r/cloud_project_database_mongodb_user.html.markdown @@ -31,12 +31,12 @@ resource "ovh_cloud_project_database_mongodb_user" "user" { The following arguments are supported: -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID. +* `cluster_id` - (Required, Forces new resource) Cluster ID. -* `name` - Name of the user. +* `name` - (Required, Forces new resource) Name of the user. * `roles` - (Optional: if omit, default role) Roles the user belongs to. Possible values: * `backup` @@ -55,7 +55,7 @@ The following attributes are exported: * `created_at` - Date of the creation of the user. * `id` - ID of the user. * `name` - See Argument Reference above. -* `password` - Password of the user. +* `password` - (Sensitive) Password of the user. * `roles` - See Argument Reference above. * `service_name` - See Argument Reference above. * `status` - Current status of the user. diff --git a/website/docs/r/cloud_project_database_opensearch_pattern.html.markdown b/website/docs/r/cloud_project_database_opensearch_pattern.html.markdown new file mode 100644 index 000000000..5ea5bc15d --- /dev/null +++ b/website/docs/r/cloud_project_database_opensearch_pattern.html.markdown @@ -0,0 +1,58 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_opensearch_pattern" +sidebar_current: "docs-ovh-resource-cloud-project-database-opensearch-pattern" +description: |- + Creates a pattern for a opensearch cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_opensearch_pattern + +Creates a pattern for a opensearch cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database" "opensearch" { + service_name = "XXX" + engine = "opensearch" + cluster_id = "ZZZ" +} + +resource "ovh_cloud_project_database_opensearch_pattern" "pattern" { + service_name = ovh_cloud_project_database.opensearch.service_name + cluster_id = ovh_cloud_project_database.opensearch.id + max_index_count = 2 + pattern = "logs_*" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required, Forces new resource) Cluster ID. + +* `max_index_count` - (Optional, Forces new resource) Maximum number of index for this pattern. + +* `pattern` - (Required, Forces new resource) Pattern format. + +## Attributes Reference + +The following attributes are exported: + +* `cluster_id` - See Argument Reference above. +* `id` - ID of the pattern. +* `max_index_count` - See Argument Reference above. +* `pattern` - See Argument Reference above. +* `service_name` - See Argument Reference above. + +## Import + +OVHcloud Managed opensearch clusters patterns can be imported using the `service_name`, `cluster_id` and `id` of the pattern, separated by "/" E.g., + +``` +$ terraform import ovh_cloud_project_database_opensearch_pattern.my_pattern // \ No newline at end of file diff --git a/website/docs/r/cloud_project_database_opensearch_user.html.markdown b/website/docs/r/cloud_project_database_opensearch_user.html.markdown new file mode 100644 index 000000000..acd151e88 --- /dev/null +++ b/website/docs/r/cloud_project_database_opensearch_user.html.markdown @@ -0,0 +1,77 @@ +--- +layout: "ovh" +page_title: "OVH: cloud_project_database_opensearch_user" +sidebar_current: "docs-ovh-resource-cloud-project-database-opensearch-user" +description: |- + Creates an user for a opensearch cluster associated with a public cloud project. +--- + +# ovh_cloud_project_database_opensearch_user + +Creates an user for a opensearch cluster associated with a public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_database" "opensearch" { + service_name = "XXX" + engine = "opensearch" + cluster_id = "ZZZ" +} + +resource "ovh_cloud_project_database_opensearch_user" "user" { + service_name = ovh_cloud_project_database.opensearch.service_name + cluster_id = ovh_cloud_project_database.opensearch.id + acls { + pattern = "logs_*" + permission = "read" + } + acls { + pattern = "data_*" + permission = "deny" + } + name = "johndoe" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, + the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. + +* `cluster_id` - (Required, Forces new resource) Cluster ID. + +* `acls` - (Optional) Acls of the user. + * `pattern` - (Required) Pattern of the ACL. + * `permission` - (Required) Permission of the ACL: + * `admin` + * `read` + * `write` + * `readwrite` + * `deny` + +* `name` - (Required, Forces new resource) Username affected by this acl. + +## Attributes Reference + +The following attributes are exported: + +* `acls` - See Argument Reference above. + * `pattern` - See Argument Reference above. + * `permission` - See Argument Reference above. +* `cluster_id` - See Argument Reference above. +* `created_at` - Date of the creation of the user. +* `id` - ID of the user. +* `name` - See Argument Reference above. +* `password` - (Sensitive) Password of the user. +* `service_name` - See Argument Reference above. +* `status` - Current status of the user. + +## Import + +OVHcloud Managed opensearch clusters users can be imported using the `service_name`, `cluster_id` and `id` of the user, separated by "/" E.g., + +``` +$ terraform import ovh_cloud_project_database_opensearch_user.my_user // \ No newline at end of file diff --git a/website/docs/r/cloud_project_database_postgresql_user.html.markdown b/website/docs/r/cloud_project_database_postgresql_user.html.markdown index b2c25be46..47be999b7 100644 --- a/website/docs/r/cloud_project_database_postgresql_user.html.markdown +++ b/website/docs/r/cloud_project_database_postgresql_user.html.markdown @@ -31,12 +31,12 @@ resource "ovh_cloud_project_database_postgresql_user" "user" { The following arguments are supported: -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID. +* `cluster_id` - (Required, Forces new resource) Cluster ID. -* `name` - Name of the user. +* `name` - (Required, Forces new resource) Name of the user. * `roles` - (Optional: if omit, default role) Roles the user belongs to. Possible values: * `["replication"]` @@ -48,7 +48,7 @@ The following attributes are exported: * `cluster_id` - See Argument Reference above. * `created_at` - Date of the creation of the user. * `id` - ID of the user. -* `password` - Password of the user. +* `password` - (Sensitive) Password of the user. * `roles` - Roles the user belongs to. * `service_name` - See Argument Reference above. * `status` - Current status of the user. diff --git a/website/docs/r/cloud_project_database_redis_user.html.markdown b/website/docs/r/cloud_project_database_redis_user.html.markdown index 3af1b73af..8115877e6 100644 --- a/website/docs/r/cloud_project_database_redis_user.html.markdown +++ b/website/docs/r/cloud_project_database_redis_user.html.markdown @@ -34,20 +34,20 @@ resource "ovh_cloud_project_database_redis_user" "user" { The following arguments are supported: -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `cluster_id` - Cluster ID. +* `cluster_id` - (Required, Forces new resource) Cluster ID. -* `categories` - Categories of the user. +* `categories` - (Optional) Categories of the user. -* `channels` - Channels of the user. +* `channels` - (Optional: if omit, all channels) Channels of the user. -* `commands` - Commands of the user. +* `commands` - (Optional) Commands of the user. -* `keys` - Keys of the user. +* `keys` - (Optional) Keys of the user. -* `name` - Name of the user. +* `name` - (Required, Forces new resource) Name of the user. ## Attributes Reference @@ -61,7 +61,7 @@ The following attributes are exported: * `id` - ID of the user. * `keys` - See Argument Reference above. * `name` - See Argument Reference above. -* `password` - Password of the user. +* `password` - (Sensitive) Password of the user. * `service_name` - See Argument Reference above. * `status` - Current status of the user. diff --git a/website/docs/r/cloud_project_database_user.html.markdown b/website/docs/r/cloud_project_database_user.html.markdown index 1109ae353..a415465a4 100644 --- a/website/docs/r/cloud_project_database_user.html.markdown +++ b/website/docs/r/cloud_project_database_user.html.markdown @@ -38,10 +38,10 @@ resource "ovh_cloud_project_database_user" "user" { The following arguments are supported: -* `service_name` - The id of the public cloud project. If omitted, +* `service_name` - (Required, Forces new resource) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. -* `engine` - The engine of the database cluster you want to add. To get a full list of available engine visit : +* `engine` - (Required, Forces new resource) The engine of the database cluster you want to add. To get a full list of available engine visit : [public documentation](https://docs.ovh.com/gb/en/publiccloud/databases).\ Available engines for this resource (other have specific resource): * `cassandra` @@ -49,9 +49,9 @@ Available engines for this resource (other have specific resource): * `kafkaConnect` * `mysql` -* `cluster_id` - Cluster ID. +* `cluster_id` - (Required, Forces new resource) Cluster ID. -* `name` - Name of the user. +* `name` - (Required, Forces new resource) Name of the user. ## Attributes Reference @@ -60,7 +60,7 @@ The following attributes are exported: * `cluster_id` - See Argument Reference above. * `created_at` - Date of the creation of the user. * `id` - ID of the user. -* `password` - Password of the user. +* `password` - (Sensitive) Password of the user. * `service_name` - See Argument Reference above. * `status` - Current status of the user. * `name` - See Argument Reference above.