From c9bab2c18159a8ec05dcccd0a540fbdc830679a5 Mon Sep 17 00:00:00 2001 From: grace-rehn Date: Fri, 22 Nov 2024 13:03:15 +1000 Subject: [PATCH] feat: Add ability to disable tenants (#820) * feat: Add ability to disable tenants * chore: fix doc changes * fix: wrong schema attr * fix: add UseStateForUnknown to is_disabled field * chore: update resource tenant tests --- docs/data-sources/tenants.md | 2 ++ docs/resources/tenant.md | 1 + octopusdeploy_framework/datasource_tenants.go | 1 + octopusdeploy_framework/resource_tenant.go | 2 ++ .../resource_tenant_test.go | 12 +++++--- octopusdeploy_framework/schemas/tenant.go | 29 ++++++++++++++++--- 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/docs/data-sources/tenants.md b/docs/data-sources/tenants.md index c95b3b896..40b737117 100644 --- a/docs/data-sources/tenants.md +++ b/docs/data-sources/tenants.md @@ -20,6 +20,7 @@ Provides information about existing tenants. - `cloned_from_tenant_id` (String) A filter to search for a cloned tenant by its ID. - `ids` (List of String) A filter to search by a list of IDs. - `is_clone` (Boolean) A filter to search for cloned resources. +- `is_disabled` (Boolean) A filter to search by the disabled status of a resource. - `name` (String) A filter to search by name. - `partial_name` (String) A filter to search by a partial name. - `project_id` (String) A filter to search by a project ID. @@ -41,6 +42,7 @@ Read-Only: - `cloned_from_tenant_id` (String) The ID of the tenant from which this tenant was cloned. - `description` (String) The description of this tenants. - `id` (String) The unique ID for this resource. +- `is_disabled` (Boolean) The disabled status of this tenant. - `name` (String) The name of this resource. - `space_id` (String) The space ID associated with this tenant. - `tenant_tags` (Set of String) A list of tenant tags associated with this resource. diff --git a/docs/resources/tenant.md b/docs/resources/tenant.md index 02fb8feb7..733859606 100644 --- a/docs/resources/tenant.md +++ b/docs/resources/tenant.md @@ -20,6 +20,7 @@ This resource manages tenants in Octopus Deploy. - `cloned_from_tenant_id` (String) The ID of the tenant from which this tenant was cloned. - `description` (String) The description of this tenant. +- `is_disabled` (Boolean) The disabled status of this tenant. - `space_id` (String) The space ID associated with this tenant. - `tenant_tags` (Set of String) A list of tenant tags associated with this resource. diff --git a/octopusdeploy_framework/datasource_tenants.go b/octopusdeploy_framework/datasource_tenants.go index d7bcf71da..ec8cf6e1f 100644 --- a/octopusdeploy_framework/datasource_tenants.go +++ b/octopusdeploy_framework/datasource_tenants.go @@ -42,6 +42,7 @@ func (b *tenantsDataSource) Read(ctx context.Context, req datasource.ReadRequest ClonedFromTenantID: data.ClonedFromTenantId.ValueString(), IDs: util.ExpandStringList(data.IDs), IsClone: data.IsClone.ValueBool(), + IsDisabled: data.IsDisabled.ValueBool(), Name: data.Name.ValueString(), PartialName: data.PartialName.ValueString(), ProjectID: data.ProjectId.ValueString(), diff --git a/octopusdeploy_framework/resource_tenant.go b/octopusdeploy_framework/resource_tenant.go index 3fa5c5103..73bfc5c42 100644 --- a/octopusdeploy_framework/resource_tenant.go +++ b/octopusdeploy_framework/resource_tenant.go @@ -151,6 +151,7 @@ func mapStateToTenant(ctx context.Context, data *schemas.TenantModel) (*tenants. tenant.ID = data.ID.ValueString() tenant.ClonedFromTenantID = data.ClonedFromTenantId.ValueString() tenant.Description = data.Description.ValueString() + tenant.IsDisabled = data.IsDisabled.ValueBool() tenant.SpaceID = data.SpaceID.ValueString() convertedTenantTags, diags := util.SetToStringArray(ctx, data.TenantTags) @@ -167,6 +168,7 @@ func mapTenantToState(ctx context.Context, data *schemas.TenantModel, tenant *te data.ID = types.StringValue(tenant.ID) data.ClonedFromTenantId = types.StringValue(tenant.ClonedFromTenantID) data.Description = types.StringValue(tenant.Description) + data.IsDisabled = types.BoolValue(tenant.IsDisabled) data.SpaceID = types.StringValue(tenant.SpaceID) data.Name = types.StringValue(tenant.Name) diff --git a/octopusdeploy_framework/resource_tenant_test.go b/octopusdeploy_framework/resource_tenant_test.go index 3d99614c5..5d2f1ca34 100644 --- a/octopusdeploy_framework/resource_tenant_test.go +++ b/octopusdeploy_framework/resource_tenant_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "path/filepath" + "strconv" "testing" "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/tenants" @@ -41,22 +42,24 @@ func TestAccTenantBasic(t *testing.T) { testTenantExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "description", description), + resource.TestCheckResourceAttr(resourceName, "is_disabled", strconv.FormatBool(false)), ), - Config: testAccTenantBasic(lifecycleLocalName, lifecycleName, projectGroupLocalName, projectGroupName, projectLocalName, projectName, projectDescription, environmentLocalName, environmentName, localName, name, description), + Config: testAccTenantBasic(lifecycleLocalName, lifecycleName, projectGroupLocalName, projectGroupName, projectLocalName, projectName, projectDescription, environmentLocalName, environmentName, localName, name, description, false), }, { Check: resource.ComposeTestCheckFunc( testTenantExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "description", newDescription), + resource.TestCheckResourceAttr(resourceName, "is_disabled", strconv.FormatBool(true)), ), - Config: testAccTenantBasic(lifecycleLocalName, lifecycleName, projectGroupLocalName, projectGroupName, projectLocalName, projectName, projectDescription, environmentLocalName, environmentName, localName, name, newDescription), + Config: testAccTenantBasic(lifecycleLocalName, lifecycleName, projectGroupLocalName, projectGroupName, projectLocalName, projectName, projectDescription, environmentLocalName, environmentName, localName, name, newDescription, true), }, }, }) } -func testAccTenantBasic(lifecycleLocalName string, lifecycleName string, projectGroupLocalName string, projectGroupName string, projectLocalName string, projectName string, projectDescription string, environmentLocalName string, environmentName string, localName string, name string, description string) string { +func testAccTenantBasic(lifecycleLocalName string, lifecycleName string, projectGroupLocalName string, projectGroupName string, projectLocalName string, projectName string, projectDescription string, environmentLocalName string, environmentName string, localName string, name string, description string, isDisabled bool) string { allowDynamicInfrastructure := false environmentDescription := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) sortOrder := acctest.RandIntRange(0, 10) @@ -67,13 +70,14 @@ func testAccTenantBasic(lifecycleLocalName string, lifecycleName string, project resource "octopusdeploy_tenant" "%s" { description = "%s" name = "%s" + is_disabled = %v } resource "octopusdeploy_tenant_project" "project_environment" { tenant_id = octopusdeploy_tenant.%s.id project_id = "${octopusdeploy_project.%s.id}" environment_ids = ["${octopusdeploy_environment.%s.id}"] - }`, localName, description, name, localName, projectLocalName, environmentLocalName) + }`, localName, description, name, isDisabled, localName, projectLocalName, environmentLocalName) } func testTenantExists(prefix string) resource.TestCheckFunc { diff --git a/octopusdeploy_framework/schemas/tenant.go b/octopusdeploy_framework/schemas/tenant.go index 5b0c9f695..f0cc07bcb 100644 --- a/octopusdeploy_framework/schemas/tenant.go +++ b/octopusdeploy_framework/schemas/tenant.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" datasourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" @@ -14,6 +15,7 @@ import ( type TenantModel struct { ClonedFromTenantId types.String `tfsdk:"cloned_from_tenant_id"` Description types.String `tfsdk:"description"` + IsDisabled types.Bool `tfsdk:"is_disabled"` Name types.String `tfsdk:"name"` SpaceID types.String `tfsdk:"space_id"` TenantTags types.Set `tfsdk:"tenant_tags"` @@ -26,6 +28,7 @@ type TenantsModel struct { ID types.String `tfsdk:"id"` IDs types.List `tfsdk:"ids"` IsClone types.Bool `tfsdk:"is_clone"` + IsDisabled types.Bool `tfsdk:"is_disabled"` Name types.String `tfsdk:"name"` PartialName types.String `tfsdk:"partial_name"` ProjectId types.String `tfsdk:"project_id"` @@ -45,6 +48,7 @@ func TenantObjectType() map[string]attr.Type { "cloned_from_tenant_id": types.StringType, "description": types.StringType, "id": types.StringType, + "is_disabled": types.BoolType, "name": types.StringType, "space_id": types.StringType, "tenant_tags": types.SetType{ElemType: types.StringType}, @@ -62,6 +66,7 @@ func FlattenTenant(tenant *tenants.Tenant) attr.Value { "cloned_from_tenant_id": types.StringValue(tenant.ClonedFromTenantID), "description": types.StringValue(tenant.Description), "id": types.StringValue(tenant.GetID()), + "is_disabled": types.BoolValue(tenant.IsDisabled), "name": types.StringValue(tenant.Name), "space_id": types.StringValue(tenant.SpaceID), "tenant_tags": tenantTagsSet, @@ -82,6 +87,10 @@ func (t TenantSchema) GetDatasourceSchema() datasourceSchema.Schema { Description: "A filter to search for cloned resources.", Optional: true, }, + "is_disabled": datasourceSchema.BoolAttribute{ + Description: "A filter to search by the disabled status of a resource.", + Optional: true, + }, "name": datasourceSchema.StringAttribute{ Description: "A filter to search by name.", Optional: true, @@ -106,8 +115,12 @@ func (t TenantSchema) GetDatasourceSchema() datasourceSchema.Schema { }, "description": GetDescriptionDatasourceSchema("tenants"), "id": GetIdDatasourceSchema(true), - "name": GetReadonlyNameDatasourceSchema(), - "space_id": GetSpaceIdDatasourceSchema("tenant", true), + "is_disabled": datasourceSchema.BoolAttribute{ + Description: "The disabled status of this tenant.", + Computed: true, + }, + "name": GetReadonlyNameDatasourceSchema(), + "space_id": GetSpaceIdDatasourceSchema("tenant", true), "tenant_tags": datasourceSchema.SetAttribute{ Computed: true, Description: "A list of tenant tags associated with this resource.", @@ -132,8 +145,16 @@ func (t TenantSchema) GetResourceSchema() resourceSchema.Schema { }, "description": GetDescriptionResourceSchema("tenant"), "id": GetIdResourceSchema(), - "name": GetNameResourceSchema(true), - "space_id": GetSpaceIdResourceSchema("tenant"), + "is_disabled": resourceSchema.BoolAttribute{ + Description: "The disabled status of this tenant.", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.UseStateForUnknown(), + }, + }, + "name": GetNameResourceSchema(true), + "space_id": GetSpaceIdResourceSchema("tenant"), "tenant_tags": resourceSchema.SetAttribute{ Description: "A list of tenant tags associated with this resource.", ElementType: types.StringType,