Skip to content

Commit b46ff01

Browse files
committed
Add Bulk Delete & Detach Volume
- Add bulk volume delete - Add bulk volume detach - Add example for bulk delete and detach
1 parent 3460ff2 commit b46ff01

File tree

4 files changed

+339
-0
lines changed

4 files changed

+339
-0
lines changed

clients/instance/ibm-pi-volume.go

+32
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,35 @@ func (f *IBMPIVolumeClient) GetVolumeFlashCopyMappings(id string) (models.FlashC
254254
}
255255
return resp.Payload, nil
256256
}
257+
258+
// Bulk volume detach
259+
func (f *IBMPIVolumeClient) BulkVolumeDetach(pvmID string, body *models.VolumesDetach) (*models.VolumesDetachmentResponse, error) {
260+
params := p_cloud_volumes.NewPcloudV2PvminstancesVolumesDeleteParams().
261+
WithContext(f.ctx).WithTimeout(helpers.PIDeleteTimeOut).WithCloudInstanceID(f.cloudInstanceID).WithPvmInstanceID(pvmID).
262+
WithBody(body)
263+
resp, err := f.session.Power.PCloudVolumes.PcloudV2PvminstancesVolumesDelete(params, f.session.AuthInfo(f.cloudInstanceID))
264+
if err != nil {
265+
return nil, ibmpisession.SDKFailWithAPIError(err, fmt.Errorf(errors.DetachVolumesOperationFailed, pvmID, f.cloudInstanceID, err))
266+
}
267+
if resp == nil || resp.Payload == nil {
268+
return nil, fmt.Errorf("failed detaching volumes for %s", pvmID)
269+
}
270+
return resp.Payload, nil
271+
}
272+
273+
// Bulk volume delete
274+
func (f *IBMPIVolumeClient) BulkVolumeDelete(body *models.VolumesDelete) (*models.VolumesDeleteResponse, error) {
275+
params := p_cloud_volumes.NewPcloudV2VolumesDeleteParams().WithContext(f.ctx).WithTimeout(helpers.PIDeleteTimeOut).
276+
WithCloudInstanceID(f.cloudInstanceID).WithBody(body)
277+
acceptedRes, partialResp, err := f.session.Power.PCloudVolumes.PcloudV2VolumesDelete(params, f.session.AuthInfo(f.cloudInstanceID))
278+
if err != nil {
279+
return nil, ibmpisession.SDKFailWithAPIError(err, fmt.Errorf(errors.DeleteVolumeOperationFailed, body.VolumeIDs, err))
280+
}
281+
if acceptedRes.Code() == 202 {
282+
return nil, nil
283+
}
284+
if partialResp == nil || partialResp.Payload == nil {
285+
return nil, fmt.Errorf("failed Deleting volumes : %s", body.VolumeIDs)
286+
}
287+
return partialResp.Payload, nil
288+
}

errors/errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const AttachVolumeOperationFailed = "failed to perform the Attach volume Operati
7070
const DetachVolumeOperationFailed = "failed to perform the Detach volume Operation for volume %s with error %w"
7171
const GetVolumeRemoteCopyRelationshipsOperationFailed = "failed to Get remote copy relationships of a volume %s for the cloud instance %s with error %w"
7272
const GetVolumeFlashCopyMappingOperationFailed = "failed to Get flash copy mapping of a volume %s for the cloud instance %s with error %w"
73+
const DetachVolumesOperationFailed = "failed to perfome the Detach volumes Operation V2 for pvminstance %s in cloud instance %s with error %w"
7374

7475
// start of volume onboarding
7576
const GetVolumeOnboardingOperationFailed = "failed to perform the Get Volume Onboarding Operation for volume-onboarding ID:%s for the cloud instance %s with error %w"

