Skip to content

Commit 1022180

Browse files
fix(lh-87215): allow deletion of MSP-managed tenants (#147)
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.
1 parent bf6e271 commit 1022180

File tree

9 files changed

+100
-9
lines changed

9 files changed

+100
-9
lines changed

client/client.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ func (c *Client) ReadMspManagedTenantByUid(ctx context.Context, readByUidInput t
284284
return tenants.ReadByUid(ctx, c.client, readByUidInput)
285285
}
286286

287+
func (c *Client) DeleteMspManagedTenantByUid(ctx context.Context, deleteByUidInput tenants.DeleteByUidInput) (interface{}, error) {
288+
return tenants.DeleteByUid(ctx, c.client, deleteByUidInput)
289+
}
290+
287291
func (c *Client) FindMspManagedTenantByName(ctx context.Context, readByNameInput tenants.ReadByNameInput) (*tenants.MspTenantsOutput, error) {
288292
return tenants.ReadByName(ctx, c.client, readByNameInput)
289293
}

client/internal/url/url.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func CreateMspManagedTenant(baseUrl string) string {
210210
return fmt.Sprintf("%s/api/rest/v1/msp/tenants/create", baseUrl)
211211
}
212212

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

client/msp/tenants/delete.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package tenants
2+
3+
import (
4+
"context"
5+
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
6+
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
7+
)
8+
9+
func DeleteByUid(ctx context.Context, client http.Client, deleteInp DeleteByUidInput) (interface{}, error) {
10+
client.Logger.Println("Removing tenant by UID from the MSP portal " + deleteInp.Uid)
11+
deleteUrl := url.MspManagedTenantByUid(client.BaseUrl(), deleteInp.Uid)
12+
if err := client.NewDelete(ctx, deleteUrl).Send(&DeleteOutput{}); err != nil {
13+
return nil, err
14+
}
15+
16+
return nil, nil
17+
}

client/msp/tenants/delete_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package tenants_test
2+
3+
import (
4+
"context"
5+
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
6+
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/msp/tenants"
7+
"github.com/google/uuid"
8+
"github.com/jarcoal/httpmock"
9+
"github.com/stretchr/testify/assert"
10+
netHttp "net/http"
11+
"testing"
12+
"time"
13+
)
14+
15+
func TestDelete(t *testing.T) {
16+
httpmock.Activate()
17+
defer httpmock.DeactivateAndReset()
18+
19+
t.Run("successfully delete tenant", func(t *testing.T) {
20+
httpmock.Reset()
21+
var tenantUid = uuid.New().String()
22+
var deleteInput = tenants.DeleteByUidInput{
23+
Uid: tenantUid,
24+
}
25+
httpmock.RegisterResponder(
26+
netHttp.MethodDelete,
27+
"/api/rest/v1/msp/tenants/"+tenantUid,
28+
httpmock.NewJsonResponderOrPanic(204, nil),
29+
)
30+
response, err := tenants.DeleteByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), deleteInput)
31+
assert.Nil(t, response)
32+
assert.Nil(t, err)
33+
})
34+
35+
t.Run("send through error if deletion failed", func(t *testing.T) {
36+
httpmock.Reset()
37+
var tenantUid = uuid.New().String()
38+
var deleteInput = tenants.DeleteByUidInput{
39+
Uid: tenantUid,
40+
}
41+
httpmock.RegisterResponder(
42+
netHttp.MethodDelete,
43+
"/api/rest/v1/msp/tenants/"+tenantUid,
44+
httpmock.NewJsonResponderOrPanic(500, "Not found"),
45+
)
46+
response, err := tenants.DeleteByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), deleteInput)
47+
assert.Nil(t, response)
48+
assert.NotNil(t, err)
49+
})
50+
}

client/msp/tenants/models.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,10 @@ type ReadByUidInput struct {
2626
type ReadByNameInput struct {
2727
Name string `json:"name"`
2828
}
29+
30+
type DeleteByUidInput struct {
31+
Uid string `json:"uid"`
32+
}
33+
34+
type DeleteOutput struct {
35+
}

client/msp/tenants/read.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
func ReadByUid(ctx context.Context, client http.Client, readInp ReadByUidInput) (*MspTenantOutput, error) {
1010
client.Logger.Println("reading tenant by UID " + readInp.Uid)
1111

12-
readUrl := url.ReadMspManagedTenantByUid(client.BaseUrl(), readInp.Uid)
12+
readUrl := url.MspManagedTenantByUid(client.BaseUrl(), readInp.Uid)
1313
req := client.NewGet(ctx, readUrl)
1414

1515
var outp MspTenantOutput

client/msp/users/delete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func Delete(ctx context.Context, client http.Client, deleteInp MspDeleteUsersInp
2121
return nil, err
2222
}
2323

24-
transaction, err = publicapi.WaitForTransactionToFinishWithDefaults(
24+
_, err = publicapi.WaitForTransactionToFinishWithDefaults(
2525
ctx,
2626
client,
2727
transaction,

docs/resources/msp_managed_tenant.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
page_title: "cdo_msp_managed_tenant Resource - cdo"
44
subcategory: ""
55
description: |-
6-
Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.
6+
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.
77
---
88

99
# cdo_msp_managed_tenant (Resource)
1010

11-
Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.
11+
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.
1212

1313

1414

provider/internal/msp/msp_tenant/resource.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (*TenantResource) Metadata(ctx context.Context, request resource.MetadataRe
2727

2828
func (*TenantResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) {
2929
response.Schema = schema.Schema{
30-
MarkdownDescription: "Provides an MSP managed tenant resource. This allows MSP managed tenants to be created.",
30+
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.",
3131
Attributes: map[string]schema.Attribute{
3232
"id": schema.StringAttribute{
3333
MarkdownDescription: "Universally unique identifier of the tenant",
@@ -62,7 +62,7 @@ func (*TenantResource) Schema(ctx context.Context, request resource.SchemaReques
6262
}
6363
}
6464

65-
func (resource *TenantResource) Configure(ctx context.Context, req resource.ConfigureRequest, res *resource.ConfigureResponse) {
65+
func (t *TenantResource) Configure(ctx context.Context, req resource.ConfigureRequest, res *resource.ConfigureResponse) {
6666
if req.ProviderData == nil {
6767
return
6868
}
@@ -78,7 +78,7 @@ func (resource *TenantResource) Configure(ctx context.Context, req resource.Conf
7878
return
7979
}
8080

81-
resource.client = client
81+
t.client = client
8282
}
8383

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

152152
func (t *TenantResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
153-
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.")
153+
tflog.Debug(ctx, "'Deleting' a CDO tenant by removing it from the MSP portal...")
154+
var stateData *TenantResourceModel
155+
response.Diagnostics.Append(request.State.Get(ctx, &stateData)...)
156+
if response.Diagnostics.HasError() {
157+
return
158+
}
159+
160+
deleteInp := tenants.DeleteByUidInput{
161+
Uid: stateData.Id.ValueString(),
162+
}
163+
_, err := t.client.DeleteMspManagedTenantByUid(ctx, deleteInp)
164+
if err != nil {
165+
response.Diagnostics.AddError("failed to delete tenant from MSP portal", err.Error())
166+
}
154167
}
155168

156169
type PreventUpdatePlanModifier struct{}

0 commit comments

Comments
 (0)