1package rules 2 3import ( 4 "github.com/gophercloud/gophercloud" 5 "github.com/gophercloud/gophercloud/pagination" 6) 7 8type ( 9 // Protocol represents a valid rule protocol. 10 Protocol string 11) 12 13const ( 14 // ProtocolAny is to allow any protocol. 15 ProtocolAny Protocol = "any" 16 17 // ProtocolICMP is to allow the ICMP protocol. 18 ProtocolICMP Protocol = "icmp" 19 20 // ProtocolTCP is to allow the TCP protocol. 21 ProtocolTCP Protocol = "tcp" 22 23 // ProtocolUDP is to allow the UDP protocol. 24 ProtocolUDP Protocol = "udp" 25) 26 27// ListOptsBuilder allows extensions to add additional parameters to the 28// List request. 29type ListOptsBuilder interface { 30 ToRuleListQuery() (string, error) 31} 32 33// ListOpts allows the filtering and sorting of paginated collections through 34// the API. Filtering is achieved by passing in struct field values that map to 35// the Firewall rule attributes you want to see returned. SortKey allows you to 36// sort by a particular firewall rule attribute. SortDir sets the direction, and 37// is either `asc' or `desc'. Marker and Limit are used for pagination. 38type ListOpts struct { 39 TenantID string `q:"tenant_id"` 40 ProjectID string `q:"project_id"` 41 Name string `q:"name"` 42 Description string `q:"description"` 43 Protocol string `q:"protocol"` 44 Action string `q:"action"` 45 IPVersion int `q:"ip_version"` 46 SourceIPAddress string `q:"source_ip_address"` 47 DestinationIPAddress string `q:"destination_ip_address"` 48 SourcePort string `q:"source_port"` 49 DestinationPort string `q:"destination_port"` 50 Enabled bool `q:"enabled"` 51 ID string `q:"id"` 52 Limit int `q:"limit"` 53 Marker string `q:"marker"` 54 SortKey string `q:"sort_key"` 55 SortDir string `q:"sort_dir"` 56} 57 58// ToRuleListQuery formats a ListOpts into a query string. 59func (opts ListOpts) ToRuleListQuery() (string, error) { 60 q, err := gophercloud.BuildQueryString(opts) 61 if err != nil { 62 return "", err 63 } 64 return q.String(), nil 65} 66 67// List returns a Pager which allows you to iterate over a collection of 68// firewall rules. It accepts a ListOpts struct, which allows you to filter 69// and sort the returned collection for greater efficiency. 70// 71// Default policy settings return only those firewall rules that are owned by 72// the tenant who submits the request, unless an admin user submits the request. 73func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 74 url := rootURL(c) 75 76 if opts != nil { 77 query, err := opts.ToRuleListQuery() 78 if err != nil { 79 return pagination.Pager{Err: err} 80 } 81 url += query 82 } 83 84 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { 85 return RulePage{pagination.LinkedPageBase{PageResult: r}} 86 }) 87} 88 89// CreateOptsBuilder allows extensions to add additional parameters to the 90// Create request. 91type CreateOptsBuilder interface { 92 ToRuleCreateMap() (map[string]interface{}, error) 93} 94 95// CreateOpts contains all the values needed to create a new firewall rule. 96type CreateOpts struct { 97 Protocol Protocol `json:"protocol" required:"true"` 98 Action string `json:"action" required:"true"` 99 TenantID string `json:"tenant_id,omitempty"` 100 ProjectID string `json:"project_id,omitempty"` 101 Name string `json:"name,omitempty"` 102 Description string `json:"description,omitempty"` 103 IPVersion gophercloud.IPVersion `json:"ip_version,omitempty"` 104 SourceIPAddress string `json:"source_ip_address,omitempty"` 105 DestinationIPAddress string `json:"destination_ip_address,omitempty"` 106 SourcePort string `json:"source_port,omitempty"` 107 DestinationPort string `json:"destination_port,omitempty"` 108 Shared *bool `json:"shared,omitempty"` 109 Enabled *bool `json:"enabled,omitempty"` 110} 111 112// ToRuleCreateMap casts a CreateOpts struct to a map. 113func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) { 114 b, err := gophercloud.BuildRequestBody(opts, "firewall_rule") 115 if err != nil { 116 return nil, err 117 } 118 119 if m := b["firewall_rule"].(map[string]interface{}); m["protocol"] == "any" { 120 m["protocol"] = nil 121 } 122 123 return b, nil 124} 125 126// Create accepts a CreateOpts struct and uses the values to create a new 127// firewall rule. 128func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 129 b, err := opts.ToRuleCreateMap() 130 if err != nil { 131 r.Err = err 132 return 133 } 134 resp, err := c.Post(rootURL(c), b, &r.Body, nil) 135 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 136 return 137} 138 139// Get retrieves a particular firewall rule based on its unique ID. 140func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { 141 resp, err := c.Get(resourceURL(c, id), &r.Body, nil) 142 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 143 return 144} 145 146// UpdateOptsBuilder allows extensions to add additional parameters to the 147// Update request. 148type UpdateOptsBuilder interface { 149 ToRuleUpdateMap() (map[string]interface{}, error) 150} 151 152// UpdateOpts contains the values used when updating a firewall rule. 153// These fields are all pointers so that unset fields will not cause the 154// existing Rule attribute to be removed. 155type UpdateOpts struct { 156 Protocol *string `json:"protocol,omitempty"` 157 Action *string `json:"action,omitempty"` 158 Name *string `json:"name,omitempty"` 159 Description *string `json:"description,omitempty"` 160 IPVersion *gophercloud.IPVersion `json:"ip_version,omitempty"` 161 SourceIPAddress *string `json:"source_ip_address,omitempty"` 162 DestinationIPAddress *string `json:"destination_ip_address,omitempty"` 163 SourcePort *string `json:"source_port,omitempty"` 164 DestinationPort *string `json:"destination_port,omitempty"` 165 Shared *bool `json:"shared,omitempty"` 166 Enabled *bool `json:"enabled,omitempty"` 167} 168 169// ToRuleUpdateMap casts a UpdateOpts struct to a map. 170func (opts UpdateOpts) ToRuleUpdateMap() (map[string]interface{}, error) { 171 return gophercloud.BuildRequestBody(opts, "firewall_rule") 172} 173 174// Update allows firewall policies to be updated. 175func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { 176 b, err := opts.ToRuleUpdateMap() 177 if err != nil { 178 r.Err = err 179 return 180 } 181 resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ 182 OkCodes: []int{200}, 183 }) 184 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 185 return 186} 187 188// Delete will permanently delete a particular firewall rule based on its 189// unique ID. 190func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { 191 resp, err := c.Delete(resourceURL(c, id), nil) 192 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 193 return 194} 195