Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lh-87215): allow deletion of MSP-managed tenants #147

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading