summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/elb/elb.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/elb/elb.go')
-rw-r--r--vendor/github.com/goamz/goamz/elb/elb.go435
1 files changed, 435 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/elb/elb.go b/vendor/github.com/goamz/goamz/elb/elb.go
new file mode 100644
index 000000000..0127435a7
--- /dev/null
+++ b/vendor/github.com/goamz/goamz/elb/elb.go
@@ -0,0 +1,435 @@
+// This package provides types and functions to interact Elastic Load Balancing service
+package elb
+
+import (
+ "encoding/xml"
+ "fmt"
+ "net/http"
+ "net/url"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/goamz/goamz/aws"
+)
+
+type ELB struct {
+ aws.Auth
+ aws.Region
+}
+
+func New(auth aws.Auth, region aws.Region) *ELB {
+ return &ELB{auth, region}
+}
+
+// The CreateLoadBalancer type encapsulates options for the respective request in AWS.
+// The creation of a Load Balancer may differ inside EC2 and VPC.
+//
+// See http://goo.gl/4QFKi for more details.
+type CreateLoadBalancer struct {
+ Name string
+ AvailabilityZones []string
+ Listeners []Listener
+ Scheme string
+ SecurityGroups []string
+ Subnets []string
+}
+
+// Listener to configure in Load Balancer.
+//
+// See http://goo.gl/NJQCj for more details.
+type Listener struct {
+ InstancePort int
+ InstanceProtocol string
+ LoadBalancerPort int
+ Protocol string
+ SSLCertificateId string
+}
+
+// Response to a CreateLoadBalance request.
+//
+// See http://goo.gl/4QFKi for more details.
+type CreateLoadBalancerResp struct {
+ DNSName string `xml:"CreateLoadBalancerResult>DNSName"`
+}
+
+type SimpleResp struct {
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// Creates a Load Balancer in Amazon.
+//
+// See http://goo.gl/4QFKi for more details.
+func (elb *ELB) CreateLoadBalancer(options *CreateLoadBalancer) (resp *CreateLoadBalancerResp, err error) {
+ params := makeCreateParams(options)
+ resp = new(CreateLoadBalancerResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return
+}
+
+// Deletes a Load Balancer.
+//
+// See http://goo.gl/sDmPp for more details.
+func (elb *ELB) DeleteLoadBalancer(name string) (resp *SimpleResp, err error) {
+ params := map[string]string{
+ "Action": "DeleteLoadBalancer",
+ "LoadBalancerName": name,
+ }
+ resp = new(SimpleResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+type RegisterInstancesResp struct {
+ InstanceIds []string `xml:"RegisterInstancesWithLoadBalancerResult>Instances>member>InstanceId"`
+}
+
+// Register N instances with a given Load Balancer.
+//
+// See http://goo.gl/x9hru for more details.
+func (elb *ELB) RegisterInstancesWithLoadBalancer(instanceIds []string, lbName string) (resp *RegisterInstancesResp, err error) {
+ // TODO: change params order and use ..., e.g (lbName string, instanceIds ...string)
+ params := map[string]string{
+ "Action": "RegisterInstancesWithLoadBalancer",
+ "LoadBalancerName": lbName,
+ }
+ for i, instanceId := range instanceIds {
+ key := fmt.Sprintf("Instances.member.%d.InstanceId", i+1)
+ params[key] = instanceId
+ }
+ resp = new(RegisterInstancesResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// Deregister N instances from a given Load Balancer.
+//
+// See http://goo.gl/Hgo4U for more details.
+func (elb *ELB) DeregisterInstancesFromLoadBalancer(instanceIds []string, lbName string) (resp *SimpleResp, err error) {
+ // TODO: change params order and use ..., e.g (lbName string, instanceIds ...string)
+ params := map[string]string{
+ "Action": "DeregisterInstancesFromLoadBalancer",
+ "LoadBalancerName": lbName,
+ }
+ for i, instanceId := range instanceIds {
+ key := fmt.Sprintf("Instances.member.%d.InstanceId", i+1)
+ params[key] = instanceId
+ }
+ resp = new(SimpleResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+type DescribeLoadBalancerResp struct {
+ LoadBalancerDescriptions []LoadBalancerDescription `xml:"DescribeLoadBalancersResult>LoadBalancerDescriptions>member"`
+}
+
+type LoadBalancerDescription struct {
+ AvailabilityZones []string `xml:"AvailabilityZones>member"`
+ BackendServerDescriptions []BackendServerDescriptions `xml:"BackendServerDescriptions>member"`
+ CanonicalHostedZoneName string `xml:"CanonicalHostedZoneName"`
+ CanonicalHostedZoneNameId string `xml:"CanonicalHostedZoneNameID"`
+ CreatedTime time.Time `xml:"CreatedTime"`
+ DNSName string `xml:"DNSName"`
+ HealthCheck HealthCheck `xml:"HealthCheck"`
+ Instances []Instance `xml:"Instances>member"`
+ ListenerDescriptions []ListenerDescription `xml:"ListenerDescriptions>member"`
+ LoadBalancerName string `xml:"LoadBalancerName"`
+ Policies Policies `xml:"Policies"`
+ Scheme string `xml:"Scheme"`
+ SecurityGroups []string `xml:"SecurityGroups>member"` //vpc only
+ SourceSecurityGroup SourceSecurityGroup `xml:"SourceSecurityGroup"`
+ Subnets []string `xml:"Subnets>member"`
+ VPCId string `xml:"VPCId"`
+}
+
+// Describe Load Balancers.
+// It can be used to describe all Load Balancers or specific ones.
+//
+// See http://goo.gl/wofJA for more details.
+func (elb *ELB) DescribeLoadBalancers(names ...string) (*DescribeLoadBalancerResp, error) {
+ params := map[string]string{"Action": "DescribeLoadBalancers"}
+ for i, name := range names {
+ index := fmt.Sprintf("LoadBalancerNames.member.%d", i+1)
+ params[index] = name
+ }
+ resp := new(DescribeLoadBalancerResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+type BackendServerDescriptions struct {
+ InstancePort int `xml:"InstancePort"`
+ PolicyNames []string `xml:"PolicyNames>member"`
+}
+
+type HealthCheck struct {
+ HealthyThreshold int `xml:"HealthyThreshold"`
+ Interval int `xml:"Interval"`
+ Target string `xml:"Target"`
+ Timeout int `xml:"Timeout"`
+ UnhealthyThreshold int `xml:"UnhealthyThreshold"`
+}
+
+type Instance struct {
+ InstanceId string `xml:"InstanceId"`
+}
+
+type ListenerDescription struct {
+ Listener Listener `xml:"Listener"`
+ PolicyNames []string `xml:"PolicyNames>member"`
+}
+
+type Policies struct {
+ AppCookieStickinessPolicies []AppCookieStickinessPolicies `xml:"AppCookieStickinessPolicies>member"`
+ LBCookieStickinessPolicies []LBCookieStickinessPolicies `xml:"LBCookieStickinessPolicies>member"`
+ OtherPolicies []string `xml:"OtherPolicies>member"`
+}
+
+// see http://goo.gl/clXGV for more information.
+type AppCookieStickinessPolicies struct {
+ CookieName string `xml:"CookieName"`
+ PolicyName string `xml:"PolicyName"`
+}
+
+type LBCookieStickinessPolicies struct {
+ CookieExpirationPeriod int `xml:"CookieExpirationPeriod"`
+ PolicyName string `xml:"PolicyName"`
+}
+
+type SourceSecurityGroup struct {
+ GroupName string `xml:"GroupName"`
+ OwnerAlias string `xml:"OwnerAlias"`
+}
+
+// Represents a XML response for DescribeInstanceHealth action
+//
+// See http://goo.gl/ovIB1 for more information.
+type DescribeInstanceHealthResp struct {
+ InstanceStates []InstanceState `xml:"DescribeInstanceHealthResult>InstanceStates>member"`
+}
+
+// See http://goo.gl/dzWfP for more information.
+type InstanceState struct {
+ Description string `xml:"Description"`
+ InstanceId string `xml:"InstanceId"`
+ ReasonCode string `xml:"ReasonCode"`
+ State string `xml:"State"`
+}
+
+// Describe instance health.
+//
+// See http://goo.gl/ovIB1 for more information.
+func (elb *ELB) DescribeInstanceHealth(lbName string, instanceIds ...string) (*DescribeInstanceHealthResp, error) {
+ params := map[string]string{
+ "Action": "DescribeInstanceHealth",
+ "LoadBalancerName": lbName,
+ }
+ for i, iId := range instanceIds {
+ key := fmt.Sprintf("Instances.member.%d.InstanceId", i+1)
+ params[key] = iId
+ }
+ resp := new(DescribeInstanceHealthResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+type HealthCheckResp struct {
+ HealthCheck *HealthCheck `xml:"ConfigureHealthCheckResult>HealthCheck"`
+}
+
+// Configure health check for a LB
+//
+// See http://goo.gl/2HE6a for more information
+func (elb *ELB) ConfigureHealthCheck(lbName string, healthCheck *HealthCheck) (*HealthCheckResp, error) {
+ params := map[string]string{
+ "Action": "ConfigureHealthCheck",
+ "LoadBalancerName": lbName,
+ "HealthCheck.HealthyThreshold": strconv.Itoa(healthCheck.HealthyThreshold),
+ "HealthCheck.Interval": strconv.Itoa(healthCheck.Interval),
+ "HealthCheck.Target": healthCheck.Target,
+ "HealthCheck.Timeout": strconv.Itoa(healthCheck.Timeout),
+ "HealthCheck.UnhealthyThreshold": strconv.Itoa(healthCheck.UnhealthyThreshold),
+ }
+ resp := new(HealthCheckResp)
+ if err := elb.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// Add tags to the named ELB
+//
+// Note that AWS only accepts one ELB name at a time (even though it is sent as a list)
+//
+// See http://goo.gl/6JW4Wf for the rest of the details
+func (elb *ELB) AddTags(elbName string, tags map[string]string) (*SimpleResp, error) {
+ var sortedKeys []string
+ params := make(map[string]string)
+ response := &SimpleResp{}
+
+ for tagKey := range tags {
+ sortedKeys = append(sortedKeys, tagKey)
+ }
+
+ sort.Strings(sortedKeys)
+
+ for _, key := range sortedKeys {
+ number := len(tags)
+ params[fmt.Sprintf("Tags.member.%d.Key", number)] = key
+ params[fmt.Sprintf("Tags.member.%d.Value", number)] = tags[key]
+ delete(tags, key)
+ }
+
+ params["Action"] = "AddTags"
+ params["LoadBalancerNames.member.1"] = elbName
+
+ if err := elb.query(params, response); err != nil {
+ return nil, err
+ }
+
+ return response, nil
+}
+
+// Remove tags from the named ELB
+//
+// Note that AWS only accepts one ELB name at a time (even though it is sent as a list)
+//
+// see http://goo.gl/ochFqo for more details
+
+func (elb *ELB) RemoveTags(elbName string, tagKeys []string) (*SimpleResp, error) {
+ response := &SimpleResp{}
+ params := make(map[string]string)
+
+ params["Action"] = "RemoveTags"
+ params["LoadBalancerNames.member.1"] = elbName
+
+ for i, tagKey := range tagKeys {
+ params[fmt.Sprintf("Tags.member.%d.Key", i+1)] = tagKey
+ }
+
+ if err := elb.query(params, response); err != nil {
+ return nil, err
+ }
+
+ return response, nil
+}
+
+func (elb *ELB) query(params map[string]string, resp interface{}) error {
+ params["Version"] = "2012-06-01"
+ params["Timestamp"] = time.Now().In(time.UTC).Format(time.RFC3339)
+ data := strings.NewReader(multimap(params).Encode())
+ hreq, err := http.NewRequest("GET", elb.Region.ELBEndpoint+"/", data)
+ if err != nil {
+ return err
+ }
+
+ hreq.URL.RawQuery = multimap(params).Encode()
+ token := elb.Auth.Token()
+ if token != "" {
+ hreq.Header.Set("X-Amz-Security-Token", token)
+ }
+
+ signer := aws.NewV4Signer(elb.Auth, "elasticloadbalancing", elb.Region)
+ signer.Sign(hreq)
+
+ r, err := http.DefaultClient.Do(hreq)
+
+ if err != nil {
+ return err
+ }
+ defer r.Body.Close()
+ if r.StatusCode != 200 {
+ return buildError(r)
+ }
+ return xml.NewDecoder(r.Body).Decode(resp)
+}
+
+// Error encapsulates an error returned by ELB.
+type Error struct {
+ // HTTP status code
+ StatusCode int
+ // AWS error code
+ Code string
+ // The human-oriented error message
+ Message string
+}
+
+func (err *Error) Error() string {
+ if err.Code == "" {
+ return err.Message
+ }
+
+ return fmt.Sprintf("%s (%s)", err.Message, err.Code)
+}
+
+type xmlErrors struct {
+ Errors []Error `xml:"Error"`
+}
+
+func buildError(r *http.Response) error {
+ var (
+ err Error
+ errors xmlErrors
+ )
+ xml.NewDecoder(r.Body).Decode(&errors)
+ if len(errors.Errors) > 0 {
+ err = errors.Errors[0]
+ }
+ err.StatusCode = r.StatusCode
+ if err.Message == "" {
+ err.Message = r.Status
+ }
+ return &err
+}
+
+func multimap(p map[string]string) url.Values {
+ q := make(url.Values, len(p))
+ for k, v := range p {
+ q[k] = []string{v}
+ }
+ return q
+}
+
+func makeCreateParams(createLB *CreateLoadBalancer) map[string]string {
+ params := make(map[string]string)
+ params["LoadBalancerName"] = createLB.Name
+ params["Action"] = "CreateLoadBalancer"
+ if createLB.Scheme != "" {
+ params["Scheme"] = createLB.Scheme
+ }
+ for i, s := range createLB.SecurityGroups {
+ key := fmt.Sprintf("SecurityGroups.member.%d", i+1)
+ params[key] = s
+ }
+ for i, s := range createLB.Subnets {
+ key := fmt.Sprintf("Subnets.member.%d", i+1)
+ params[key] = s
+ }
+ for i, l := range createLB.Listeners {
+ key := "Listeners.member.%d.%s"
+ index := i + 1
+ params[fmt.Sprintf(key, index, "InstancePort")] = strconv.Itoa(l.InstancePort)
+ params[fmt.Sprintf(key, index, "InstanceProtocol")] = l.InstanceProtocol
+ params[fmt.Sprintf(key, index, "Protocol")] = l.Protocol
+ params[fmt.Sprintf(key, index, "LoadBalancerPort")] = strconv.Itoa(l.LoadBalancerPort)
+ }
+ for i, az := range createLB.AvailabilityZones {
+ key := fmt.Sprintf("AvailabilityZones.member.%d", i+1)
+ params[key] = az
+ }
+ return params
+}