Skip to content

Commit

Permalink
feat: add new function to delete reclamation instances using CRN (#914)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vipin654 authored Jan 27, 2025
1 parent 838f9d6 commit 8c35ed6
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 7 deletions.
8 changes: 4 additions & 4 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "go.sum|package-lock.json|^.secrets.baseline$",
"lines": null
},
"generated_at": "2025-01-24T15:40:02Z",
"generated_at": "2025-01-24T16:21:04Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -128,23 +128,23 @@
"hashed_secret": "892bd503fb45f6fcafb1c7003d88291fc0b20208",
"is_secret": false,
"is_verified": false,
"line_number": 284,
"line_number": 291,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "5da5a31d49370df43eff521b39c10db1466fae44",
"is_secret": false,
"is_verified": false,
"line_number": 287,
"line_number": 294,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "d4c3d66fd0c38547a3c7a4c6bdc29c36911bc030",
"is_secret": false,
"is_verified": false,
"line_number": 488,
"line_number": 495,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down
54 changes: 53 additions & 1 deletion cloudinfo/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,25 @@ func (mock *iamPolicyServiceMock) DeletePolicy(deletePolicyOptions *iampolicyman
// RESOURCE CONTROLLER SERVICE MOCK
type resourceControllerServiceMock struct {
mock.Mock
mockResourceList *resourcecontrollerv2.ResourceInstancesList
mockResourceList *resourcecontrollerv2.ResourceInstancesList
mockReclamationList *resourcecontrollerv2.ReclamationsList
mockReclamation *resourcecontrollerv2.Reclamation
}

func (mock *resourceControllerServiceMock) NewListResourceInstancesOptions() *resourcecontrollerv2.ListResourceInstancesOptions {
return &resourcecontrollerv2.ListResourceInstancesOptions{}
}

func (mock *resourceControllerServiceMock) NewListReclamationsOptions() *resourcecontrollerv2.ListReclamationsOptions {

return &resourcecontrollerv2.ListReclamationsOptions{}
}

func (mock *resourceControllerServiceMock) NewRunReclamationActionOptions(id string, action string) *resourcecontrollerv2.RunReclamationActionOptions {

return &resourcecontrollerv2.RunReclamationActionOptions{ID: core.StringPtr(id), ActionName: core.StringPtr(action)}
}

func (mock *resourceControllerServiceMock) ListResourceInstances(options *resourcecontrollerv2.ListResourceInstancesOptions) (*resourcecontrollerv2.ResourceInstancesList, *core.DetailedResponse, error) {
var retList *resourcecontrollerv2.ResourceInstancesList
var mockCount int64 = 0
Expand All @@ -146,6 +158,46 @@ func (mock *resourceControllerServiceMock) ListResourceInstances(options *resour
return retList, nil, nil
}

func (mock *resourceControllerServiceMock) ListReclamations(options *resourcecontrollerv2.ListReclamationsOptions) (*resourcecontrollerv2.ReclamationsList, *core.DetailedResponse, error) {

var recList *resourcecontrollerv2.ReclamationsList
var mockID string = "mock-reclamation-id"
mockReclamation := resourcecontrollerv2.Reclamation{ID: &mockID}
mockReclamationList := []resourcecontrollerv2.Reclamation{mockReclamation}

if options.ResourceInstanceID != nil && *options.ResourceInstanceID == "ERROR" {
return nil, nil, errors.New("mock Resource is error")
}

if mock.mockReclamationList == nil {

recList = &resourcecontrollerv2.ReclamationsList{

Resources: mockReclamationList,
}
} else {
recList = mock.mockReclamationList
}

return recList, nil, nil
}

func (mock *resourceControllerServiceMock) RunReclamationAction(options *resourcecontrollerv2.RunReclamationActionOptions) (*resourcecontrollerv2.Reclamation, *core.DetailedResponse, error) {

var reclamation *resourcecontrollerv2.Reclamation
var mockID string = "mock-reclamation-id"
mockReclamation := resourcecontrollerv2.Reclamation{ID: &mockID}

if mock.mockReclamation == nil {

reclamation = &mockReclamation
} else {
reclamation = mock.mockReclamation
}

return reclamation, nil, nil
}

// Resource Manager mock
type resourceManagerServiceMock struct {
mockResourceGroupList *resourcemanagerv2.ResourceGroupList
Expand Down
78 changes: 77 additions & 1 deletion cloudinfo/resourcecontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package cloudinfo

import (
"fmt"
bluemix_crn "github.com/IBM-Cloud/bluemix-go/crn"
"strings"

bluemix_crn "github.com/IBM-Cloud/bluemix-go/crn"

"github.com/IBM/go-sdk-core/v5/core"
"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
)
Expand Down Expand Up @@ -66,6 +67,81 @@ func (infoSvc *CloudInfoService) ListResourcesByGroupID(resourceGroupId string)
return allResources, nil
}

func (infoSvc *CloudInfoService) GetReclamationIdFromCRN(CRN string) (string, error) {

parsed_crn := strings.Split(CRN, ":")

if len(parsed_crn) < 8 {

return "", fmt.Errorf("invalid crn, instance guid is not present")
}
resourceInstanceID := parsed_crn[7]

listReclamationsOptions := infoSvc.resourceControllerService.NewListReclamationsOptions()
listReclamationsOptions = listReclamationsOptions.SetResourceInstanceID(resourceInstanceID)
reclamationsList, _, err := infoSvc.resourceControllerService.ListReclamations(listReclamationsOptions)
if err != nil {

return "", err
}

if len(reclamationsList.Resources) == 0 {

return "", nil

}

reclamationID := *reclamationsList.Resources[0].ID

fmt.Println("reclamation id is ", reclamationID)
return reclamationID, nil
}

func (infoSvc *CloudInfoService) DeleteInstanceFromReclamationId(reclamationID string) error {

fmt.Println("Deleting the instance using reclamation id")

runReclamationActionOptions := infoSvc.resourceControllerService.NewRunReclamationActionOptions(
reclamationID,
"reclaim",
)

_, _, err := infoSvc.resourceControllerService.RunReclamationAction(runReclamationActionOptions)
if err != nil {

return err
}

fmt.Println("Instance reclaimed successfully")

return nil
}

func (infoSvc *CloudInfoService) DeleteInstanceFromReclamationByCRN(CRN string) error {

reclamationID, err := infoSvc.GetReclamationIdFromCRN(CRN)

if err != nil {

return err
}

if reclamationID == "" {

fmt.Println("No reclamation found for the given CRN")
return nil
}

err = infoSvc.DeleteInstanceFromReclamationId(reclamationID)

if err != nil {
return err
}

return nil

}

// listResourceInstances will retrieve all resources of a given type for an account
func listResourceInstances(infoSvc *CloudInfoService, options *resourcecontrollerv2.ListResourceInstancesOptions) ([]resourcecontrollerv2.ResourceInstance, error) {
// this API is paginated, but there is no pager support in the library at this time.
Expand Down
37 changes: 36 additions & 1 deletion cloudinfo/resourcecontroller_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package cloudinfo

import (
"github.com/IBM/platform-services-go-sdk/resourcemanagerv2"
"testing"

"github.com/IBM/platform-services-go-sdk/resourcemanagerv2"

"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -158,3 +159,37 @@ func TestListResourcesByGroupName(t *testing.T) {
assert.Equal(t, len(twoTotalList), 2)
})
}

func TestGetReclamationIDFromCrn(t *testing.T) {

infoSvc := CloudInfoService{
resourceControllerService: &resourceControllerServiceMock{},
}

var CRN string = "crn:v1:bluemix:public:my-service:theregion:a/accountnum:guid::"

_, err := infoSvc.GetReclamationIdFromCRN(CRN)
assert.Nil(t, err)

}

func TestDeleteInstanceFromReclamation(t *testing.T) {

infoSvc := CloudInfoService{
resourceControllerService: &resourceControllerServiceMock{},
}

err := infoSvc.DeleteInstanceFromReclamationId("abc")
assert.Nil(t, err)

}

func TestDeleteInstanceFromReclamationByCrn(t *testing.T) {

infoSvc := CloudInfoService{
resourceControllerService: &resourceControllerServiceMock{},
}

err := infoSvc.DeleteInstanceFromReclamationByCRN("crn:v1:bluemix:public:my-service:theregion:a/accountnum:guid::")
assert.Nil(t, err)
}
7 changes: 7 additions & 0 deletions cloudinfo/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ type CloudInfoServiceI interface {
GetSchematicsJobFileData(jobID string, fileType string, location string) (*schematics.JobFileData, error)
GetSchematicsJobPlanJson(jobID string, location string) (string, error)
GetSchematicsServiceByLocation(location string) (schematicsService, error)
GetReclamationIdFromCRN(CRN string) (string, error)
DeleteInstanceFromReclamationId(reclamationID string) error
DeleteInstanceFromReclamationByCRN(CRN string) error
}

// CloudInfoServiceOptions structure used as input params for service constructor.
Expand Down Expand Up @@ -144,7 +147,11 @@ type iamPolicyService interface {
// resourceControllerService for external Resource Controller V2 Service API. Used for mocking.
type resourceControllerService interface {
NewListResourceInstancesOptions() *resourcecontrollerv2.ListResourceInstancesOptions
NewListReclamationsOptions() *resourcecontrollerv2.ListReclamationsOptions
NewRunReclamationActionOptions(string, string) *resourcecontrollerv2.RunReclamationActionOptions
ListReclamations(*resourcecontrollerv2.ListReclamationsOptions) (*resourcecontrollerv2.ReclamationsList, *core.DetailedResponse, error)
ListResourceInstances(*resourcecontrollerv2.ListResourceInstancesOptions) (*resourcecontrollerv2.ResourceInstancesList, *core.DetailedResponse, error)
RunReclamationAction(*resourcecontrollerv2.RunReclamationActionOptions) (*resourcecontrollerv2.Reclamation, *core.DetailedResponse, error)
}

// resourceManagerService for external Resource Manager V2 Service API. Used for mocking.
Expand Down

0 comments on commit 8c35ed6

Please sign in to comment.