diff --git a/docs/data-sources/workspace_app_group_authorizations.md b/docs/data-sources/workspace_app_group_authorizations.md new file mode 100644 index 0000000000..7eea2dbd91 --- /dev/null +++ b/docs/data-sources/workspace_app_group_authorizations.md @@ -0,0 +1,73 @@ +--- +subcategory: "Workspace" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_workspace_app_group_authorizations" +description: |- + Use this data source to get the list of the application group authorizations within HuaweiCloud. +--- + +# huaweicloud_workspace_app_group_authorizations + +Use this data source to get the list of the application group authorizations within HuaweiCloud. + +## Example Usage + +### Query all application group authorizations + +```hcl +data "huaweicloud_workspace_app_group_authorizations" "test" {} +``` + +### Query the application group authorizations that contains the same name segment and the account type is USER + +```hcl +variable "account_name_prefix" {} + +data "huaweicloud_workspace_app_group_authorizations" "test" { + account = var.account_name_prefix + account_type = "USER" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String) Specifies the region in which to query the authorizations. + If omitted, the provider-level region will be used. + +* `app_group_id` - (Optional, String) Specifies the authorized application group ID. + +* `account` - (Optional, String) Specifies the name of the authorized account. Fuzzy search is supported. + +* `account_type` - (Optional, String) Specifies the type of the authorized account. + The valid values are as follows: + + **USER** + + **USER_GROUP** + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `authorizations` - All authorizations that match the filter parameters. + + The [authorizations](#app_group_authorizations) structure is documented below. + + +The `authorizations` block supports: + +* `id` - The authorized ID. + +* `account_id` - The ID of the authorized account. + +* `account` - The name of the authorized account. + +* `account_type` - The type of the authorized account. + +* `app_group_id` - The application group ID corresponding to the authorized account. + +* `app_group_name` - The application group name corresponding to the authorized account. + +* `created_at` - The time when the account is authorized to the specified application group, in RFC3339 format. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index c5120ca98f..035f22ebf3 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -1187,12 +1187,13 @@ func Provider() *schema.Provider { "huaweicloud_dws_workload_queue_associated_users": dws.DataSourceDwsWorkloadQueueAssociatedUsers(), "huaweicloud_dws_workload_queues": dws.DataSourceWorkloadQueues(), - "huaweicloud_workspace_app_groups": workspace.DataSourceWorkspaceAppGroups(), - "huaweicloud_workspace_app_nas_storages": workspace.DataSourceAppNasStorages(), - "huaweicloud_workspace_app_publishable_apps": workspace.DataSourceWorkspaceAppPublishableApps(), - "huaweicloud_workspace_app_storage_policies": workspace.DataSourceAppStoragePolicies(), - "huaweicloud_workspace_desktops": workspace.DataSourceDesktops(), - "huaweicloud_workspace_flavors": workspace.DataSourceWorkspaceFlavors(), + "huaweicloud_workspace_app_group_authorizations": workspace.DataSourceWorkspaceAppGroupAuthorizations(), + "huaweicloud_workspace_app_groups": workspace.DataSourceWorkspaceAppGroups(), + "huaweicloud_workspace_app_nas_storages": workspace.DataSourceAppNasStorages(), + "huaweicloud_workspace_app_publishable_apps": workspace.DataSourceWorkspaceAppPublishableApps(), + "huaweicloud_workspace_app_storage_policies": workspace.DataSourceAppStoragePolicies(), + "huaweicloud_workspace_desktops": workspace.DataSourceDesktops(), + "huaweicloud_workspace_flavors": workspace.DataSourceWorkspaceFlavors(), // Legacy "huaweicloud_images_image_v2": ims.DataSourceImagesImageV2(), diff --git a/huaweicloud/services/acceptance/workspace/data_source_huaweicloud_workspace_app_group_authorizations_test.go b/huaweicloud/services/acceptance/workspace/data_source_huaweicloud_workspace_app_group_authorizations_test.go new file mode 100644 index 0000000000..397be982e4 --- /dev/null +++ b/huaweicloud/services/acceptance/workspace/data_source_huaweicloud_workspace_app_group_authorizations_test.go @@ -0,0 +1,124 @@ +package workspace + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccDataSourceAppGroupAuthorizations_basic(t *testing.T) { + var ( + rName = acceptance.RandomAccResourceName() + dataSource = "data.huaweicloud_workspace_app_group_authorizations.test" + dc = acceptance.InitDataSourceCheck(dataSource) + + byAppGroupId = "data.huaweicloud_workspace_app_group_authorizations.filter_by_app_group_id" + dcByAppGroupId = acceptance.InitDataSourceCheck(byAppGroupId) + + byAccount = "data.huaweicloud_workspace_app_group_authorizations.filter_by_account" + dcByAccount = acceptance.InitDataSourceCheck(byAccount) + + byAccountType = "data.huaweicloud_workspace_app_group_authorizations.filter_by_account_type" + dcByAccountType = acceptance.InitDataSourceCheck(byAccountType) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckWorkspaceAppServerGroup(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDataSourceAppGroupAuthorizations_basic(rName), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestMatchResourceAttr(dataSource, "authorizations.#", regexp.MustCompile(`^[1-9]([0-9]*)?$`)), + dcByAppGroupId.CheckResourceExists(), + resource.TestCheckOutput("is_app_group_id_filter_useful", "true"), + resource.TestCheckResourceAttrSet(byAppGroupId, "authorizations.0.id"), + resource.TestCheckResourceAttrSet(byAppGroupId, "authorizations.0.account_id"), + resource.TestCheckResourceAttrSet(byAppGroupId, "authorizations.0.app_group_id"), + resource.TestCheckResourceAttrSet(byAppGroupId, "authorizations.0.app_group_name"), + resource.TestMatchResourceAttr(byAppGroupId, "authorizations.0.created_at", + regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}?(Z|([+-]\d{2}:\d{2}))$`)), + dcByAccount.CheckResourceExists(), + resource.TestCheckOutput("is_account_filter_useful", "true"), + dcByAccountType.CheckResourceExists(), + resource.TestCheckOutput("is_account_type_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDataSourceAppGroupAuthorizations_basic(name string) string { + return fmt.Sprintf(` +%[1]s + +data "huaweicloud_workspace_app_group_authorizations" "test" { + depends_on = [huaweicloud_workspace_app_group_authorization.test] +} + +locals { + app_group_id = huaweicloud_workspace_app_group.test.id + authorized_account = huaweicloud_workspace_app_group_authorization.test.accounts[0].account + authorized_account_type = huaweicloud_workspace_app_group_authorization.test.accounts[0].type +} + +data "huaweicloud_workspace_app_group_authorizations" "filter_by_app_group_id" { + depends_on = [huaweicloud_workspace_app_group_authorization.test] + + app_group_id = local.app_group_id +} + +locals { + app_group_id_filter_result = [ + for v in data.huaweicloud_workspace_app_group_authorizations.filter_by_app_group_id.authorizations[*].app_group_id : v == local.app_group_id + ] +} + +output "is_app_group_id_filter_useful" { + value = length(local.app_group_id_filter_result) > 0 && alltrue(local.app_group_id_filter_result) +} + +# Fuzzy search is supported. +data "huaweicloud_workspace_app_group_authorizations" "filter_by_account" { + depends_on = [huaweicloud_workspace_app_group_authorization.test] + + account = local.authorized_account +} + +locals { + account_filter_result = [ + for v in data.huaweicloud_workspace_app_group_authorizations.filter_by_account.authorizations[*].account : + strcontains(v, local.authorized_account) + ] +} + +output "is_account_filter_useful" { + value = length(local.account_filter_result) > 0 && alltrue(local.account_filter_result) +} + +data "huaweicloud_workspace_app_group_authorizations" "filter_by_account_type" { + depends_on = [huaweicloud_workspace_app_group_authorization.test] + + account_type = local.authorized_account_type +} + +locals { + account_type_filter_result = [ + for v in data.huaweicloud_workspace_app_group_authorizations.filter_by_account_type.authorizations[*].account_type : + v == local.authorized_account_type + ] +} + +output "is_account_type_filter_useful" { + value = length(local.account_type_filter_result) > 0 && alltrue(local.account_type_filter_result) +} +`, testAccAppGroupAuthorization_basic(name)) +} diff --git a/huaweicloud/services/acceptance/workspace/resource_huaweicloud_workspace_app_group_authorization_test.go b/huaweicloud/services/acceptance/workspace/resource_huaweicloud_workspace_app_group_authorization_test.go index c58e2865e1..84595f4ae7 100644 --- a/huaweicloud/services/acceptance/workspace/resource_huaweicloud_workspace_app_group_authorization_test.go +++ b/huaweicloud/services/acceptance/workspace/resource_huaweicloud_workspace_app_group_authorization_test.go @@ -15,7 +15,7 @@ func TestAccResourceAppGroupAuthorization_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.TestAccPreCheck(t) - acceptance.TestAccPreCheckWorkspaceAppServerGroupId(t) + acceptance.TestAccPreCheckWorkspaceAppServerGroup(t) }, ProviderFactories: acceptance.TestAccProviderFactories, CheckDestroy: nil, diff --git a/huaweicloud/services/workspace/data_source_huaweicloud_workspace_app_group_authorizations.go b/huaweicloud/services/workspace/data_source_huaweicloud_workspace_app_group_authorizations.go new file mode 100644 index 0000000000..1c4ada35e0 --- /dev/null +++ b/huaweicloud/services/workspace/data_source_huaweicloud_workspace_app_group_authorizations.go @@ -0,0 +1,172 @@ +// Generated by PMS #449 +package workspace + +import ( + "context" + + "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/tidwall/gjson" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/httphelper" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/schemas" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +func DataSourceWorkspaceAppGroupAuthorizations() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceWorkspaceAppGroupAuthorizationsRead, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Specifies the region in which to query the authorizations. If omitted, the provider-level region will be used.`, + }, + "app_group_id": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the authorized application group ID.`, + }, + "account": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the name of the authorized account. Fuzzy search is supported.`, + }, + "account_type": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the type of the authorized account.`, + }, + "authorizations": { + Type: schema.TypeList, + Computed: true, + Description: `All authorizations that match the filter parameters.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `The authorized ID.`, + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: `The ID of the authorized account.`, + }, + "account": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the authorized account.`, + }, + "account_type": { + Type: schema.TypeString, + Computed: true, + Description: `The type of the authorized account.`, + }, + "app_group_id": { + Type: schema.TypeString, + Computed: true, + Description: `The application group ID corresponding to the authorized account.`, + }, + "app_group_name": { + Type: schema.TypeString, + Computed: true, + Description: `The application group name corresponding to the authorized account.`, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: `The time when the account is authorized to the specified application group, in RFC3339 format.`, + }, + }, + }, + }, + }, + } +} + +type AppGroupAuthorizationsDSWrapper struct { + *schemas.ResourceDataWrapper + Config *config.Config +} + +func newAppGroupAuthorizationsDSWrapper(d *schema.ResourceData, meta interface{}) *AppGroupAuthorizationsDSWrapper { + return &AppGroupAuthorizationsDSWrapper{ + ResourceDataWrapper: schemas.NewSchemaWrapper(d), + Config: meta.(*config.Config), + } +} + +func dataSourceWorkspaceAppGroupAuthorizationsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + wrapper := newAppGroupAuthorizationsDSWrapper(d, meta) + lisAppGroAutRst, err := wrapper.ListAppGroupAuthorization() + if err != nil { + return diag.FromErr(err) + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + err = wrapper.listAppGroupAuthorizationToSchema(lisAppGroAutRst) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +// @API Workspace GET /v1/{project_id}/app-groups/actions/list-authorizations +func (w *AppGroupAuthorizationsDSWrapper) ListAppGroupAuthorization() (*gjson.Result, error) { + client, err := w.NewClient(w.Config, "appstream") + if err != nil { + return nil, err + } + + uri := "/v1/{project_id}/app-groups/actions/list-authorizations" + params := map[string]any{ + "app_group_id": w.Get("app_group_id"), + "account": w.Get("account"), + "account_type": w.Get("account_type"), + } + params = utils.RemoveNil(params) + return httphelper.New(client). + Method("GET"). + URI(uri). + Query(params). + OffsetPager("authorizations", "offset", "limit", 100). + Request(). + Result() +} + +func (w *AppGroupAuthorizationsDSWrapper) listAppGroupAuthorizationToSchema(body *gjson.Result) error { + d := w.ResourceData + mErr := multierror.Append(nil, + d.Set("region", w.Config.GetRegion(w.ResourceData)), + d.Set("authorizations", schemas.SliceToList(body.Get("authorizations"), + func(authorizations gjson.Result) any { + return map[string]any{ + "id": authorizations.Get("id").Value(), + "account_id": authorizations.Get("account_id").Value(), + "account": authorizations.Get("account").Value(), + "account_type": authorizations.Get("account_type").Value(), + "app_group_id": authorizations.Get("app_group_id").Value(), + "app_group_name": authorizations.Get("app_group_name").Value(), + "created_at": w.setAutCreAt(authorizations), + } + }, + )), + ) + return mErr.ErrorOrNil() +} + +func (*AppGroupAuthorizationsDSWrapper) setAutCreAt(data gjson.Result) string { + return utils.FormatTimeStampRFC3339(utils.ConvertTimeStrToNanoTimestamp(data.Get("create_at").String())/1000, false) +}