1package backups
2
3import (
4	"encoding/json"
5	"time"
6
7	"github.com/gophercloud/gophercloud"
8	"github.com/gophercloud/gophercloud/pagination"
9)
10
11// Backup contains all the information associated with a Cinder Backup.
12type Backup struct {
13	// ID is the Unique identifier of the backup.
14	ID string `json:"id"`
15
16	// CreatedAt is the date the backup was created.
17	CreatedAt time.Time `json:"-"`
18
19	// UpdatedAt is the date the backup was updated.
20	UpdatedAt time.Time `json:"-"`
21
22	// Name is the display name of the backup.
23	Name string `json:"name"`
24
25	// Description is the description of the backup.
26	Description string `json:"description"`
27
28	// VolumeID is the ID of the Volume from which this backup was created.
29	VolumeID string `json:"volume_id"`
30
31	// SnapshotID is the ID of the snapshot from which this backup was created.
32	SnapshotID string `json:"snapshot_id"`
33
34	// Status is the status of the backup.
35	Status string `json:"status"`
36
37	// Size is the size of the backup, in GB.
38	Size int `json:"size"`
39
40	// Object Count is the number of objects in the backup.
41	ObjectCount int `json:"object_count"`
42
43	// Container is the container where the backup is stored.
44	Container string `json:"container"`
45
46	// AvailabilityZone is the availability zone of the backup.
47	AvailabilityZone string `json:"availability_zone"`
48
49	// HasDependentBackups is whether there are other backups
50	// depending on this backup.
51	HasDependentBackups bool `json:"has_dependent_backups"`
52
53	// FailReason has the reason for the backup failure.
54	FailReason string `json:"fail_reason"`
55
56	// IsIncremental is whether this is an incremental backup.
57	IsIncremental bool `json:"is_incremental"`
58
59	// DataTimestamp is the time when the data on the volume was first saved.
60	DataTimestamp time.Time `json:"-"`
61
62	// ProjectID is the ID of the project that owns the backup. This is
63	// an admin-only field.
64	ProjectID string `json:"os-backup-project-attr:project_id"`
65}
66
67// CreateResult contains the response body and error from a Create request.
68type CreateResult struct {
69	commonResult
70}
71
72// GetResult contains the response body and error from a Get request.
73type GetResult struct {
74	commonResult
75}
76
77// DeleteResult contains the response body and error from a Delete request.
78type DeleteResult struct {
79	gophercloud.ErrResult
80}
81
82// BackupPage is a pagination.Pager that is returned from a call to the List function.
83type BackupPage struct {
84	pagination.LinkedPageBase
85}
86
87// UnmarshalJSON converts our JSON API response into our backup struct
88func (r *Backup) UnmarshalJSON(b []byte) error {
89	type tmp Backup
90	var s struct {
91		tmp
92		CreatedAt     gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
93		UpdatedAt     gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
94		DataTimestamp gophercloud.JSONRFC3339MilliNoZ `json:"data_timestamp"`
95	}
96	err := json.Unmarshal(b, &s)
97	if err != nil {
98		return err
99	}
100	*r = Backup(s.tmp)
101
102	r.CreatedAt = time.Time(s.CreatedAt)
103	r.UpdatedAt = time.Time(s.UpdatedAt)
104	r.DataTimestamp = time.Time(s.DataTimestamp)
105
106	return err
107}
108
109// IsEmpty returns true if a BackupPage contains no Backups.
110func (r BackupPage) IsEmpty() (bool, error) {
111	volumes, err := ExtractBackups(r)
112	return len(volumes) == 0, err
113}
114
115func (page BackupPage) NextPageURL() (string, error) {
116	var s struct {
117		Links []gophercloud.Link `json:"backups_links"`
118	}
119	err := page.ExtractInto(&s)
120	if err != nil {
121		return "", err
122	}
123	return gophercloud.ExtractNextURL(s.Links)
124}
125
126// ExtractBackups extracts and returns Backups. It is used while iterating over a backups.List call.
127func ExtractBackups(r pagination.Page) ([]Backup, error) {
128	var s []Backup
129	err := ExtractBackupsInto(r, &s)
130	return s, err
131}
132
133// UpdateResult contains the response body and error from an Update request.
134type UpdateResult struct {
135	commonResult
136}
137
138type commonResult struct {
139	gophercloud.Result
140}
141
142// Extract will get the Backup object out of the commonResult object.
143func (r commonResult) Extract() (*Backup, error) {
144	var s Backup
145	err := r.ExtractInto(&s)
146	return &s, err
147}
148
149func (r commonResult) ExtractInto(v interface{}) error {
150	return r.Result.ExtractIntoStructPtr(v, "backup")
151}
152
153func ExtractBackupsInto(r pagination.Page, v interface{}) error {
154	return r.(BackupPage).Result.ExtractIntoSlicePtr(v, "backups")
155}
156