results.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package policies
  2. import (
  3. "encoding/json"
  4. "devel.mephi.ru/iacherepanov/openstack-gophercloud"
  5. "devel.mephi.ru/iacherepanov/openstack-gophercloud/internal"
  6. "devel.mephi.ru/iacherepanov/openstack-gophercloud/pagination"
  7. )
  8. // Policy is an arbitrarily serialized policy engine rule
  9. // set to be consumed by a remote service.
  10. type Policy struct {
  11. // ID is the unique ID of the policy.
  12. ID string `json:"id"`
  13. // Blob is the policy rule as a serialized blob.
  14. Blob string `json:"blob"`
  15. // Type is the MIME media type of the serialized policy blob.
  16. Type string `json:"type"`
  17. // Links contains referencing links to the policy.
  18. Links map[string]interface{} `json:"links"`
  19. // Extra is a collection of miscellaneous key/values.
  20. Extra map[string]interface{} `json:"-"`
  21. }
  22. func (r *Policy) UnmarshalJSON(b []byte) error {
  23. type tmp Policy
  24. var s struct {
  25. tmp
  26. Extra map[string]interface{} `json:"extra"`
  27. }
  28. err := json.Unmarshal(b, &s)
  29. if err != nil {
  30. return err
  31. }
  32. *r = Policy(s.tmp)
  33. // Collect other fields and bundle them into Extra
  34. // but only if a field titled "extra" wasn't sent.
  35. if s.Extra != nil {
  36. r.Extra = s.Extra
  37. } else {
  38. var result interface{}
  39. err := json.Unmarshal(b, &result)
  40. if err != nil {
  41. return err
  42. }
  43. if resultMap, ok := result.(map[string]interface{}); ok {
  44. r.Extra = internal.RemainingKeys(Policy{}, resultMap)
  45. }
  46. }
  47. return err
  48. }
  49. type policyResult struct {
  50. gophercloud.Result
  51. }
  52. // CreateResult is the response from a Create operation. Call its Extract method
  53. // to interpret it as a Policy
  54. type CreateResult struct {
  55. policyResult
  56. }
  57. // GetResult is the response from a Get operation. Call its Extract method
  58. // to interpret it as a Policy.
  59. type GetResult struct {
  60. policyResult
  61. }
  62. // UpdateResult is the response from an Update operation. Call its Extract
  63. // method to interpret it as a Policy.
  64. type UpdateResult struct {
  65. policyResult
  66. }
  67. // DeleteResult is the response from a Delete operation. Call its ExtractErr to
  68. // determine if the request succeeded or failed.
  69. type DeleteResult struct {
  70. gophercloud.ErrResult
  71. }
  72. // PolicyPage is a single page of Policy results.
  73. type PolicyPage struct {
  74. pagination.LinkedPageBase
  75. }
  76. // IsEmpty determines whether or not a page of Policies contains any results.
  77. func (r PolicyPage) IsEmpty() (bool, error) {
  78. policies, err := ExtractPolicies(r)
  79. return len(policies) == 0, err
  80. }
  81. // NextPageURL extracts the "next" link from the links section of the result.
  82. func (r PolicyPage) NextPageURL() (string, error) {
  83. var s struct {
  84. Links struct {
  85. Next string `json:"next"`
  86. Previous string `json:"previous"`
  87. } `json:"links"`
  88. }
  89. err := r.ExtractInto(&s)
  90. if err != nil {
  91. return "", err
  92. }
  93. return s.Links.Next, err
  94. }
  95. // ExtractPolicies returns a slice of Policies
  96. // contained in a single page of results.
  97. func ExtractPolicies(r pagination.Page) ([]Policy, error) {
  98. var s struct {
  99. Policies []Policy `json:"policies"`
  100. }
  101. err := (r.(PolicyPage)).ExtractInto(&s)
  102. return s.Policies, err
  103. }
  104. // Extract interprets any policyResults as a Policy.
  105. func (r policyResult) Extract() (*Policy, error) {
  106. var s struct {
  107. Policy *Policy `json:"policy"`
  108. }
  109. err := r.ExtractInto(&s)
  110. return s.Policy, err
  111. }