blob: 842a659e0bad02e0a231c54d7b4109c9260ae6af [file] [log] [blame]
feiskycf0c7fe2015-11-05 22:06:17 +08001package volumeactions
2
3import (
4 "github.com/rackspace/gophercloud"
5)
6
Pengfei Ni8bfbfb02016-04-29 16:04:12 +08007// AttachOptsBuilder allows extensions to add additional parameters to the
8// Attach request.
feiskycf0c7fe2015-11-05 22:06:17 +08009type AttachOptsBuilder interface {
10 ToVolumeAttachMap() (map[string]interface{}, error)
11}
12
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080013// AttachMode describes the attachment mode for volumes.
14type AttachMode string
15
16// These constants determine how a volume is attached
17const (
18 ReadOnly AttachMode = "ro"
19 ReadWrite AttachMode = "rw"
20)
21
22// AttachOpts contains options for attaching a Volume.
feiskycf0c7fe2015-11-05 22:06:17 +080023type AttachOpts struct {
24 // The mountpoint of this volume
25 MountPoint string
26 // The nova instance ID, can't set simultaneously with HostName
27 InstanceUUID string
28 // The hostname of baremetal host, can't set simultaneously with InstanceUUID
29 HostName string
30 // Mount mode of this volume
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080031 Mode AttachMode
feiskycf0c7fe2015-11-05 22:06:17 +080032}
33
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080034// ToVolumeAttachMap assembles a request body based on the contents of a
35// AttachOpts.
feiskycf0c7fe2015-11-05 22:06:17 +080036func (opts AttachOpts) ToVolumeAttachMap() (map[string]interface{}, error) {
37 v := make(map[string]interface{})
38
39 if opts.MountPoint != "" {
40 v["mountpoint"] = opts.MountPoint
41 }
42 if opts.Mode != "" {
43 v["mode"] = opts.Mode
44 }
45 if opts.InstanceUUID != "" {
46 v["instance_uuid"] = opts.InstanceUUID
47 }
48 if opts.HostName != "" {
49 v["host_name"] = opts.HostName
50 }
51
52 return map[string]interface{}{"os-attach": v}, nil
53}
54
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080055// Attach will attach a volume based on the values in AttachOpts.
feiskycf0c7fe2015-11-05 22:06:17 +080056func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder) AttachResult {
57 var res AttachResult
58
59 reqBody, err := opts.ToVolumeAttachMap()
60 if err != nil {
61 res.Err = err
62 return res
63 }
64
Jamie Hannaford531e0cc2016-05-13 13:03:39 +020065 _, res.Err = client.Post(attachURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080066 OkCodes: []int{202},
feiskycf0c7fe2015-11-05 22:06:17 +080067 })
68
69 return res
70}
71
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080072// Attach will detach a volume based on volume id.
feiskycf0c7fe2015-11-05 22:06:17 +080073func Detach(client *gophercloud.ServiceClient, id string) DetachResult {
74 var res DetachResult
75
76 v := make(map[string]interface{})
77 reqBody := map[string]interface{}{"os-detach": v}
78
Jamie Hannaford531e0cc2016-05-13 13:03:39 +020079 _, res.Err = client.Post(detachURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080080 OkCodes: []int{202},
feiskycf0c7fe2015-11-05 22:06:17 +080081 })
82
83 return res
84}
85
Pengfei Ni8bfbfb02016-04-29 16:04:12 +080086// Reserve will reserve a volume based on volume id.
feiskycf0c7fe2015-11-05 22:06:17 +080087func Reserve(client *gophercloud.ServiceClient, id string) ReserveResult {
88 var res ReserveResult
89
90 v := make(map[string]interface{})
91 reqBody := map[string]interface{}{"os-reserve": v}
92
Jamie Hannaford531e0cc2016-05-13 13:03:39 +020093 _, res.Err = client.Post(reserveURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
feiskycf0c7fe2015-11-05 22:06:17 +080094 OkCodes: []int{200, 201, 202},
95 })
96
97 return res
98}
99
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800100// Unreserve will unreserve a volume based on volume id.
feiskycf0c7fe2015-11-05 22:06:17 +0800101func Unreserve(client *gophercloud.ServiceClient, id string) UnreserveResult {
102 var res UnreserveResult
103
104 v := make(map[string]interface{})
105 reqBody := map[string]interface{}{"os-unreserve": v}
106
Jamie Hannaford531e0cc2016-05-13 13:03:39 +0200107 _, res.Err = client.Post(unreserveURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
feiskycf0c7fe2015-11-05 22:06:17 +0800108 OkCodes: []int{200, 201, 202},
109 })
110
111 return res
112}
113
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800114// ConnectorOptsBuilder allows extensions to add additional parameters to the
115// InitializeConnection request.
feiskycf0c7fe2015-11-05 22:06:17 +0800116type ConnectorOptsBuilder interface {
117 ToConnectorMap() (map[string]interface{}, error)
118}
119
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800120// ConnectorOpts hosts options for InitializeConnection.
feiskycf0c7fe2015-11-05 22:06:17 +0800121type ConnectorOpts struct {
122 IP string
123 Host string
124 Initiator string
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800125 Wwpns []string
feiskycf0c7fe2015-11-05 22:06:17 +0800126 Wwnns string
127 Multipath bool
128 Platform string
129 OSType string
130}
131
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800132// ToConnectorMap assembles a request body based on the contents of a
133// ConnectorOpts.
feiskycf0c7fe2015-11-05 22:06:17 +0800134func (opts ConnectorOpts) ToConnectorMap() (map[string]interface{}, error) {
135 v := make(map[string]interface{})
136
137 if opts.IP != "" {
138 v["ip"] = opts.IP
139 }
140 if opts.Host != "" {
141 v["host"] = opts.Host
142 }
143 if opts.Initiator != "" {
144 v["initiator"] = opts.Initiator
145 }
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800146 if opts.Wwpns != nil {
feiskycf0c7fe2015-11-05 22:06:17 +0800147 v["wwpns"] = opts.Wwpns
148 }
149 if opts.Wwnns != "" {
150 v["wwnns"] = opts.Wwnns
151 }
152
153 v["multipath"] = opts.Multipath
154
155 if opts.Platform != "" {
156 v["platform"] = opts.Platform
157 }
158 if opts.OSType != "" {
159 v["os_type"] = opts.OSType
160 }
161
162 return map[string]interface{}{"connector": v}, nil
163}
164
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800165// InitializeConnection initializes iscsi connection.
feiskycf0c7fe2015-11-05 22:06:17 +0800166func InitializeConnection(client *gophercloud.ServiceClient, id string, opts *ConnectorOpts) InitializeConnectionResult {
167 var res InitializeConnectionResult
168
169 connctorMap, err := opts.ToConnectorMap()
170 if err != nil {
171 res.Err = err
172 return res
173 }
174
175 reqBody := map[string]interface{}{"os-initialize_connection": connctorMap}
176
177 _, res.Err = client.Post(initializeConnectionURL(client, id), reqBody, &res.Body, &gophercloud.RequestOpts{
178 OkCodes: []int{200, 201, 202},
179 })
180
181 return res
182}
183
Pengfei Ni8bfbfb02016-04-29 16:04:12 +0800184// TerminateConnection terminates iscsi connection.
feiskycf0c7fe2015-11-05 22:06:17 +0800185func TerminateConnection(client *gophercloud.ServiceClient, id string, opts *ConnectorOpts) TerminateConnectionResult {
186 var res TerminateConnectionResult
187
188 connctorMap, err := opts.ToConnectorMap()
189 if err != nil {
190 res.Err = err
191 return res
192 }
193
194 reqBody := map[string]interface{}{"os-terminate_connection": connctorMap}
195
Jamie Hannaford531e0cc2016-05-13 13:03:39 +0200196 _, res.Err = client.Post(teminateConnectionURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
197 OkCodes: []int{202},
feiskycf0c7fe2015-11-05 22:06:17 +0800198 })
199
200 return res
201}