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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
|
package shares
import (
"encoding/json"
"net/url"
"strconv"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
const (
invalidMarker = "-1"
)
// Share contains all information associated with an OpenStack Share
type Share struct {
// The availability zone of the share
AvailabilityZone string `json:"availability_zone"`
// A description of the share
Description string `json:"description,omitempty"`
// DisplayDescription is inherited from BlockStorage API.
// Both Description and DisplayDescription can be used
DisplayDescription string `json:"display_description,omitempty"`
// DisplayName is inherited from BlockStorage API
// Both DisplayName and Name can be used
DisplayName string `json:"display_name,omitempty"`
// Indicates whether a share has replicas or not.
HasReplicas bool `json:"has_replicas"`
// The host name of the share
Host string `json:"host"`
// The UUID of the share
ID string `json:"id"`
// Indicates the visibility of the share
IsPublic bool `json:"is_public,omitempty"`
// Share links for pagination
Links []map[string]string `json:"links"`
// Key, value -pairs of custom metadata
Metadata map[string]string `json:"metadata,omitempty"`
// The name of the share
Name string `json:"name,omitempty"`
// The UUID of the project to which this share belongs to
ProjectID string `json:"project_id"`
// The share replication type
ReplicationType string `json:"replication_type,omitempty"`
// The UUID of the share network
ShareNetworkID string `json:"share_network_id"`
// The shared file system protocol
ShareProto string `json:"share_proto"`
// The UUID of the share server
ShareServerID string `json:"share_server_id"`
// The UUID of the share type.
ShareType string `json:"share_type"`
// The name of the share type.
ShareTypeName string `json:"share_type_name"`
// Size of the share in GB
Size int `json:"size"`
// UUID of the snapshot from which to create the share
SnapshotID string `json:"snapshot_id"`
// The share status
Status string `json:"status"`
// The task state, used for share migration
TaskState string `json:"task_state"`
// The type of the volume
VolumeType string `json:"volume_type,omitempty"`
// The UUID of the consistency group this share belongs to
ConsistencyGroupID string `json:"consistency_group_id"`
// Used for filtering backends which either support or do not support share snapshots
SnapshotSupport bool `json:"snapshot_support"`
SourceCgsnapshotMemberID string `json:"source_cgsnapshot_member_id"`
// Timestamp when the share was created
CreatedAt time.Time `json:"-"`
// Timestamp when the share was updated
UpdatedAt time.Time `json:"-"`
}
func (r *Share) UnmarshalJSON(b []byte) error {
type tmp Share
var s struct {
tmp
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
}
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*r = Share(s.tmp)
r.CreatedAt = time.Time(s.CreatedAt)
r.UpdatedAt = time.Time(s.UpdatedAt)
return nil
}
type commonResult struct {
gophercloud.Result
}
// Extract will get the Share object from the commonResult
func (r commonResult) Extract() (*Share, error) {
var s struct {
Share *Share `json:"share"`
}
err := r.ExtractInto(&s)
return s.Share, err
}
// CreateResult contains the response body and error from a Create request.
type CreateResult struct {
commonResult
}
// SharePage is a pagination.pager that is returned from a call to the List function.
type SharePage struct {
pagination.MarkerPageBase
}
// NextPageURL generates the URL for the page of results after this one.
func (r SharePage) NextPageURL() (string, error) {
currentURL := r.URL
mark, err := r.Owner.LastMarker()
if err != nil {
return "", err
}
if mark == invalidMarker {
return "", nil
}
q := currentURL.Query()
q.Set("offset", mark)
currentURL.RawQuery = q.Encode()
return currentURL.String(), nil
}
// LastMarker returns the last offset in a ListResult.
func (r SharePage) LastMarker() (string, error) {
shares, err := ExtractShares(r)
if err != nil {
return invalidMarker, err
}
if len(shares) == 0 {
return invalidMarker, nil
}
u, err := url.Parse(r.URL.String())
if err != nil {
return invalidMarker, err
}
queryParams := u.Query()
offset := queryParams.Get("offset")
limit := queryParams.Get("limit")
// Limit is not present, only one page required
if limit == "" {
return invalidMarker, nil
}
iOffset := 0
if offset != "" {
iOffset, err = strconv.Atoi(offset)
if err != nil {
return invalidMarker, err
}
}
iLimit, err := strconv.Atoi(limit)
if err != nil {
return invalidMarker, err
}
iOffset = iOffset + iLimit
offset = strconv.Itoa(iOffset)
return offset, nil
}
// IsEmpty satisifies the IsEmpty method of the Page interface
func (r SharePage) IsEmpty() (bool, error) {
shares, err := ExtractShares(r)
return len(shares) == 0, err
}
// ExtractShares extracts and returns a Share slice. It is used while
// iterating over a shares.List call.
func ExtractShares(r pagination.Page) ([]Share, error) {
var s struct {
Shares []Share `json:"shares"`
}
err := (r.(SharePage)).ExtractInto(&s)
return s.Shares, err
}
// DeleteResult contains the response body and error from a Delete request.
type DeleteResult struct {
gophercloud.ErrResult
}
// GetResult contains the response body and error from a Get request.
type GetResult struct {
commonResult
}
// UpdateResult contains the response body and error from an Update request.
type UpdateResult struct {
commonResult
}
// ListExportLocationsResult contains the result body and error from a
// ListExportLocations request.
type ListExportLocationsResult struct {
gophercloud.Result
}
// GetExportLocationResult contains the result body and error from a
// GetExportLocation request.
type GetExportLocationResult struct {
gophercloud.Result
}
// ExportLocation contains all information associated with a share export location
type ExportLocation struct {
// The export location path that should be used for mount operation.
Path string `json:"path"`
// The UUID of the share instance that this export location belongs to.
ShareInstanceID string `json:"share_instance_id"`
// Defines purpose of an export location.
// If set to true, then it is expected to be used for service needs
// and by administrators only.
// If it is set to false, then this export location can be used by end users.
IsAdminOnly bool `json:"is_admin_only"`
// The share export location UUID.
ID string `json:"id"`
// Drivers may use this field to identify which export locations are
// most efficient and should be used preferentially by clients.
// By default it is set to false value. New in version 2.14
Preferred bool `json:"preferred"`
}
// Extract will get the Export Locations from the ListExportLocationsResult
func (r ListExportLocationsResult) Extract() ([]ExportLocation, error) {
var s struct {
ExportLocations []ExportLocation `json:"export_locations"`
}
err := r.ExtractInto(&s)
return s.ExportLocations, err
}
// Extract will get the Export Location from the GetExportLocationResult
func (r GetExportLocationResult) Extract() (*ExportLocation, error) {
var s struct {
ExportLocation *ExportLocation `json:"export_location"`
}
err := r.ExtractInto(&s)
return s.ExportLocation, err
}
// AccessRight contains all information associated with an OpenStack share
// Grant Access Response
type AccessRight struct {
// The UUID of the share to which you are granted or denied access.
ShareID string `json:"share_id"`
// The access rule type that can be "ip", "cert" or "user".
AccessType string `json:"access_type,omitempty"`
// The value that defines the access that can be a valid format of IP, cert or user.
AccessTo string `json:"access_to,omitempty"`
// The access credential of the entity granted share access.
AccessKey string `json:"access_key,omitempty"`
// The access level to the share is either "rw" or "ro".
AccessLevel string `json:"access_level,omitempty"`
// The state of the access rule
State string `json:"state,omitempty"`
// The access rule ID.
ID string `json:"id"`
}
// Extract will get the GrantAccess object from the commonResult
func (r GrantAccessResult) Extract() (*AccessRight, error) {
var s struct {
AccessRight *AccessRight `json:"access"`
}
err := r.ExtractInto(&s)
return s.AccessRight, err
}
// GrantAccessResult contains the result body and error from an GrantAccess request.
type GrantAccessResult struct {
gophercloud.Result
}
// RevokeAccessResult contains the response body and error from a Revoke access request.
type RevokeAccessResult struct {
gophercloud.ErrResult
}
// Extract will get a slice of AccessRight objects from the commonResult
func (r ListAccessRightsResult) Extract() ([]AccessRight, error) {
var s struct {
AccessRights []AccessRight `json:"access_list"`
}
err := r.ExtractInto(&s)
return s.AccessRights, err
}
// ListAccessRightsResult contains the result body and error from a ListAccessRights request.
type ListAccessRightsResult struct {
gophercloud.Result
}
// ExtendResult contains the response body and error from an Extend request.
type ExtendResult struct {
gophercloud.ErrResult
}
// ShrinkResult contains the response body and error from a Shrink request.
type ShrinkResult struct {
gophercloud.ErrResult
}
// GetMetadatumResult contains the response body and error from a GetMetadatum request.
type GetMetadatumResult struct {
gophercloud.Result
}
// Extract will get the string-string map from GetMetadatumResult
func (r GetMetadatumResult) Extract() (map[string]string, error) {
var s struct {
Meta map[string]string `json:"meta"`
}
err := r.ExtractInto(&s)
return s.Meta, err
}
// MetadataResult contains the response body and error from GetMetadata, SetMetadata or UpdateMetadata requests.
type MetadataResult struct {
gophercloud.Result
}
// Extract will get the string-string map from MetadataResult
func (r MetadataResult) Extract() (map[string]string, error) {
var s struct {
Metadata map[string]string `json:"metadata"`
}
err := r.ExtractInto(&s)
return s.Metadata, err
}
// DeleteMetadatumResult contains the response body and error from a DeleteMetadatum request.
type DeleteMetadatumResult struct {
gophercloud.ErrResult
}
// RevertResult contains the response error from an Revert request.
type RevertResult struct {
gophercloud.ErrResult
}
// ResetStatusResult contains the response error from an ResetStatus request.
type ResetStatusResult struct {
gophercloud.ErrResult
}
// ForceDeleteResult contains the response error from an ForceDelete request.
type ForceDeleteResult struct {
gophercloud.ErrResult
}
// UnmanageResult contains the response error from an Unmanage request.
type UnmanageResult struct {
gophercloud.ErrResult
}
|