From 09033fc1519477b91e95077e4e7ce6623b8d567b Mon Sep 17 00:00:00 2001 From: Ere Mid Date: Mon, 20 Feb 2023 15:33:23 +0100 Subject: [PATCH] feat(org): add datasource org_group --- docs/data-sources/org_group.md | 38 +++++ .../cloudavenue_org_group/data-source.tf | 3 + internal/provider/org/group_datasource.go | 132 ++++++++++++++++++ internal/provider/provider.go | 1 + internal/tests/org_group_datasource_test.go | 42 ++++++ 5 files changed, 216 insertions(+) create mode 100644 docs/data-sources/org_group.md create mode 100644 examples/data-sources/cloudavenue_org_group/data-source.tf create mode 100644 internal/provider/org/group_datasource.go create mode 100644 internal/tests/org_group_datasource_test.go diff --git a/docs/data-sources/org_group.md b/docs/data-sources/org_group.md new file mode 100644 index 00000000..f40e45e2 --- /dev/null +++ b/docs/data-sources/org_group.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cloudavenue_org_group Data Source - cloudavenue" +subcategory: "" +description: |- + Provides a CloudAvenue Org User data source. This can be used to read group. +--- + +# cloudavenue_org_group (Data Source) + +Provides a CloudAvenue Org User data source. This can be used to read group. + +## Example Usage + +```terraform +data "cloudavenue_org_group" "example" { + name = "your_value" +} +``` + + +## Schema + +### Required + +- `name` (String) A name for the org group + +### Optional + +- `description` (String) Description of the org group + +### Read-Only + +- `id` (String) The ID is a group `name`. +- `role` (String) The role to assign to the org group +- `user_names` (List of String) Set of user names that belong to the org group + + diff --git a/examples/data-sources/cloudavenue_org_group/data-source.tf b/examples/data-sources/cloudavenue_org_group/data-source.tf new file mode 100644 index 00000000..b84826be --- /dev/null +++ b/examples/data-sources/cloudavenue_org_group/data-source.tf @@ -0,0 +1,3 @@ +data "cloudavenue_org_group" "example" { + name = "your_value" +} \ No newline at end of file diff --git a/internal/provider/org/group_datasource.go b/internal/provider/org/group_datasource.go new file mode 100644 index 00000000..0b90050a --- /dev/null +++ b/internal/provider/org/group_datasource.go @@ -0,0 +1,132 @@ +// Package org provides a Terraform datasource. +package org + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" +) + +var ( + _ datasource.DataSource = &orgGroupDataSource{} + _ datasource.DataSourceWithConfigure = &orgGroupDataSource{} +) + +func NewOrgGroupDataSource() datasource.DataSource { + return &orgGroupDataSource{} +} + +type orgGroupDataSource struct { + client *client.CloudAvenue +} + +type orgGroupDataSourceModel struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Role types.String `tfsdk:"role"` + UserNames types.List `tfsdk:"user_names"` +} + +func (d *orgGroupDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_" + "org_group" +} + +func (d *orgGroupDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: "Provides a CloudAvenue Org User data source. This can be used to read group.", + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The ID is a group `name`.", + }, + "name": schema.StringAttribute{ + Required: true, + MarkdownDescription: "A name for the org group", + }, + "description": schema.StringAttribute{ + Optional: true, + MarkdownDescription: "Description of the org group", + }, + "role": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The role to assign to the org group", + }, + "user_names": schema.ListAttribute{ + ElementType: types.StringType, + Computed: true, + MarkdownDescription: "Set of user names that belong to the org group", + }, + }, + } +} + +func (d *orgGroupDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.CloudAvenue) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *client.CloudAvenue, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + d.client = client +} + +func (d *orgGroupDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data orgGroupDataSourceModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // group creation is accessible only for administator account + adminOrg, err := d.client.Vmware.GetAdminOrgByNameOrId(d.client.GetOrg()) + if err != nil { + resp.Diagnostics.AddError("Error retrieving Org", err.Error()) + return + } + + orgGroup, err := adminOrg.GetGroupByName(data.Name.ValueString(), false) + if err != nil { + resp.Diagnostics.AddError("Error retrieving Org Group", err.Error()) + return + } + + var userNames []attr.Value + for _, user := range orgGroup.Group.UsersList.UserReference { + userNames = append(userNames, types.StringValue(user.Name)) + } + + data = orgGroupDataSourceModel{ + ID: types.StringValue(orgGroup.Group.ID), + Name: types.StringValue(orgGroup.Group.Name), + Description: types.StringValue(orgGroup.Group.Description), + Role: types.StringValue(orgGroup.Group.Role.Name), + UserNames: types.ListValueMust(types.StringType, userNames), + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 34b186cf..c0bc19f3 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -63,6 +63,7 @@ func (p *cloudavenueProvider) DataSources(_ context.Context) []func() datasource vapp.NewVappDataSource, catalog.NewCatalogDataSource, org.NewOrgUserDataSource, + org.NewOrgGroupDataSource, catalog.NewCatalogsDataSource, } } diff --git a/internal/tests/org_group_datasource_test.go b/internal/tests/org_group_datasource_test.go new file mode 100644 index 00000000..fd183318 --- /dev/null +++ b/internal/tests/org_group_datasource_test.go @@ -0,0 +1,42 @@ +package tests + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +//go:generate go run github.com/FrangipaneTeam/tf-doc-extractor@latest -filename $GOFILE -example-dir ../../examples -test +const testAccOrgGroupDataSourceConfig = ` +resource "cloudavenue_org_group" "example" { + name = "OrgTest" + role = "Organization Administrator" + description = "org test from go test" +} + +data "cloudavenue_org_group" "example" { + name = cloudavenue_org_group.example.name +} +` + +func TestAccOrgGroupDataSource(t *testing.T) { + resourceName := "data.cloudavenue_org_group.example" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + Config: testAccOrgGroupDataSourceConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "name", "OrgTest"), + resource.TestCheckResourceAttr(resourceName, "role", "Organization Administrator"), + resource.TestCheckResourceAttr(resourceName, "description", "org test from go test"), + resource.TestCheckResourceAttr(resourceName, "user_names.#", "0"), + ), + }, + }, + }) +}