github.com/gophercloud/gophercloud@v1.11.0/openstack/sharedfilesystems/v2/snapshots/results.go (about)

     1  package snapshots
     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  // Snapshot contains all information associated with an OpenStack Snapshot
    18  type Snapshot struct {
    19  	// The UUID of the snapshot
    20  	ID string `json:"id"`
    21  	// The name of the snapshot
    22  	Name string `json:"name,omitempty"`
    23  	// A description of the snapshot
    24  	Description string `json:"description,omitempty"`
    25  	// UUID of the share from which the snapshot was created
    26  	ShareID string `json:"share_id"`
    27  	// The shared file system protocol
    28  	ShareProto string `json:"share_proto"`
    29  	// Size of the snapshot share in GB
    30  	ShareSize int `json:"share_size"`
    31  	// Size of the snapshot in GB
    32  	Size int `json:"size"`
    33  	// The snapshot status
    34  	Status string `json:"status"`
    35  	// The UUID of the project in which the snapshot was created
    36  	ProjectID string `json:"project_id"`
    37  	// Timestamp when the snapshot was created
    38  	CreatedAt time.Time `json:"-"`
    39  	// Snapshot links for pagination
    40  	Links []map[string]string `json:"links"`
    41  }
    42  
    43  func (r *Snapshot) UnmarshalJSON(b []byte) error {
    44  	type tmp Snapshot
    45  	var s struct {
    46  		tmp
    47  		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
    48  	}
    49  	err := json.Unmarshal(b, &s)
    50  	if err != nil {
    51  		return err
    52  	}
    53  	*r = Snapshot(s.tmp)
    54  
    55  	r.CreatedAt = time.Time(s.CreatedAt)
    56  
    57  	return nil
    58  }
    59  
    60  type commonResult struct {
    61  	gophercloud.Result
    62  }
    63  
    64  // Extract will get the Snapshot object from the commonResult
    65  func (r commonResult) Extract() (*Snapshot, error) {
    66  	var s struct {
    67  		Snapshot *Snapshot `json:"snapshot"`
    68  	}
    69  	err := r.ExtractInto(&s)
    70  	return s.Snapshot, err
    71  }
    72  
    73  // CreateResult contains the response body and error from a Create request.
    74  type CreateResult struct {
    75  	commonResult
    76  }
    77  
    78  // SnapshotPage is a pagination.pager that is returned from a call to the List function.
    79  type SnapshotPage struct {
    80  	pagination.MarkerPageBase
    81  }
    82  
    83  // NextPageURL generates the URL for the page of results after this one.
    84  func (r SnapshotPage) NextPageURL() (string, error) {
    85  	currentURL := r.URL
    86  	mark, err := r.Owner.LastMarker()
    87  	if err != nil {
    88  		return "", err
    89  	}
    90  	if mark == invalidMarker {
    91  		return "", nil
    92  	}
    93  
    94  	q := currentURL.Query()
    95  	q.Set("offset", mark)
    96  	currentURL.RawQuery = q.Encode()
    97  	return currentURL.String(), nil
    98  }
    99  
   100  // LastMarker returns the last offset in a ListResult.
   101  func (r SnapshotPage) LastMarker() (string, error) {
   102  	snapshots, err := ExtractSnapshots(r)
   103  	if err != nil {
   104  		return invalidMarker, err
   105  	}
   106  	if len(snapshots) == 0 {
   107  		return invalidMarker, nil
   108  	}
   109  
   110  	u, err := url.Parse(r.URL.String())
   111  	if err != nil {
   112  		return invalidMarker, err
   113  	}
   114  	queryParams := u.Query()
   115  	offset := queryParams.Get("offset")
   116  	limit := queryParams.Get("limit")
   117  
   118  	// Limit is not present, only one page required
   119  	if limit == "" {
   120  		return invalidMarker, nil
   121  	}
   122  
   123  	iOffset := 0
   124  	if offset != "" {
   125  		iOffset, err = strconv.Atoi(offset)
   126  		if err != nil {
   127  			return invalidMarker, err
   128  		}
   129  	}
   130  	iLimit, err := strconv.Atoi(limit)
   131  	if err != nil {
   132  		return invalidMarker, err
   133  	}
   134  	iOffset = iOffset + iLimit
   135  	offset = strconv.Itoa(iOffset)
   136  
   137  	return offset, nil
   138  }
   139  
   140  // IsEmpty satisifies the IsEmpty method of the Page interface
   141  func (r SnapshotPage) IsEmpty() (bool, error) {
   142  	if r.StatusCode == 204 {
   143  		return true, nil
   144  	}
   145  
   146  	snapshots, err := ExtractSnapshots(r)
   147  	return len(snapshots) == 0, err
   148  }
   149  
   150  // ExtractSnapshots extracts and returns a Snapshot slice. It is used while
   151  // iterating over a snapshots.List call.
   152  func ExtractSnapshots(r pagination.Page) ([]Snapshot, error) {
   153  	var s struct {
   154  		Snapshots []Snapshot `json:"snapshots"`
   155  	}
   156  
   157  	err := (r.(SnapshotPage)).ExtractInto(&s)
   158  
   159  	return s.Snapshots, err
   160  }
   161  
   162  // DeleteResult contains the response body and error from a Delete request.
   163  type DeleteResult struct {
   164  	gophercloud.ErrResult
   165  }
   166  
   167  // GetResult contains the response body and error from a Get request.
   168  type GetResult struct {
   169  	commonResult
   170  }
   171  
   172  // UpdateResult contains the response body and error from an Update request.
   173  type UpdateResult struct {
   174  	commonResult
   175  }
   176  
   177  // ResetStatusResult contains the response error from an ResetStatus request.
   178  type ResetStatusResult struct {
   179  	gophercloud.ErrResult
   180  }
   181  
   182  // ForceDeleteResult contains the response error from an ForceDelete request.
   183  type ForceDeleteResult struct {
   184  	gophercloud.ErrResult
   185  }