blob: cf9e240982df070ccd180086710d201f0434b638 [file] [log] [blame]
Jon Perritt7cbb42c2015-02-08 21:13:08 -07001package stackevents
2
3import (
Jon Perritta11b5df2015-03-05 13:51:59 -07004 "fmt"
5 "reflect"
Jon Perritt7cbb42c2015-02-08 21:13:08 -07006 "time"
7
8 "github.com/mitchellh/mapstructure"
9 "github.com/rackspace/gophercloud"
10 "github.com/rackspace/gophercloud/pagination"
11)
12
13// Event represents a stack event.
14type Event struct {
Jon Perritt9dce4152015-02-11 13:05:54 -070015 // The name of the resource for which the event occurred.
16 ResourceName string `mapstructure:"resource_name"`
17 // The time the event occurred.
18 Time time.Time `mapstructure:"-"`
19 // The URLs to the event.
20 Links []gophercloud.Link `mapstructure:"links"`
21 // The logical ID of the stack resource.
22 LogicalResourceID string `mapstructure:"logical_resource_id"`
23 // The reason of the status of the event.
24 ResourceStatusReason string `mapstructure:"resource_status_reason"`
25 // The status of the event.
26 ResourceStatus string `mapstructure:"resource_status"`
27 // The physical ID of the stack resource.
28 PhysicalResourceID string `mapstructure:"physical_resource_id"`
29 // The event ID.
30 ID string `mapstructure:"id"`
31 // Properties of the stack resource.
32 ResourceProperties map[string]interface{} `mapstructure:"resource_properties"`
Jon Perritt7cbb42c2015-02-08 21:13:08 -070033}
34
35// FindResult represents the result of a Find operation.
36type FindResult struct {
37 gophercloud.Result
38}
39
40// Extract returns a slice of Event objects and is called after a
41// Find operation.
42func (r FindResult) Extract() ([]Event, error) {
43 if r.Err != nil {
44 return nil, r.Err
45 }
46
47 var res struct {
48 Res []Event `mapstructure:"events"`
49 }
50
51 if err := mapstructure.Decode(r.Body, &res); err != nil {
52 return nil, err
53 }
54
55 events := r.Body.(map[string]interface{})["events"].([]interface{})
56
57 for i, eventRaw := range events {
58 event := eventRaw.(map[string]interface{})
59 if date, ok := event["event_time"]; ok && date != nil {
Pratik Mallyae1b6cbb2015-09-09 14:24:14 -050060 t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
Jon Perritt7cbb42c2015-02-08 21:13:08 -070061 if err != nil {
62 return nil, err
63 }
64 res.Res[i].Time = t
65 }
66 }
67
68 return res.Res, nil
69}
70
71// EventPage abstracts the raw results of making a List() request against the API.
72// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
73// data provided through the ExtractResources call.
74type EventPage struct {
75 pagination.MarkerPageBase
76}
77
78// IsEmpty returns true if a page contains no Server results.
79func (r EventPage) IsEmpty() (bool, error) {
80 events, err := ExtractEvents(r)
81 if err != nil {
82 return true, err
83 }
84 return len(events) == 0, nil
85}
86
87// LastMarker returns the last stack ID in a ListResult.
88func (r EventPage) LastMarker() (string, error) {
89 events, err := ExtractEvents(r)
90 if err != nil {
91 return "", err
92 }
93 if len(events) == 0 {
94 return "", nil
95 }
96 return events[len(events)-1].ID, nil
97}
98
99// ExtractEvents interprets the results of a single page from a List() call, producing a slice of Event entities.
100func ExtractEvents(page pagination.Page) ([]Event, error) {
101 casted := page.(EventPage).Body
102
103 var res struct {
104 Res []Event `mapstructure:"events"`
105 }
106
107 if err := mapstructure.Decode(casted, &res); err != nil {
108 return nil, err
109 }
110
Jon Perritta11b5df2015-03-05 13:51:59 -0700111 var events []interface{}
112 switch casted.(type) {
113 case map[string]interface{}:
114 events = casted.(map[string]interface{})["events"].([]interface{})
115 case map[string][]interface{}:
116 events = casted.(map[string][]interface{})["events"]
117 default:
118 return res.Res, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
119 }
Jon Perritt7cbb42c2015-02-08 21:13:08 -0700120
121 for i, eventRaw := range events {
122 event := eventRaw.(map[string]interface{})
123 if date, ok := event["event_time"]; ok && date != nil {
Pratik Mallyae1b6cbb2015-09-09 14:24:14 -0500124 t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
Jon Perritt7cbb42c2015-02-08 21:13:08 -0700125 if err != nil {
126 return nil, err
127 }
128 res.Res[i].Time = t
129 }
130 }
131
132 return res.Res, nil
133}
134
Jon Perritt64c053f2015-02-09 15:42:18 -0700135// ExtractResourceEvents interprets the results of a single page from a
136// ListResourceEvents() call, producing a slice of Event entities.
137func ExtractResourceEvents(page pagination.Page) ([]Event, error) {
138 return ExtractEvents(page)
139}
140
Jon Perritt7cbb42c2015-02-08 21:13:08 -0700141// GetResult represents the result of a Get operation.
142type GetResult struct {
143 gophercloud.Result
144}
145
146// Extract returns a pointer to an Event object and is called after a
147// Get operation.
148func (r GetResult) Extract() (*Event, error) {
149 if r.Err != nil {
150 return nil, r.Err
151 }
152
153 var res struct {
154 Res *Event `mapstructure:"event"`
155 }
156
157 if err := mapstructure.Decode(r.Body, &res); err != nil {
158 return nil, err
159 }
160
161 event := r.Body.(map[string]interface{})["event"].(map[string]interface{})
162
163 if date, ok := event["event_time"]; ok && date != nil {
Pratik Mallyae1b6cbb2015-09-09 14:24:14 -0500164 t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
Jon Perritt7cbb42c2015-02-08 21:13:08 -0700165 if err != nil {
166 return nil, err
167 }
168 res.Res.Time = t
169 }
170
171 return res.Res, nil
172}