examples/bulk-volume-delete/main.go

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"math/rand"
8+
"time"
9+
10+
v "github.com/IBM-Cloud/power-go-client/clients/instance"
11+
ps "github.com/IBM-Cloud/power-go-client/ibmpisession"
12+
"github.com/IBM-Cloud/power-go-client/power/models"
13+
"github.com/IBM/go-sdk-core/v5/core"
14+
)
15+
16+
func main() {
17+
//session Inputs
18+
// < IAM TOKEN >
19+
// token := ""
20+
region := ""
21+
zone := ""
22+
accountID := ""
23+
url := region + ".power-iaas.test.cloud.ibm.com"
24+
25+
// volume inputs
26+
rand.Seed(time.Now().UnixNano())
27+
randomNumber := rand.Intn(100) + 1
28+
randomNumber2 := rand.Intn(100) + 1
29+
piID := ""
30+
name := fmt.Sprintf("power-go-test-volume-%d", randomNumber)
31+
name2 := fmt.Sprintf("power-go-test-volume-%d", randomNumber2)
32+
size := 20.0
33+
vtype := "tier3"
34+
sharable := true
35+
replicationEnabled := false
36+
37+
// authenticator := &core.BearerTokenAuthenticator{
38+
// BearerToken: token,
39+
// }
40+
authenticator := &core.IamAuthenticator{
41+
ApiKey: "",
42+
// Uncomment for test environment
43+
URL: "https://iam.test.cloud.ibm.com",
44+
}
45+
// Create the session
46+
options := &ps.IBMPIOptions{
47+
Authenticator: authenticator,
48+
UserAccount: accountID,
49+
Zone: zone,
50+
URL: url,
51+
Debug: true,
52+
}
53+
session, err := ps.NewIBMPISession(options)
54+
if err != nil {
55+
log.Fatal(err)
56+
}
57+
powerClientVolume := v.NewIBMPIVolumeClient(context.Background(), session, piID)
58+
if err != nil {
59+
log.Fatal(err)
60+
}
61+
bodyVolume := &models.CreateDataVolume{
62+
Name: &name,
63+
Size: &size,
64+
DiskType: vtype,
65+
Shareable: &sharable,
66+
ReplicationEnabled: &replicationEnabled,
67+
}
68+
bodyVolume2 := &models.CreateDataVolume{
69+
Name: &name2,
70+
Size: &size,
71+
DiskType: vtype,
72+
Shareable: &sharable,
73+
ReplicationEnabled: &replicationEnabled,
74+
}
75+
log.Print("Creating first Volume\n")
76+
createRespOk, err := powerClientVolume.CreateVolume(bodyVolume)
77+
if err != nil {
78+
log.Fatal(err)
79+
}
80+
log.Printf("***************[1]****************** %+v\n", *createRespOk)
81+
82+
volumeID := *createRespOk.VolumeID
83+
getResp, err := powerClientVolume.Get(volumeID)
84+
if err != nil {
85+
log.Fatal(err)
86+
}
87+
log.Printf("***************[2]****************** %+v \n", *getResp)
88+
log.Print("Creating Second Volume\n")
89+
createRespOk2, err := powerClientVolume.CreateVolume(bodyVolume2)
90+
if err != nil {
91+
log.Fatal(err)
92+
}
93+
log.Printf("***************[3]****************** %+v\n", *createRespOk2)
94+
95+
volumeID2 := *createRespOk2.VolumeID
96+
getResp2, err := powerClientVolume.Get(volumeID2)
97+
if err != nil {
98+
log.Fatal(err)
99+
}
100+
log.Printf("***************[4]****************** %+v \n", *getResp2)
101+
time.Sleep(2 * time.Minute)
102+
log.Print("Deleting Volumes\n")
103+
body := &models.VolumesDelete{VolumeIDs: []string{volumeID, volumeID2}}
104+
delResp, err := powerClientVolume.BulkVolumeDelete(body)
105+
if err != nil {
106+
log.Fatal(err)
107+
}
108+
if delResp == nil {
109+
log.Print("***************[5]****************** Deleted\n")
110+
111+
} else {
112+
113+
log.Printf("***************[5]****************** %+v\n", *delResp)
114+
}
115+
116+
}

