blob: 95cc53b08bbd509e08305935a5f18f000a6cebb3 [file] [log] [blame]
Jon Perritt7cbb42c2015-02-08 21:13:08 -07001package stackevents
2
3import (
4 "time"
5
6 "github.com/mitchellh/mapstructure"
7 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
11// Event represents a stack event.
12type Event struct {
13 ResourceName string `mapstructure:"resource_name"`
14 Time time.Time `mapstructure:"-"`
15 Links []gophercloud.Link `mapstructure:"links"`
16 LogicalResourceID string `mapstructure:"logical_resource_id"`
17 ResourceStatusReason string `mapstructure:"resource_status_reason"`
18 ResourceStatus string `mapstructure:"resource_status"`
19 PhysicalResourceID string `mapstructure:"physical_resource_id"`
20 ID string `mapstructure:"id"`
21 ResourceProperties map[string]interface{} `mapstructure:"resource_properties"`
22}
23
24// FindResult represents the result of a Find operation.
25type FindResult struct {
26 gophercloud.Result
27}
28
29// Extract returns a slice of Event objects and is called after a
30// Find operation.
31func (r FindResult) Extract() ([]Event, error) {
32 if r.Err != nil {
33 return nil, r.Err
34 }
35
36 var res struct {
37 Res []Event `mapstructure:"events"`
38 }
39
40 if err := mapstructure.Decode(r.Body, &res); err != nil {
41 return nil, err
42 }
43
44 events := r.Body.(map[string]interface{})["events"].([]interface{})
45
46 for i, eventRaw := range events {
47 event := eventRaw.(map[string]interface{})
48 if date, ok := event["event_time"]; ok && date != nil {
49 t, err := time.Parse(time.RFC3339, date.(string))
50 if err != nil {
51 return nil, err
52 }
53 res.Res[i].Time = t
54 }
55 }
56
57 return res.Res, nil
58}
59
60// EventPage abstracts the raw results of making a List() request against the API.
61// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
62// data provided through the ExtractResources call.
63type EventPage struct {
64 pagination.MarkerPageBase
65}
66
67// IsEmpty returns true if a page contains no Server results.
68func (r EventPage) IsEmpty() (bool, error) {
69 events, err := ExtractEvents(r)
70 if err != nil {
71 return true, err
72 }
73 return len(events) == 0, nil
74}
75
76// LastMarker returns the last stack ID in a ListResult.
77func (r EventPage) LastMarker() (string, error) {
78 events, err := ExtractEvents(r)
79 if err != nil {
80 return "", err
81 }
82 if len(events) == 0 {
83 return "", nil
84 }
85 return events[len(events)-1].ID, nil
86}
87
88// ExtractEvents interprets the results of a single page from a List() call, producing a slice of Event entities.
89func ExtractEvents(page pagination.Page) ([]Event, error) {
90 casted := page.(EventPage).Body
91
92 var res struct {
93 Res []Event `mapstructure:"events"`
94 }
95
96 if err := mapstructure.Decode(casted, &res); err != nil {
97 return nil, err
98 }
99
100 events := casted.(map[string]interface{})["events"].([]interface{})
101
102 for i, eventRaw := range events {
103 event := eventRaw.(map[string]interface{})
104 if date, ok := event["event_time"]; ok && date != nil {
105 t, err := time.Parse(time.RFC3339, date.(string))
106 if err != nil {
107 return nil, err
108 }
109 res.Res[i].Time = t
110 }
111 }
112
113 return res.Res, nil
114}
115
Jon Perritt64c053f2015-02-09 15:42:18 -0700116// ExtractResourceEvents interprets the results of a single page from a
117// ListResourceEvents() call, producing a slice of Event entities.
118func ExtractResourceEvents(page pagination.Page) ([]Event, error) {
119 return ExtractEvents(page)
120}
121
Jon Perritt7cbb42c2015-02-08 21:13:08 -0700122// GetResult represents the result of a Get operation.
123type GetResult struct {
124 gophercloud.Result
125}
126
127// Extract returns a pointer to an Event object and is called after a
128// Get operation.
129func (r GetResult) Extract() (*Event, error) {
130 if r.Err != nil {
131 return nil, r.Err
132 }
133
134 var res struct {
135 Res *Event `mapstructure:"event"`
136 }
137
138 if err := mapstructure.Decode(r.Body, &res); err != nil {
139 return nil, err
140 }
141
142 event := r.Body.(map[string]interface{})["event"].(map[string]interface{})
143
144 if date, ok := event["event_time"]; ok && date != nil {
145 t, err := time.Parse(time.RFC3339, date.(string))
146 if err != nil {
147 return nil, err
148 }
149 res.Res.Time = t
150 }
151
152 return res.Res, nil
153}