github.com/gophercloud/gophercloud@v1.11.0/openstack/clustering/v1/policies/results.go (about) 1 package policies 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 "time" 8 9 "github.com/gophercloud/gophercloud" 10 "github.com/gophercloud/gophercloud/pagination" 11 ) 12 13 // Policy represents a clustering policy in the Openstack cloud. 14 type Policy struct { 15 CreatedAt time.Time `json:"-"` 16 Data map[string]interface{} `json:"data"` 17 Domain string `json:"domain"` 18 ID string `json:"id"` 19 Name string `json:"name"` 20 Project string `json:"project"` 21 Spec Spec `json:"spec"` 22 Type string `json:"type"` 23 UpdatedAt time.Time `json:"-"` 24 User string `json:"user"` 25 } 26 27 func (r *Policy) UnmarshalJSON(b []byte) error { 28 type tmp Policy 29 var s struct { 30 tmp 31 CreatedAt string `json:"created_at,omitempty"` 32 UpdatedAt string `json:"updated_at,omitempty"` 33 } 34 err := json.Unmarshal(b, &s) 35 if err != nil { 36 return err 37 } 38 *r = Policy(s.tmp) 39 40 if s.CreatedAt != "" { 41 r.CreatedAt, err = time.Parse(gophercloud.RFC3339MilliNoZ, s.CreatedAt) 42 if err != nil { 43 r.CreatedAt, err = time.Parse(time.RFC3339, s.CreatedAt) 44 if err != nil { 45 return err 46 } 47 } 48 } 49 50 if s.UpdatedAt != "" { 51 r.UpdatedAt, err = time.Parse(gophercloud.RFC3339MilliNoZ, s.UpdatedAt) 52 if err != nil { 53 r.UpdatedAt, err = time.Parse(time.RFC3339, s.UpdatedAt) 54 if err != nil { 55 return err 56 } 57 } 58 } 59 60 return nil 61 } 62 63 // Spec represents an OpenStack clustering policy spec. 64 type Spec struct { 65 Description string `json:"description"` 66 Properties map[string]interface{} `json:"properties"` 67 Type string `json:"type"` 68 Version string `json:"-"` 69 } 70 71 func (r *Spec) UnmarshalJSON(b []byte) error { 72 type tmp Spec 73 var s struct { 74 tmp 75 Version interface{} `json:"version"` 76 } 77 err := json.Unmarshal(b, &s) 78 if err != nil { 79 return err 80 } 81 *r = Spec(s.tmp) 82 83 switch t := s.Version.(type) { 84 case float64: 85 if t == 1 { 86 r.Version = fmt.Sprintf("%.1f", t) 87 } else { 88 r.Version = strconv.FormatFloat(t, 'f', -1, 64) 89 } 90 case string: 91 r.Version = t 92 } 93 94 return nil 95 } 96 97 func (r Spec) MarshalJSON() ([]byte, error) { 98 spec := struct { 99 Type string `json:"type"` 100 Version string `json:"version"` 101 Properties map[string]interface{} `json:"properties"` 102 }{ 103 Type: r.Type, 104 Version: r.Version, 105 Properties: r.Properties, 106 } 107 return json.Marshal(spec) 108 } 109 110 // policyResult is the resposne of a base Policy result. 111 type policyResult struct { 112 gophercloud.Result 113 } 114 115 // Extract interpets any policyResult-base result as a Policy. 116 func (r policyResult) Extract() (*Policy, error) { 117 var s struct { 118 Policy *Policy `json:"policy"` 119 } 120 err := r.ExtractInto(&s) 121 122 return s.Policy, err 123 } 124 125 // CreateResult is the result of an Update operation. Call its Extract 126 // method to interpret it as a Policy. 127 type CreateResult struct { 128 policyResult 129 } 130 131 // GetResult is the result of a Get operation. Call its Extract method to 132 // interpret it as a Policy. 133 type GetResult struct { 134 policyResult 135 } 136 137 // UpdateResult is the result of an Update operation. Call its Extract 138 // method to interpret it as a Policy. 139 type UpdateResult struct { 140 policyResult 141 } 142 143 // ValidateResult is the result of a Validate operation. Call its Extract 144 // method to interpret it as a Policy. 145 type ValidateResult struct { 146 policyResult 147 } 148 149 // DeleteResult is the result of a Delete operation. Call its Extract 150 // method to interpret it as a DeleteHeader. 151 type DeleteResult struct { 152 gophercloud.ErrResult 153 } 154 155 // PolicyPage contains a list page of all policies from a List call. 156 type PolicyPage struct { 157 pagination.MarkerPageBase 158 } 159 160 // IsEmpty determines if a PolicyPage contains any results. 161 func (page PolicyPage) IsEmpty() (bool, error) { 162 if page.StatusCode == 204 { 163 return true, nil 164 } 165 166 policies, err := ExtractPolicies(page) 167 return len(policies) == 0, err 168 } 169 170 // LastMarker returns the last policy ID in a ListResult. 171 func (r PolicyPage) LastMarker() (string, error) { 172 policies, err := ExtractPolicies(r) 173 if err != nil { 174 return "", err 175 } 176 if len(policies) == 0 { 177 return "", nil 178 } 179 return policies[len(policies)-1].ID, nil 180 } 181 182 // ExtractPolicies returns a slice of Policies from the List operation. 183 func ExtractPolicies(r pagination.Page) ([]Policy, error) { 184 var s struct { 185 Policies []Policy `json:"policies"` 186 } 187 err := (r.(PolicyPage)).ExtractInto(&s) 188 return s.Policies, err 189 }