-
Notifications
You must be signed in to change notification settings - Fork 8
/
storage_volume_attachments.go
179 lines (144 loc) · 5.99 KB
/
storage_volume_attachments.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package compute
import (
"time"
"github.com/hashicorp/go-oracle-terraform/client"
)
const WaitForVolumeAttachmentDeleteTimeout = time.Duration(30 * time.Second)
const WaitForVolumeAttachmentReadyTimeout = time.Duration(30 * time.Second)
// StorageAttachmentsClient is a client for the Storage Attachment functions of the Compute API.
type StorageAttachmentsClient struct {
ResourceClient
}
// StorageAttachments obtains a StorageAttachmentsClient which can be used to access to the
// Storage Attachment functions of the Compute API
func (c *ComputeClient) StorageAttachments() *StorageAttachmentsClient {
return &StorageAttachmentsClient{
ResourceClient: ResourceClient{
ComputeClient: c,
ResourceDescription: "storage volume attachment",
ContainerPath: "/storage/attachment/",
ResourceRootPath: "/storage/attachment",
}}
}
type StorageAttachmentState string
const (
Attaching StorageAttachmentState = "attaching"
Attached StorageAttachmentState = "attached"
Detaching StorageAttachmentState = "detaching"
Unavailable StorageAttachmentState = "unavailable"
Unknown StorageAttachmentState = "unknown"
)
// StorageAttachmentInfo describes an existing storage attachment.
type StorageAttachmentInfo struct {
// Name of this attachment, generated by the server.
Name string `json:"name"`
// Index number for the volume. The allowed range is 1-10
// An attachment with index 1 is exposed to the instance as /dev/xvdb, an attachment with index 2 is exposed as /dev/xvdc, and so on.
Index int `json:"index"`
// Multipart name of the instance attached to the storage volume.
InstanceName string `json:"instance_name"`
// Multipart name of the volume attached to the instance.
StorageVolumeName string `json:"storage_volume_name"`
// The State of the Storage Attachment
State StorageAttachmentState `json:"state"`
}
func (c *StorageAttachmentsClient) success(attachmentInfo *StorageAttachmentInfo) (*StorageAttachmentInfo, error) {
c.unqualify(&attachmentInfo.Name, &attachmentInfo.InstanceName, &attachmentInfo.StorageVolumeName)
return attachmentInfo, nil
}
type CreateStorageAttachmentInput struct {
// Index number for the volume. The allowed range is 1-10
// An attachment with index 1 is exposed to the instance as /dev/xvdb, an attachment with index 2 is exposed as /dev/xvdc, and so on.
// Required.
Index int `json:"index"`
// Multipart name of the instance to which you want to attach the volume.
// Required.
InstanceName string `json:"instance_name"`
// Multipart name of the volume that you want to attach.
// Required.
StorageVolumeName string `json:"storage_volume_name"`
// Time to wait for storage volume attachment
Timeout time.Duration `json:"-"`
}
// CreateStorageAttachment creates a storage attachment attaching the given volume to the given instance at the given index.
func (c *StorageAttachmentsClient) CreateStorageAttachment(input *CreateStorageAttachmentInput) (*StorageAttachmentInfo, error) {
input.InstanceName = c.getQualifiedName(input.InstanceName)
input.StorageVolumeName = c.getQualifiedName(input.StorageVolumeName)
var attachmentInfo *StorageAttachmentInfo
if err := c.createResource(&input, &attachmentInfo); err != nil {
return nil, err
}
if input.Timeout == 0 {
input.Timeout = WaitForVolumeAttachmentReadyTimeout
}
return c.waitForStorageAttachmentToFullyAttach(attachmentInfo.Name, input.Timeout)
}
// DeleteStorageAttachmentInput represents the body of an API request to delete a Storage Attachment.
type DeleteStorageAttachmentInput struct {
// The three-part name of the Storage Attachment (/Compute-identity_domain/user/object).
// Required
Name string `json:"name"`
// Time to wait for storage volume snapshot
Timeout time.Duration `json:"-"`
}
// DeleteStorageAttachment deletes the storage attachment with the given name.
func (c *StorageAttachmentsClient) DeleteStorageAttachment(input *DeleteStorageAttachmentInput) error {
if err := c.deleteResource(input.Name); err != nil {
return err
}
if input.Timeout == 0 {
input.Timeout = WaitForVolumeAttachmentDeleteTimeout
}
return c.waitForStorageAttachmentToBeDeleted(input.Name, input.Timeout)
}
// GetStorageAttachmentInput represents the body of an API request to obtain a Storage Attachment.
type GetStorageAttachmentInput struct {
// The three-part name of the Storage Attachment (/Compute-identity_domain/user/object).
// Required
Name string `json:"name"`
}
// GetStorageAttachment retrieves the storage attachment with the given name.
func (c *StorageAttachmentsClient) GetStorageAttachment(input *GetStorageAttachmentInput) (*StorageAttachmentInfo, error) {
var attachmentInfo *StorageAttachmentInfo
if err := c.getResource(input.Name, &attachmentInfo); err != nil {
return nil, err
}
return c.success(attachmentInfo)
}
// waitForStorageAttachmentToFullyAttach waits for the storage attachment with the given name to be fully attached, or times out.
func (c *StorageAttachmentsClient) waitForStorageAttachmentToFullyAttach(name string, timeout time.Duration) (*StorageAttachmentInfo, error) {
var waitResult *StorageAttachmentInfo
err := c.client.WaitFor("storage attachment to be attached", timeout, func() (bool, error) {
input := &GetStorageAttachmentInput{
Name: name,
}
info, err := c.GetStorageAttachment(input)
if err != nil {
return false, err
}
if info != nil {
if info.State == Attached {
waitResult = info
return true, nil
}
}
return false, nil
})
return waitResult, err
}
// waitForStorageAttachmentToBeDeleted waits for the storage attachment with the given name to be fully deleted, or times out.
func (c *StorageAttachmentsClient) waitForStorageAttachmentToBeDeleted(name string, timeout time.Duration) error {
return c.client.WaitFor("storage attachment to be deleted", timeout, func() (bool, error) {
input := &GetStorageAttachmentInput{
Name: name,
}
_, err := c.GetStorageAttachment(input)
if err != nil {
if client.WasNotFoundError(err) {
return true, nil
}
return false, err
}
return false, nil
})
}