1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
package groups
import (
"encoding/json"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
"github.com/gophercloud/gophercloud/pagination"
)
// SecGroup represents a container for security group rules.
type SecGroup struct {
// The UUID for the security group.
ID string
// Human-readable name for the security group. Might not be unique.
// Cannot be named "default" as that is automatically created for a tenant.
Name string
// The security group description.
Description string
// A slice of security group rules that dictate the permitted behaviour for
// traffic entering and leaving the group.
Rules []rules.SecGroupRule `json:"security_group_rules"`
// TenantID is the project owner of the security group.
TenantID string `json:"tenant_id"`
// UpdatedAt and CreatedAt contain ISO-8601 timestamps of when the state of the
// security group last changed, and when it was created.
UpdatedAt time.Time `json:"-"`
CreatedAt time.Time `json:"-"`
// ProjectID is the project owner of the security group.
ProjectID string `json:"project_id"`
// Tags optionally set via extensions/attributestags
Tags []string `json:"tags"`
}
func (r *SecGroup) UnmarshalJSON(b []byte) error {
type tmp SecGroup
// Support for older neutron time format
var s1 struct {
tmp
CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"`
UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"`
}
err := json.Unmarshal(b, &s1)
if err == nil {
*r = SecGroup(s1.tmp)
r.CreatedAt = time.Time(s1.CreatedAt)
r.UpdatedAt = time.Time(s1.UpdatedAt)
return nil
}
// Support for newer neutron time format
var s2 struct {
tmp
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
err = json.Unmarshal(b, &s2)
if err != nil {
return err
}
*r = SecGroup(s2.tmp)
r.CreatedAt = time.Time(s2.CreatedAt)
r.UpdatedAt = time.Time(s2.UpdatedAt)
return nil
}
// SecGroupPage is the page returned by a pager when traversing over a
// collection of security groups.
type SecGroupPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of security groups has
// reached the end of a page and the pager seeks to traverse over a new one. In
// order to do this, it needs to construct the next page's URL.
func (r SecGroupPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"security_groups_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a SecGroupPage struct is empty.
func (r SecGroupPage) IsEmpty() (bool, error) {
if r.StatusCode == 204 {
return true, nil
}
is, err := ExtractGroups(r)
return len(is) == 0, err
}
// ExtractGroups accepts a Page struct, specifically a SecGroupPage struct,
// and extracts the elements into a slice of SecGroup structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractGroups(r pagination.Page) ([]SecGroup, error) {
var s struct {
SecGroups []SecGroup `json:"security_groups"`
}
err := (r.(SecGroupPage)).ExtractInto(&s)
return s.SecGroups, err
}
type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a security group.
func (r commonResult) Extract() (*SecGroup, error) {
var s struct {
SecGroup *SecGroup `json:"security_group"`
}
err := r.ExtractInto(&s)
return s.SecGroup, err
}
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a SecGroup.
type CreateResult struct {
commonResult
}
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a SecGroup.
type UpdateResult struct {
commonResult
}
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a SecGroup.
type GetResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
|