Rename lb dir to lbs
diff --git a/rackspace/lb/lbs/requests.go b/rackspace/lb/lbs/requests.go
new file mode 100644
index 0000000..98484e9
--- /dev/null
+++ b/rackspace/lb/lbs/requests.go
@@ -0,0 +1,339 @@
+package lbs
+
+import (
+ "errors"
+ "strconv"
+
+ "github.com/racker/perigee"
+
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
+)
+
+// ListOptsBuilder allows extensions to add additional parameters to the
+// List request.
+type ListOptsBuilder interface {
+ ToLBListQuery() (string, error)
+}
+
+// ListOpts allows the filtering and sorting of paginated collections through
+// the API.
+type ListOpts struct {
+ ChangesSince string `q:"changes-since"`
+ Status Status `q:"status"`
+ NodeAddr string `q:"nodeaddress"`
+ Marker string `q:"marker"`
+ Limit int `q:"limit"`
+}
+
+// ToLBListQuery formats a ListOpts into a query string.
+func (opts ListOpts) ToLBListQuery() (string, error) {
+ q, err := gophercloud.BuildQueryString(opts)
+ if err != nil {
+ return "", err
+ }
+ return q.String(), nil
+}
+
+func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
+ url := rootURL(client)
+ if opts != nil {
+ query, err := opts.ToLBListQuery()
+ if err != nil {
+ return pagination.Pager{Err: err}
+ }
+ url += query
+ }
+
+ return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
+ return LBPage{pagination.LinkedPageBase{PageResult: r}}
+ })
+}
+
+type enabledState *bool
+
+var (
+ iTrue = true
+ iFalse = false
+
+ Enabled enabledState = &iTrue
+ Disabled enabledState = &iFalse
+)
+
+// CreateOptsBuilder is the interface options structs have to satisfy in order
+// to be used in the main Create operation in this package. Since many
+// extensions decorate or modify the common logic, it is useful for them to
+// satisfy a basic interface in order for them to be used.
+type CreateOptsBuilder interface {
+ ToLBCreateMap() (map[string]interface{}, error)
+}
+
+// CreateOpts is the common options struct used in this package's Create
+// operation.
+type CreateOpts struct {
+ // Required - name of the load balancer to create. The name must be 128
+ // characters or fewer in length, and all UTF-8 characters are valid.
+ Name string
+
+ // Optional - nodes to be added.
+ Nodes []Node
+
+ // Required - protocol of the service that is being load balanced.
+ Protocol Protocol
+
+ // Optional - enables or disables Half-Closed support for the load balancer.
+ // Half-Closed support provides the ability for one end of the connection to
+ // terminate its output, while still receiving data from the other end. Only
+ // available for TCP/TCP_CLIENT_FIRST protocols.
+ HalfClosed enabledState
+
+ // Optional - the type of virtual IPs you want associated with the load
+ // balancer.
+ VIPs []VIP
+
+ // Optional - the access list management feature allows fine-grained network
+ // access controls to be applied to the load balancer virtual IP address.
+ AccessList string
+
+ // Optional - algorithm that defines how traffic should be directed between
+ // back-end nodes.
+ Algorithm Algorithm
+
+ // Optional - current connection logging configuration.
+ ConnectionLogging *ConnectionLogging
+
+ // Optional - specifies a limit on the number of connections per IP address
+ // to help mitigate malicious or abusive traffic to your applications.
+ //??? ConnThrottle string
+
+ //??? HealthMonitor string
+
+ // Optional - arbitrary information that can be associated with each LB.
+ Metadata map[string]interface{}
+
+ // Optional - port number for the service you are load balancing.
+ Port int
+
+ // Optional - the timeout value for the load balancer and communications with
+ // its nodes. Defaults to 30 seconds with a maximum of 120 seconds.
+ Timeout int
+
+ // Optional - specifies whether multiple requests from clients are directed
+ // to the same node.
+ //??? SessionPersistence
+
+ // Optional - enables or disables HTTP to HTTPS redirection for the load
+ // balancer. When enabled, any HTTP request returns status code 301 (Moved
+ // Permanently), and the requester is redirected to the requested URL via the
+ // HTTPS protocol on port 443. For example, http://example.com/page.html
+ // would be redirected to https://example.com/page.html. Only available for
+ // HTTPS protocol (port=443), or HTTP protocol with a properly configured SSL
+ // termination (secureTrafficOnly=true, securePort=443).
+ HTTPSRedirect enabledState
+}
+
+var (
+ errNameRequired = errors.New("Name is a required attribute")
+ errTimeoutExceeded = errors.New("Timeout must be less than 120")
+)
+
+// ToLBCreateMap casts a CreateOpts struct to a map.
+func (opts CreateOpts) ToLBCreateMap() (map[string]interface{}, error) {
+ lb := make(map[string]interface{})
+
+ if opts.Name == "" {
+ return lb, errNameRequired
+ }
+ if opts.Timeout > 120 {
+ return lb, errTimeoutExceeded
+ }
+
+ lb["name"] = opts.Name
+
+ if len(opts.Nodes) > 0 {
+ nodes := []map[string]interface{}{}
+ for _, n := range opts.Nodes {
+ nodes = append(nodes, map[string]interface{}{
+ "address": n.Address,
+ "port": n.Port,
+ "condition": n.Condition,
+ })
+ }
+ lb["nodes"] = nodes
+ }
+
+ if opts.Protocol != "" {
+ lb["protocol"] = opts.Protocol
+ }
+ if opts.HalfClosed != nil {
+ lb["halfClosed"] = opts.HalfClosed
+ }
+
+ if len(opts.VIPs) > 0 {
+
+ lb["virtualIps"] = opts.VIPs
+ }
+
+ // if opts.AccessList != "" {
+ // lb["accessList"] = opts.AccessList
+ // }
+ if opts.Algorithm != "" {
+ lb["algorithm"] = opts.Algorithm
+ }
+ if opts.ConnectionLogging != nil {
+ lb["connectionLogging"] = &opts.ConnectionLogging
+ }
+ // if opts.ConnThrottle != "" {
+ // lb["connectionThrottle"] = opts.ConnThrottle
+ // }
+ // if opts.HealthMonitor != "" {
+ // lb["healthMonitor"] = opts.HealthMonitor
+ // }
+ if len(opts.Metadata) != 0 {
+ lb["metadata"] = opts.Metadata
+ }
+ if opts.Port > 0 {
+ lb["port"] = opts.Port
+ }
+ if opts.Timeout > 0 {
+ lb["timeout"] = opts.Timeout
+ }
+ // if opts.SessionPersistence != "" {
+ // lb["sessionPersistence"] = opts.SessionPersistence
+ // }
+ if opts.HTTPSRedirect != nil {
+ lb["httpsRedirect"] = &opts.HTTPSRedirect
+ }
+
+ return map[string]interface{}{"loadBalancer": lb}, nil
+}
+
+func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
+ var res CreateResult
+
+ reqBody, err := opts.ToLBCreateMap()
+ if err != nil {
+ res.Err = err
+ return res
+ }
+
+ _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
+ MoreHeaders: c.AuthenticatedHeaders(),
+ ReqBody: &reqBody,
+ Results: &res.Body,
+ OkCodes: []int{200},
+ })
+
+ return res
+}
+
+func Get(c *gophercloud.ServiceClient, id int) GetResult {
+ var res GetResult
+
+ _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
+ MoreHeaders: c.AuthenticatedHeaders(),
+ Results: &res.Body,
+ OkCodes: []int{200},
+ })
+
+ return res
+}
+
+func BulkDelete(c *gophercloud.ServiceClient, ids []int) DeleteResult {
+ var res DeleteResult
+
+ url := rootURL(c)
+ for k, v := range ids {
+ if k == 0 {
+ url += "?"
+ } else {
+ url += "&"
+ }
+ url += "id=" + strconv.Itoa(v)
+ }
+
+ _, res.Err = perigee.Request("DELETE", url, perigee.Options{
+ MoreHeaders: c.AuthenticatedHeaders(),
+ OkCodes: []int{202},
+ })
+
+ return res
+}
+
+func Delete(c *gophercloud.ServiceClient, id int) DeleteResult {
+ var res DeleteResult
+
+ _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
+ MoreHeaders: c.AuthenticatedHeaders(),
+ OkCodes: []int{202},
+ })
+
+ return res
+}
+
+type UpdateOptsBuilder interface {
+ ToLBUpdateMap() (map[string]interface{}, error)
+}
+
+type UpdateOpts struct {
+ Name string
+
+ Protocol Protocol
+
+ HalfClosed enabledState
+
+ Algorithm Algorithm
+
+ Port int
+
+ Timeout int
+
+ HTTPSRedirect enabledState
+}
+
+// ToLBUpdateMap casts a CreateOpts struct to a map.
+func (opts UpdateOpts) ToLBUpdateMap() (map[string]interface{}, error) {
+ lb := make(map[string]interface{})
+
+ if opts.Name != "" {
+ lb["name"] = opts.Name
+ }
+ if opts.Protocol != "" {
+ lb["protocol"] = opts.Protocol
+ }
+ if opts.HalfClosed != nil {
+ lb["halfClosed"] = opts.HalfClosed
+ }
+ if opts.Algorithm != "" {
+ lb["algorithm"] = opts.Algorithm
+ }
+ if opts.Port > 0 {
+ lb["port"] = opts.Port
+ }
+ if opts.Timeout > 0 {
+ lb["timeout"] = opts.Timeout
+ }
+ if opts.HTTPSRedirect != nil {
+ lb["httpsRedirect"] = &opts.HTTPSRedirect
+ }
+
+ return map[string]interface{}{"loadBalancer": lb}, nil
+}
+
+func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult {
+ var res UpdateResult
+
+ reqBody, err := opts.ToLBUpdateMap()
+ if err != nil {
+ res.Err = err
+ return res
+ }
+
+ _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
+ MoreHeaders: c.AuthenticatedHeaders(),
+ ReqBody: &reqBody,
+ OkCodes: []int{200},
+ })
+
+ return res
+}