From db902ae2d1b9eb1944865aefc8acb605ff77d872 Mon Sep 17 00:00:00 2001 From: wuzhuanhong Date: Tue, 6 Feb 2024 10:21:49 +0800 Subject: [PATCH] feat(dli): add a new data source to get datasource authentication list(4146) --- docs/data-sources/dli_datasource_auths.md | 60 ++++++ huaweicloud/provider.go | 1 + ...e_huaweicloud_dli_datasource_auths_test.go | 199 ++++++++++++++++++ ...source_huaweicloud_dli_datasource_auths.go | 185 ++++++++++++++++ 4 files changed, 445 insertions(+) create mode 100644 docs/data-sources/dli_datasource_auths.md create mode 100644 huaweicloud/services/acceptance/dli/data_source_huaweicloud_dli_datasource_auths_test.go create mode 100644 huaweicloud/services/dli/data_source_huaweicloud_dli_datasource_auths.go diff --git a/docs/data-sources/dli_datasource_auths.md b/docs/data-sources/dli_datasource_auths.md new file mode 100644 index 0000000000..22a5e5c4a6 --- /dev/null +++ b/docs/data-sources/dli_datasource_auths.md @@ -0,0 +1,60 @@ +--- +subcategory: "Data Lake Insight (DLI)" +--- + +# huaweicloud_dli_datasource_auths + +Use this data source to get the list of DLI datasource authentications within HuaweiCloud. + +## Example Usage + +```hcl +variable "name" {} + +data "huaweicloud_dli_datasource_auths" "test" { + name = var.name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String) Specifies the region in which to query the data source. + If omitted, the provider-level region will be used. + +* `name` - (Optional, String) Specifies the name of the datasource authentication. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `auths` - The list of the datasource authentications. + The [auths](#datasource_auths) structure is documented below. + + +The `auths` block supports: + +* `name` - The name of the datasource authentication. + +* `type` - The type of the datasource authentication. + +* `username` - The login user name of the security cluster. + +* `certificate_location` - The OBS path of the security cluster certificate. + +* `truststore_location` - The OBS path of the **truststore** configuration file. + +* `keystore_location` - The OBS path of the **keystore** configuration file. + +* `keytab` - The OBS path of the **keytab** configuration file. + +* `krb5_conf` - The OBS path of the **krb5** configuration file. + +* `owner` - The user name of owner. + +* `created_at` - The creation time of the datasource authentication. + +* `updated_at` - The latest update time of the datasource authentication. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 0caca58557..e034d8f6f7 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -466,6 +466,7 @@ func Provider() *schema.Provider { "huaweicloud_dds_flavors": dds.DataSourceDDSFlavorV3(), "huaweicloud_dds_instances": dds.DataSourceDdsInstance(), + "huaweicloud_dli_datasource_auths": dli.DataSourceAuths(), "huaweicloud_dli_datasource_connections": dli.DataSourceConnections(), "huaweicloud_dms_kafka_flavors": dms.DataSourceKafkaFlavors(), diff --git a/huaweicloud/services/acceptance/dli/data_source_huaweicloud_dli_datasource_auths_test.go b/huaweicloud/services/acceptance/dli/data_source_huaweicloud_dli_datasource_auths_test.go new file mode 100644 index 0000000000..f4b5131438 --- /dev/null +++ b/huaweicloud/services/acceptance/dli/data_source_huaweicloud_dli_datasource_auths_test.go @@ -0,0 +1,199 @@ +package dli + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccDatasourceAuths_basic(t *testing.T) { + var ( + name = acceptance.RandomAccResourceName() + password = acceptance.RandomPassword() + byName = "data.huaweicloud_dli_datasource_auths.filter_by_name" + dcByName = acceptance.InitDataSourceCheck(byName) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.TestAccPreCheck(t) }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDatasourceAuths_basic(name, password), + Check: resource.ComposeTestCheckFunc( + dcByName.CheckResourceExists(), + resource.TestCheckResourceAttrSet(byName, "auths.#"), + resource.TestCheckResourceAttrSet(byName, "auths.0.created_at"), + resource.TestCheckResourceAttrSet(byName, "auths.0.updated_at"), + resource.TestCheckResourceAttrSet(byName, "auths.0.owner"), + resource.TestCheckResourceAttr(byName, "auths.0.type", "passwd"), + resource.TestCheckOutput("is_name_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDatasourceAuths_base(name string) string { + return fmt.Sprintf(` +data "huaweicloud_dli_datasource_auths" "filter_by_name" { + depends_on = [ + huaweicloud_dli_datasource_auth.test + ] + + name = "%[1]s" +} + +output "is_name_filter_useful" { + value = length(data.huaweicloud_dli_datasource_auths.filter_by_name.auths) == 1 +} +`, name) +} + +func testDatasourceAuths_basic(name string, password string) string { + return fmt.Sprintf(` +resource "huaweicloud_dli_datasource_auth" "test" { + name = "%[1]s" + type = "passwd" + username = "%[1]s" + password = "%[2]s" +} + +%[3]s +`, name, password, testDatasourceAuths_base(name)) +} + +func TestAccDatasourceAuths_CSS(t *testing.T) { + var ( + name = acceptance.RandomAccResourceName() + password = acceptance.RandomPassword() + byName = "data.huaweicloud_dli_datasource_auths.filter_by_name" + dcByName = acceptance.InitDataSourceCheck(byName) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckDliDsAuthCss(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDatasourceAuths_CSS(name, password), + Check: resource.ComposeTestCheckFunc( + dcByName.CheckResourceExists(), + resource.TestCheckResourceAttrSet(byName, "auths.#"), + resource.TestCheckResourceAttr(byName, "auths.0.type", "CSS"), + resource.TestCheckResourceAttr(byName, "auths.0.certificate_location", acceptance.HW_DLI_DS_AUTH_CSS_OBS_PATH), + resource.TestCheckOutput("is_name_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDatasourceAuths_CSS(name string, password string) string { + return fmt.Sprintf(` +resource "huaweicloud_dli_datasource_auth" "test" { + name = "%[1]s" + type = "CSS" + username = "%[1]s" + password = "%[2]s" + certificate_location = "%[3]s" +} + +%[4]s +`, name, password, acceptance.HW_DLI_DS_AUTH_CSS_OBS_PATH, testDatasourceAuths_base(name)) +} + +func TestAccDatasourceAuths_Kafka_SSL(t *testing.T) { + var ( + name = acceptance.RandomAccResourceName() + password = acceptance.RandomPassword() + byName = "data.huaweicloud_dli_datasource_auths.filter_by_name" + dcByName = acceptance.InitDataSourceCheck(byName) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckDliDsAuthKafka(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDatasourceAuths_Kafka_SSL(name, password), + Check: resource.ComposeTestCheckFunc( + dcByName.CheckResourceExists(), + resource.TestCheckResourceAttrSet(byName, "auths.#"), + resource.TestCheckResourceAttr(byName, "auths.0.type", "Kafka_SSL"), + resource.TestCheckResourceAttr(byName, "auths.0.truststore_location", acceptance.HW_DLI_DS_AUTH_KAFKA_TRUST_OBS_PATH), + resource.TestCheckResourceAttr(byName, "auths.0.keystore_location", acceptance.HW_DLI_DS_AUTH_KAFKA_KEY_OBS_PATH), + resource.TestCheckOutput("is_name_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDatasourceAuths_Kafka_SSL(name string, password string) string { + return fmt.Sprintf(` +resource "huaweicloud_dli_datasource_auth" "test" { + name = "%[1]s" + type = "Kafka_SSL" + truststore_location = "%[3]s" + truststore_password = "%[2]s" + keystore_location = "%[4]s" + keystore_password = "%[2]s" + key_password = "%[2]s" +} + +%[5]s +`, name, password, acceptance.HW_DLI_DS_AUTH_KAFKA_TRUST_OBS_PATH, acceptance.HW_DLI_DS_AUTH_KAFKA_KEY_OBS_PATH, testDatasourceAuths_base(name)) +} + +func TestAccDatasourceAuths_KRB(t *testing.T) { + var ( + name = acceptance.RandomAccResourceName() + byName = "data.huaweicloud_dli_datasource_auths.filter_by_name" + dcByName = acceptance.InitDataSourceCheck(byName) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckDliDsAuthKrb(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDatasourceAuths_KRB(name), + Check: resource.ComposeTestCheckFunc( + dcByName.CheckResourceExists(), + resource.TestCheckResourceAttrSet(byName, "auths.#"), + resource.TestCheckResourceAttr(byName, "auths.0.type", "KRB"), + resource.TestCheckResourceAttr(byName, "auths.0.krb5_conf", acceptance.HW_DLI_DS_AUTH_KRB_CONF_OBS_PATH), + resource.TestCheckResourceAttr(byName, "auths.0.keytab", acceptance.HW_DLI_DS_AUTH_KRB_TAB_OBS_PATH), + resource.TestCheckOutput("is_name_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDatasourceAuths_KRB(name string) string { + return fmt.Sprintf(` +resource "huaweicloud_dli_datasource_auth" "test" { + name = "%[1]s" + type = "KRB" + username = "%[1]s" + krb5_conf = "%[2]s" + keytab = "%[3]s" +} + +%[4]s +`, name, acceptance.HW_DLI_DS_AUTH_KRB_CONF_OBS_PATH, acceptance.HW_DLI_DS_AUTH_KRB_TAB_OBS_PATH, testDatasourceAuths_base(name)) +} diff --git a/huaweicloud/services/dli/data_source_huaweicloud_dli_datasource_auths.go b/huaweicloud/services/dli/data_source_huaweicloud_dli_datasource_auths.go new file mode 100644 index 0000000000..578c2ba953 --- /dev/null +++ b/huaweicloud/services/dli/data_source_huaweicloud_dli_datasource_auths.go @@ -0,0 +1,185 @@ +package dli + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/chnsz/golangsdk/pagination" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/common" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// @API DLI GET /v3/{project_id}/datasource/auth-infos +func DataSourceAuths() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceAuthsRead, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "auths": { + Type: schema.TypeList, + Computed: true, + Elem: authsSchema(), + }, + }, + } +} + +func authsSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + "certificate_location": { + Type: schema.TypeString, + Computed: true, + }, + "truststore_location": { + Type: schema.TypeString, + Computed: true, + }, + "keystore_location": { + Type: schema.TypeString, + Computed: true, + }, + "keytab": { + Type: schema.TypeString, + Computed: true, + }, + "krb5_conf": { + Type: schema.TypeString, + Computed: true, + }, + "owner": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func buildListAuthsQueryParams(d *schema.ResourceData) string { + queryParam := "" + if v, ok := d.GetOk("name"); ok { + queryParam += fmt.Sprintf("&auth_info_name=%v", v) + } + + if queryParam != "" { + queryParam = "?" + queryParam + } + + return queryParam +} + +func dataSourceAuthsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + httpUrl = "v3/{project_id}/datasource/auth-infos" + ) + client, err := cfg.NewServiceClient("dli", region) + if err != nil { + return diag.Errorf("error creating DLI v3 client: %s", err) + } + + getPath := client.Endpoint + httpUrl + getPath = strings.ReplaceAll(getPath, "{project_id}", client.ProjectID) + + listAuthsParams := buildListAuthsQueryParams(d) + getPath += listAuthsParams + + resp, err := pagination.ListAllItems( + client, + "offset", + getPath, + &pagination.QueryOpts{MarkerField: ""}) + if err != nil { + return common.CheckDeletedDiag(d, err, "error retrieving DLI datasource authentications") + } + + listRespJson, err := json.Marshal(resp) + if err != nil { + return diag.FromErr(err) + } + + var listRespBody interface{} + err = json.Unmarshal(listRespJson, &listRespBody) + if err != nil { + return diag.FromErr(err) + } + + generateUUID, err := uuid.GenerateUUID() + if err != nil { + return diag.Errorf("unable to generate ID: %s", err) + } + d.SetId(generateUUID) + + mErr := multierror.Append( + nil, + d.Set("region", region), + d.Set("auths", flattenListAuths(listRespBody)), + ) + + return diag.FromErr(mErr.ErrorOrNil()) +} + +func flattenListAuths(resp interface{}) []interface{} { + if resp == nil { + return nil + } + + curJson := utils.PathSearch("auth_infos", resp, make([]interface{}, 0)) + curArray := curJson.([]interface{}) + rst := make([]interface{}, len(curArray)) + for i, v := range curArray { + rst[i] = map[string]interface{}{ + "name": utils.PathSearch("auth_info_name", v, nil), + "type": utils.PathSearch("datasource_type", v, nil), + "username": utils.PathSearch("user_name", v, nil), + "certificate_location": utils.PathSearch("certificate_location", v, nil), + "truststore_location": utils.PathSearch("truststore_location", v, nil), + "keystore_location": utils.PathSearch("keystore_location", v, nil), + "keytab": utils.PathSearch("keytab", v, nil), + "krb5_conf": utils.PathSearch("krb5_conf", v, nil), + "owner": utils.PathSearch("owner", v, nil), + "created_at": utils.FormatTimeStampRFC3339(int64(utils.PathSearch("create_time", v, float64(0)).(float64))/1000, false), + "updated_at": utils.FormatTimeStampRFC3339(int64(utils.PathSearch("update_time", v, float64(0)).(float64))/1000, false), + } + } + return rst +}