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  }