github.com/gophercloud/gophercloud@v1.11.0/openstack/sharedfilesystems/v2/shares/results.go (about) 1 package shares 2 3 import ( 4 "encoding/json" 5 "net/url" 6 "strconv" 7 "time" 8 9 "github.com/gophercloud/gophercloud" 10 "github.com/gophercloud/gophercloud/pagination" 11 ) 12 13 const ( 14 invalidMarker = "-1" 15 ) 16 17 // Share contains all information associated with an OpenStack Share 18 type Share struct { 19 // The availability zone of the share 20 AvailabilityZone string `json:"availability_zone"` 21 // A description of the share 22 Description string `json:"description,omitempty"` 23 // DisplayDescription is inherited from BlockStorage API. 24 // Both Description and DisplayDescription can be used 25 DisplayDescription string `json:"display_description,omitempty"` 26 // DisplayName is inherited from BlockStorage API 27 // Both DisplayName and Name can be used 28 DisplayName string `json:"display_name,omitempty"` 29 // Indicates whether a share has replicas or not. 30 HasReplicas bool `json:"has_replicas"` 31 // The host name of the share 32 Host string `json:"host"` 33 // The UUID of the share 34 ID string `json:"id"` 35 // Indicates the visibility of the share 36 IsPublic bool `json:"is_public,omitempty"` 37 // Share links for pagination 38 Links []map[string]string `json:"links"` 39 // Key, value -pairs of custom metadata 40 Metadata map[string]string `json:"metadata,omitempty"` 41 // The name of the share 42 Name string `json:"name,omitempty"` 43 // The UUID of the project to which this share belongs to 44 ProjectID string `json:"project_id"` 45 // The share replication type 46 ReplicationType string `json:"replication_type,omitempty"` 47 // The UUID of the share network 48 ShareNetworkID string `json:"share_network_id"` 49 // The shared file system protocol 50 ShareProto string `json:"share_proto"` 51 // The UUID of the share server 52 ShareServerID string `json:"share_server_id"` 53 // The UUID of the share type. 54 ShareType string `json:"share_type"` 55 // The name of the share type. 56 ShareTypeName string `json:"share_type_name"` 57 // Size of the share in GB 58 Size int `json:"size"` 59 // UUID of the snapshot from which to create the share 60 SnapshotID string `json:"snapshot_id"` 61 // The share status 62 Status string `json:"status"` 63 // The task state, used for share migration 64 TaskState string `json:"task_state"` 65 // The type of the volume 66 VolumeType string `json:"volume_type,omitempty"` 67 // The UUID of the consistency group this share belongs to 68 ConsistencyGroupID string `json:"consistency_group_id"` 69 // Used for filtering backends which either support or do not support share snapshots 70 SnapshotSupport bool `json:"snapshot_support"` 71 SourceCgsnapshotMemberID string `json:"source_cgsnapshot_member_id"` 72 // Used for filtering backends which either support or do not support creating shares from snapshots 73 CreateShareFromSnapshotSupport bool `json:"create_share_from_snapshot_support"` 74 // Timestamp when the share was created 75 CreatedAt time.Time `json:"-"` 76 // Timestamp when the share was updated 77 UpdatedAt time.Time `json:"-"` 78 } 79 80 func (r *Share) UnmarshalJSON(b []byte) error { 81 type tmp Share 82 var s struct { 83 tmp 84 CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` 85 UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` 86 } 87 err := json.Unmarshal(b, &s) 88 if err != nil { 89 return err 90 } 91 *r = Share(s.tmp) 92 93 r.CreatedAt = time.Time(s.CreatedAt) 94 r.UpdatedAt = time.Time(s.UpdatedAt) 95 96 return nil 97 } 98 99 type commonResult struct { 100 gophercloud.Result 101 } 102 103 // Extract will get the Share object from the commonResult 104 func (r commonResult) Extract() (*Share, error) { 105 var s struct { 106 Share *Share `json:"share"` 107 } 108 err := r.ExtractInto(&s) 109 return s.Share, err 110 } 111 112 // CreateResult contains the response body and error from a Create request. 113 type CreateResult struct { 114 commonResult 115 } 116 117 // SharePage is a pagination.pager that is returned from a call to the List function. 118 type SharePage struct { 119 pagination.MarkerPageBase 120 } 121 122 // NextPageURL generates the URL for the page of results after this one. 123 func (r SharePage) NextPageURL() (string, error) { 124 currentURL := r.URL 125 mark, err := r.Owner.LastMarker() 126 if err != nil { 127 return "", err 128 } 129 if mark == invalidMarker { 130 return "", nil 131 } 132 133 q := currentURL.Query() 134 q.Set("offset", mark) 135 currentURL.RawQuery = q.Encode() 136 return currentURL.String(), nil 137 } 138 139 // LastMarker returns the last offset in a ListResult. 140 func (r SharePage) LastMarker() (string, error) { 141 shares, err := ExtractShares(r) 142 if err != nil { 143 return invalidMarker, err 144 } 145 if len(shares) == 0 { 146 return invalidMarker, nil 147 } 148 149 u, err := url.Parse(r.URL.String()) 150 if err != nil { 151 return invalidMarker, err 152 } 153 queryParams := u.Query() 154 offset := queryParams.Get("offset") 155 limit := queryParams.Get("limit") 156 157 // Limit is not present, only one page required 158 if limit == "" { 159 return invalidMarker, nil 160 } 161 162 iOffset := 0 163 if offset != "" { 164 iOffset, err = strconv.Atoi(offset) 165 if err != nil { 166 return invalidMarker, err 167 } 168 } 169 iLimit, err := strconv.Atoi(limit) 170 if err != nil { 171 return invalidMarker, err 172 } 173 iOffset = iOffset + iLimit 174 offset = strconv.Itoa(iOffset) 175 176 return offset, nil 177 } 178 179 // IsEmpty satisifies the IsEmpty method of the Page interface 180 func (r SharePage) IsEmpty() (bool, error) { 181 if r.StatusCode == 204 { 182 return true, nil 183 } 184 185 shares, err := ExtractShares(r) 186 return len(shares) == 0, err 187 } 188 189 // ExtractShares extracts and returns a Share slice. It is used while 190 // iterating over a shares.List call. 191 func ExtractShares(r pagination.Page) ([]Share, error) { 192 var s struct { 193 Shares []Share `json:"shares"` 194 } 195 196 err := (r.(SharePage)).ExtractInto(&s) 197 198 return s.Shares, err 199 } 200 201 // DeleteResult contains the response body and error from a Delete request. 202 type DeleteResult struct { 203 gophercloud.ErrResult 204 } 205 206 // GetResult contains the response body and error from a Get request. 207 type GetResult struct { 208 commonResult 209 } 210 211 // UpdateResult contains the response body and error from an Update request. 212 type UpdateResult struct { 213 commonResult 214 } 215 216 // ListExportLocationsResult contains the result body and error from a 217 // ListExportLocations request. 218 type ListExportLocationsResult struct { 219 gophercloud.Result 220 } 221 222 // GetExportLocationResult contains the result body and error from a 223 // GetExportLocation request. 224 type GetExportLocationResult struct { 225 gophercloud.Result 226 } 227 228 // ExportLocation contains all information associated with a share export location 229 type ExportLocation struct { 230 // The export location path that should be used for mount operation. 231 Path string `json:"path"` 232 // The UUID of the share instance that this export location belongs to. 233 ShareInstanceID string `json:"share_instance_id"` 234 // Defines purpose of an export location. 235 // If set to true, then it is expected to be used for service needs 236 // and by administrators only. 237 // If it is set to false, then this export location can be used by end users. 238 IsAdminOnly bool `json:"is_admin_only"` 239 // The share export location UUID. 240 ID string `json:"id"` 241 // Drivers may use this field to identify which export locations are 242 // most efficient and should be used preferentially by clients. 243 // By default it is set to false value. New in version 2.14 244 Preferred bool `json:"preferred"` 245 } 246 247 // Extract will get the Export Locations from the ListExportLocationsResult 248 func (r ListExportLocationsResult) Extract() ([]ExportLocation, error) { 249 var s struct { 250 ExportLocations []ExportLocation `json:"export_locations"` 251 } 252 err := r.ExtractInto(&s) 253 return s.ExportLocations, err 254 } 255 256 // Extract will get the Export Location from the GetExportLocationResult 257 func (r GetExportLocationResult) Extract() (*ExportLocation, error) { 258 var s struct { 259 ExportLocation *ExportLocation `json:"export_location"` 260 } 261 err := r.ExtractInto(&s) 262 return s.ExportLocation, err 263 } 264 265 // AccessRight contains all information associated with an OpenStack share 266 // Grant Access Response 267 type AccessRight struct { 268 // The UUID of the share to which you are granted or denied access. 269 ShareID string `json:"share_id"` 270 // The access rule type that can be "ip", "cert" or "user". 271 AccessType string `json:"access_type,omitempty"` 272 // The value that defines the access that can be a valid format of IP, cert or user. 273 AccessTo string `json:"access_to,omitempty"` 274 // The access credential of the entity granted share access. 275 AccessKey string `json:"access_key,omitempty"` 276 // The access level to the share is either "rw" or "ro". 277 AccessLevel string `json:"access_level,omitempty"` 278 // The state of the access rule 279 State string `json:"state,omitempty"` 280 // The access rule ID. 281 ID string `json:"id"` 282 } 283 284 // Extract will get the GrantAccess object from the commonResult 285 func (r GrantAccessResult) Extract() (*AccessRight, error) { 286 var s struct { 287 AccessRight *AccessRight `json:"access"` 288 } 289 err := r.ExtractInto(&s) 290 return s.AccessRight, err 291 } 292 293 // GrantAccessResult contains the result body and error from an GrantAccess request. 294 type GrantAccessResult struct { 295 gophercloud.Result 296 } 297 298 // RevokeAccessResult contains the response body and error from a Revoke access request. 299 type RevokeAccessResult struct { 300 gophercloud.ErrResult 301 } 302 303 // Extract will get a slice of AccessRight objects from the commonResult 304 func (r ListAccessRightsResult) Extract() ([]AccessRight, error) { 305 var s struct { 306 AccessRights []AccessRight `json:"access_list"` 307 } 308 err := r.ExtractInto(&s) 309 return s.AccessRights, err 310 } 311 312 // ListAccessRightsResult contains the result body and error from a ListAccessRights request. 313 type ListAccessRightsResult struct { 314 gophercloud.Result 315 } 316 317 // ExtendResult contains the response body and error from an Extend request. 318 type ExtendResult struct { 319 gophercloud.ErrResult 320 } 321 322 // ShrinkResult contains the response body and error from a Shrink request. 323 type ShrinkResult struct { 324 gophercloud.ErrResult 325 } 326 327 // GetMetadatumResult contains the response body and error from a GetMetadatum request. 328 type GetMetadatumResult struct { 329 gophercloud.Result 330 } 331 332 // Extract will get the string-string map from GetMetadatumResult 333 func (r GetMetadatumResult) Extract() (map[string]string, error) { 334 var s struct { 335 Meta map[string]string `json:"meta"` 336 } 337 err := r.ExtractInto(&s) 338 return s.Meta, err 339 } 340 341 // MetadataResult contains the response body and error from GetMetadata, SetMetadata or UpdateMetadata requests. 342 type MetadataResult struct { 343 gophercloud.Result 344 } 345 346 // Extract will get the string-string map from MetadataResult 347 func (r MetadataResult) Extract() (map[string]string, error) { 348 var s struct { 349 Metadata map[string]string `json:"metadata"` 350 } 351 err := r.ExtractInto(&s) 352 return s.Metadata, err 353 } 354 355 // DeleteMetadatumResult contains the response body and error from a DeleteMetadatum request. 356 type DeleteMetadatumResult struct { 357 gophercloud.ErrResult 358 } 359 360 // RevertResult contains the response error from an Revert request. 361 type RevertResult struct { 362 gophercloud.ErrResult 363 } 364 365 // ResetStatusResult contains the response error from an ResetStatus request. 366 type ResetStatusResult struct { 367 gophercloud.ErrResult 368 } 369 370 // ForceDeleteResult contains the response error from an ForceDelete request. 371 type ForceDeleteResult struct { 372 gophercloud.ErrResult 373 } 374 375 // UnmanageResult contains the response error from an Unmanage request. 376 type UnmanageResult struct { 377 gophercloud.ErrResult 378 }