Skip to content

Commit

Permalink
fix(lh-87215): allow deletion of MSP-managed tenants (#147)
Browse files Browse the repository at this point in the history
This is a faux deletion, as described in the documentation. It removes the tenant from the MSP
portal, but doesn't actually delete it from the database.
  • Loading branch information
siddhuwarrier authored Oct 30, 2024
1 parent bf6e271 commit 1022180
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 9 deletions.
4 changes: 4 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ func (c *Client) ReadMspManagedTenantByUid(ctx context.Context, readByUidInput t
return tenants.ReadByUid(ctx, c.client, readByUidInput)
}

func (c *Client) DeleteMspManagedTenantByUid(ctx context.Context, deleteByUidInput tenants.DeleteByUidInput) (interface{}, error) {
return tenants.DeleteByUid(ctx, c.client, deleteByUidInput)
}

func (c *Client) FindMspManagedTenantByName(ctx context.Context, readByNameInput tenants.ReadByNameInput) (*tenants.MspTenantsOutput, error) {
return tenants.ReadByName(ctx, c.client, readByNameInput)
}
Expand Down
2 changes: 1 addition & 1 deletion client/internal/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func CreateMspManagedTenant(baseUrl string) string {
return fmt.Sprintf("%s/api/rest/v1/msp/tenants/create", baseUrl)
}

func ReadMspManagedTenantByUid(baseUrl string, tenantUid string) string {
func MspManagedTenantByUid(baseUrl string, tenantUid string) string {
return fmt.Sprintf("%s/api/rest/v1/msp/tenants/%s", baseUrl, tenantUid)
}

Expand Down
17 changes: 17 additions & 0 deletions client/msp/tenants/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package tenants

import (
"context"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
)

func DeleteByUid(ctx context.Context, client http.Client, deleteInp DeleteByUidInput) (interface{}, error) {
client.Logger.Println("Removing tenant by UID from the MSP portal " + deleteInp.Uid)
deleteUrl := url.MspManagedTenantByUid(client.BaseUrl(), deleteInp.Uid)
if err := client.NewDelete(ctx, deleteUrl).Send(&DeleteOutput{}); err != nil {
return nil, err
}

return nil, nil
}
50 changes: 50 additions & 0 deletions client/msp/tenants/delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package tenants_test

import (
"context"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/msp/tenants"
"github.com/google/uuid"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
netHttp "net/http"
"testing"
"time"
)

func TestDelete(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

t.Run("successfully delete tenant", func(t *testing.T) {
httpmock.Reset()
var tenantUid = uuid.New().String()
var deleteInput = tenants.DeleteByUidInput{
Uid: tenantUid,
}
httpmock.RegisterResponder(
netHttp.MethodDelete,
"/api/rest/v1/msp/tenants/"+tenantUid,
httpmock.NewJsonResponderOrPanic(204, nil),
)
response, err := tenants.DeleteByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), deleteInput)
assert.Nil(t, response)
assert.Nil(t, err)
})

t.Run("send through error if deletion failed", func(t *testing.T) {
httpmock.Reset()
var tenantUid = uuid.New().String()
var deleteInput = tenants.DeleteByUidInput{
Uid: tenantUid,
}
httpmock.RegisterResponder(
netHttp.MethodDelete,
"/api/rest/v1/msp/tenants/"+tenantUid,
httpmock.NewJsonResponderOrPanic(500, "Not found"),
)
response, err := tenants.DeleteByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), deleteInput)
assert.Nil(t, response)
assert.NotNil(t, err)
})
}
7 changes: 7 additions & 0 deletions client/msp/tenants/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ type ReadByUidInput struct {
type ReadByNameInput struct {
Name string `json:"name"`
}

type DeleteByUidInput struct {
Uid string `json:"uid"`
}

type DeleteOutput struct {
}
2 changes: 1 addition & 1 deletion client/msp/tenants/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func ReadByUid(ctx context.Context, client http.Client, readInp ReadByUidInput) (*MspTenantOutput, error) {
client.Logger.Println("reading tenant by UID " + readInp.Uid)

readUrl := url.ReadMspManagedTenantByUid(client.BaseUrl(), readInp.Uid)
readUrl := url.MspManagedTenantByUid(client.BaseUrl(), readInp.Uid)
req := client.NewGet(ctx, readUrl)

var outp MspTenantOutput
Expand Down
2 changes: 1 addition & 1 deletion client/msp/users/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Delete(ctx context.Context, client http.Client, deleteInp MspDeleteUsersInp
return nil, err
}

transaction, err = publicapi.WaitForTransactionToFinishWithDefaults(
_, err = publicapi.WaitForTransactionToFinishWithDefaults(
ctx,
client,
transaction,
Expand Down
4 changes: 2 additions & 2 deletions docs/resources/msp_managed_tenant.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "cdo_msp_managed_tenant Resource - cdo"
subcategory: ""
description: |-
Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.
Provides an MSP managed tenant resource. This allows MSP managed tenants to be created. Note: deleting this resource removes the created tenant from the MSP portal by disassociating the tenant from the MSP portal, but the tenant will continue to exist. To completely delete a tenant, please contact Cisco TAC.
---

# cdo_msp_managed_tenant (Resource)

Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.
Provides an MSP managed tenant resource. This allows MSP managed tenants to be created. Note: deleting this resource removes the created tenant from the MSP portal by disassociating the tenant from the MSP portal, but the tenant will continue to exist. To completely delete a tenant, please contact Cisco TAC.



Expand Down
21 changes: 17 additions & 4 deletions provider/internal/msp/msp_tenant/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (*TenantResource) Metadata(ctx context.Context, request resource.MetadataRe

func (*TenantResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) {
response.Schema = schema.Schema{
MarkdownDescription: "Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.",
MarkdownDescription: "Provides an MSP managed tenant resource. This allows MSP managed tenants to be created. Note: deleting this resource removes the created tenant from the MSP portal by disassociating the tenant from the MSP portal, but the tenant will continue to exist. To completely delete a tenant, please contact Cisco TAC.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "Universally unique identifier of the tenant",
Expand Down Expand Up @@ -62,7 +62,7 @@ func (*TenantResource) Schema(ctx context.Context, request resource.SchemaReques
}
}

func (resource *TenantResource) Configure(ctx context.Context, req resource.ConfigureRequest, res *resource.ConfigureResponse) {
func (t *TenantResource) Configure(ctx context.Context, req resource.ConfigureRequest, res *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
Expand All @@ -78,7 +78,7 @@ func (resource *TenantResource) Configure(ctx context.Context, req resource.Conf
return
}

resource.client = client
t.client = client
}

func (t *TenantResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
Expand Down Expand Up @@ -150,7 +150,20 @@ func (t *TenantResource) Update(ctx context.Context, request resource.UpdateRequ
}

func (t *TenantResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
response.Diagnostics.AddError("Cannot delete a created tenant", "Please reach out to CDO TAC if you really want to delete a CDO tenant. You can choose to manually remove the tenant from the Terraform state if you want to remove the tenant from your Terraform configuration.")
tflog.Debug(ctx, "'Deleting' a CDO tenant by removing it from the MSP portal...")
var stateData *TenantResourceModel
response.Diagnostics.Append(request.State.Get(ctx, &stateData)...)
if response.Diagnostics.HasError() {
return
}

deleteInp := tenants.DeleteByUidInput{
Uid: stateData.Id.ValueString(),
}
_, err := t.client.DeleteMspManagedTenantByUid(ctx, deleteInp)
if err != nil {
response.Diagnostics.AddError("failed to delete tenant from MSP portal", err.Error())
}
}

type PreventUpdatePlanModifier struct{}
Expand Down

0 comments on commit 1022180

Please sign in to comment.