examples/bulk-volume-detach/main.go

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"math/rand"
8+
"time"
9+
10+
v "github.com/IBM-Cloud/power-go-client/clients/instance"
11+
"github.com/IBM-Cloud/power-go-client/helpers"
12+
ps "github.com/IBM-Cloud/power-go-client/ibmpisession"
13+
"github.com/IBM-Cloud/power-go-client/power/models"
14+
"github.com/IBM/go-sdk-core/v5/core"
15+
)
16+
17+
func main() {
18+
//session Inputs
19+
// < IAM TOKEN >
20+
// token := ""
21+
region := "dal"
22+
zone := "dal10"
23+
accountID := "efe5e8b9d3f04b948790fe5499bd18bc"
24+
url := region + ".power-iaas.test.cloud.ibm.com"
25+
26+
// volume inputs
27+
rand.Seed(time.Now().UnixNano())
28+
randomNumber := rand.Intn(100) + 1
29+
randomNumber2 := rand.Intn(100) + 1
30+
piID := "a1a23e24-220d-4a20-a678-c8c5e84056bd"
31+
name := fmt.Sprintf("power-go-test-volume-%d", randomNumber)
32+
name2 := fmt.Sprintf("power-go-test-volume-%d", randomNumber2)
33+
size := 20.0
34+
vtype := "tier3"
35+
sharable := true
36+
replicationEnabled := false
37+
38+
// VM inputs
39+
serverName := fmt.Sprintf("power-go-test-%d", randomNumber)
40+
imageID := "cd447165-f45d-48f4-b07f-7c9a11ec84c7"
41+
networkID := "f324429e-5716-40c1-a01b-4d36ec8b82e3"
42+
memory := 4.0
43+
processors := 2.0
44+
procType := "shared"
45+
sysType := "s922"
46+
47+
// authenticator := &core.BearerTokenAuthenticator{
48+
// BearerToken: token,
49+
// }
50+
authenticator := &core.IamAuthenticator{
51+
ApiKey: "PaBXQ7QI6AyBm86Bqo0C45o_6LmW9I76csCkWLojdZLQ",
52+
// Uncomment for test environment
53+
URL: "https://iam.test.cloud.ibm.com",
54+
}
55+
// Create the session
56+
options := &ps.IBMPIOptions{
57+
Authenticator: authenticator,
58+
UserAccount: accountID,
59+
Zone: zone,
60+
URL: url,
61+
Debug: true,
62+
}
63+
session, err := ps.NewIBMPISession(options)
64+
if err != nil {
65+
log.Fatal(err)
66+
}
67+
powerClientVolume := v.NewIBMPIVolumeClient(context.Background(), session, piID)
68+
if err != nil {
69+
log.Fatal(err)
70+
}
71+
bodyVolume := &models.CreateDataVolume{
72+
Name: &name,
73+
Size: &size,
74+
DiskType: vtype,
75+
Shareable: &sharable,
76+
ReplicationEnabled: &replicationEnabled,
77+
}
78+
bodyVolume2 := &models.CreateDataVolume{
79+
Name: &name2,
80+
Size: &size,
81+
DiskType: vtype,
82+
Shareable: &sharable,
83+
ReplicationEnabled: &replicationEnabled,
84+
}
85+
log.Print("Creating first Volume\n")
86+
createRespOk, err := powerClientVolume.CreateVolume(bodyVolume)
87+
if err != nil {
88+
log.Fatal(err)
89+
}
90+
log.Printf("***************[1]****************** %+v\n", *createRespOk)
91+
92+
volumeID := *createRespOk.VolumeID
93+
getResp, err := powerClientVolume.Get(volumeID)
94+
if err != nil {
95+
log.Fatal(err)
96+
}
97+
log.Printf("***************[2]****************** %+v \n", *getResp)
98+
log.Print("Creating Second Volume\n")
99+
createRespOk2, err := powerClientVolume.CreateVolume(bodyVolume2)
100+
if err != nil {
101+
log.Fatal(err)
102+
}
103+
log.Printf("***************[3]****************** %+v\n", *createRespOk2)
104+
105+
volumeID2 := *createRespOk2.VolumeID
106+
getResp2, err := powerClientVolume.Get(volumeID)
107+
if err != nil {
108+
log.Fatal(err)
109+
}
110+
log.Printf("***************[4]****************** %+v \n", *getResp2)
111+
112+
powerClientVM := v.NewIBMPIInstanceClient(context.Background(), session, piID)
113+
if err != nil {
114+
log.Fatal(err)
115+
}
116+
bodyVM := &models.PVMInstanceCreate{
117+
ImageID: &imageID,
118+
NetworkIDs: []string{networkID},
119+
ServerName: &serverName,
120+
VolumeIDs: []string{volumeID, volumeID2},
121+
Memory: &memory,
122+
Processors: &processors,
123+
ProcType: &procType,
124+
SysType: sysType,
125+
}
126+
127+
log.Print("Creating VM\n")
128+
createRespOkVM, err := powerClientVM.Create(bodyVM)
129+
if err != nil {
130+
log.Fatal(err)
131+
}
132+
if len(*createRespOkVM) == 0 {
133+
log.Fatal("create response is empty")
134+
}
135+
log.Printf("***************[5]****************** %+v\n", *createRespOk)
136+
137+
insID := ""
138+
for _, in := range *createRespOkVM {
139+
insID = *in.PvmInstanceID
140+
}
141+
if insID == "" {
142+
log.Fatal("instance ID is empty")
143+
}
144+
145+
getRespVM, err := powerClientVM.Get(insID)
146+
if err != nil {
147+
log.Fatal(err)
148+
}
149+
log.Printf("***************[6]****************** %+v \n", *getRespVM)
150+
waitForInstanceAvailable(insID, powerClientVM)
151+
log.Print("Detaching Volumes\n")
152+
detachBody := &models.VolumesDetach{
153+
VolumeIDs: []string{volumeID, volumeID2},
154+
}
155+
156+
createRespOkDetach, err := powerClientVolume.BulkVolumeDetach(insID, detachBody)
157+
if err != nil {
158+
log.Fatal(err)
159+
}
160+
log.Printf("***************[7]****************** %+v\n", *createRespOkDetach)
161+
log.Print("Deleting VM\n")
162+
err = powerClientVM.Delete(insID)
163+
if err != nil {
164+
log.Fatal(err)
165+
}
166+
log.Print("Deleting First Volume\n")
167+
err = powerClientVolume.DeleteVolume(volumeID)
168+
if err != nil {
169+
log.Fatal(err)
170+
}
171+
log.Print("Deleting Second Volume\n")
172+
err = powerClientVolume.DeleteVolume(volumeID2)
173+
if err != nil {
174+
log.Fatal(err)
175+
}
176+
177+
}
178+
179+
func waitForInstanceAvailable(id string, powerClientVM *v.IBMPIInstanceClient) {
180+
for start := time.Now(); time.Since(start) < time.Minute*30; {
181+
time.Sleep(60 * time.Second)
182+
pvm, err := powerClientVM.Get(id)
183+
if err != nil {
184+
log.Fatal(err)
185+
}
186+
if *pvm.Status == helpers.PIInstanceAvailable && pvm.Health.Status == helpers.PIInstanceHealthOk {
187+
break
188+
}
189+
}
190+
}

0 commit comments

Comments
 (0)