mirror of https://github.com/k3s-io/k3s
Merge pull request #5182 from justinsb/aws_bump_goamz
Add dependency on ELB functionality of goamzpull/6/head
commit
828f9eaa7d
|
@ -189,6 +189,10 @@
|
|||
"ImportPath": "github.com/mitchellh/goamz/ec2",
|
||||
"Rev": "703cfb45985762869e465f37ed030ff01615ff1e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/goamz/elb",
|
||||
"Rev": "703cfb45985762869e465f37ed030ff01615ff1e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
||||
"Rev": "740c764bc6149d3f1806231418adb9f52c11bcbf"
|
||||
|
|
|
@ -0,0 +1,575 @@
|
|||
// The elb package provides types and functions for interaction with the AWS
|
||||
// Elastic Load Balancing service (ELB)
|
||||
package elb
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/goamz/aws"
|
||||
)
|
||||
|
||||
// The ELB type encapsulates operations operations with the elb endpoint.
|
||||
type ELB struct {
|
||||
aws.Auth
|
||||
aws.Region
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
const APIVersion = "2012-06-01"
|
||||
|
||||
// New creates a new ELB instance.
|
||||
func New(auth aws.Auth, region aws.Region) *ELB {
|
||||
return NewWithClient(auth, region, aws.RetryingClient)
|
||||
}
|
||||
|
||||
func NewWithClient(auth aws.Auth, region aws.Region, httpClient *http.Client) *ELB {
|
||||
return &ELB{auth, region, httpClient}
|
||||
}
|
||||
|
||||
func (elb *ELB) query(params map[string]string, resp interface{}) error {
|
||||
params["Version"] = APIVersion
|
||||
params["Timestamp"] = time.Now().In(time.UTC).Format(time.RFC3339)
|
||||
|
||||
endpoint, err := url.Parse(elb.Region.ELBEndpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sign(elb.Auth, "GET", "/", params, endpoint.Host)
|
||||
endpoint.RawQuery = multimap(params).Encode()
|
||||
r, err := elb.httpClient.Get(endpoint.String())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Body.Close()
|
||||
if r.StatusCode > 200 {
|
||||
return buildError(r)
|
||||
}
|
||||
|
||||
decoder := xml.NewDecoder(r.Body)
|
||||
decodedBody := decoder.Decode(resp)
|
||||
|
||||
return decodedBody
|
||||
}
|
||||
|
||||
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 makeParams(action string) map[string]string {
|
||||
params := make(map[string]string)
|
||||
params["Action"] = action
|
||||
return params
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ELB objects
|
||||
|
||||
// A listener attaches to an elb
|
||||
type Listener struct {
|
||||
InstancePort int64 `xml:"Listener>InstancePort"`
|
||||
InstanceProtocol string `xml:"Listener>InstanceProtocol"`
|
||||
SSLCertificateId string `xml:"Listener>SSLCertificateId"`
|
||||
LoadBalancerPort int64 `xml:"Listener>LoadBalancerPort"`
|
||||
Protocol string `xml:"Listener>Protocol"`
|
||||
}
|
||||
|
||||
// An Instance attaches to an elb
|
||||
type Instance struct {
|
||||
InstanceId string `xml:"InstanceId"`
|
||||
}
|
||||
|
||||
// A tag attached to an elb
|
||||
type Tag struct {
|
||||
Key string `xml:"Key"`
|
||||
Value string `xml:"Value"`
|
||||
}
|
||||
|
||||
// An InstanceState from an elb health query
|
||||
type InstanceState struct {
|
||||
InstanceId string `xml:"InstanceId"`
|
||||
Description string `xml:"Description"`
|
||||
State string `xml:"State"`
|
||||
ReasonCode string `xml:"ReasonCode"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AddTags
|
||||
|
||||
type AddTags struct {
|
||||
LoadBalancerNames []string
|
||||
Tags []Tag
|
||||
}
|
||||
|
||||
type AddTagsResp struct {
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) AddTags(options *AddTags) (resp *AddTagsResp, err error) {
|
||||
params := makeParams("AddTags")
|
||||
|
||||
for i, v := range options.LoadBalancerNames {
|
||||
params["LoadBalancerNames.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
for i, v := range options.Tags {
|
||||
params["Tags.member."+strconv.Itoa(i+1)+".Key"] = v.Key
|
||||
params["Tags.member."+strconv.Itoa(i+1)+".Value"] = v.Value
|
||||
}
|
||||
|
||||
resp = &AddTagsResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RemoveTags
|
||||
|
||||
type RemoveTags struct {
|
||||
LoadBalancerNames []string
|
||||
TagKeys []string
|
||||
}
|
||||
|
||||
type RemoveTagsResp struct {
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) RemoveTags(options *RemoveTags) (resp *RemoveTagsResp, err error) {
|
||||
params := makeParams("RemoveTags")
|
||||
|
||||
for i, v := range options.LoadBalancerNames {
|
||||
params["LoadBalancerNames.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
for i, v := range options.TagKeys {
|
||||
params["Tags.member."+strconv.Itoa(i+1)+".Key"] = v
|
||||
}
|
||||
|
||||
resp = &RemoveTagsResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Create
|
||||
|
||||
// The CreateLoadBalancer request parameters
|
||||
type CreateLoadBalancer struct {
|
||||
AvailZone []string
|
||||
Listeners []Listener
|
||||
LoadBalancerName string
|
||||
Internal bool // true for vpc elbs
|
||||
SecurityGroups []string
|
||||
Subnets []string
|
||||
Tags []Tag
|
||||
}
|
||||
|
||||
type CreateLoadBalancerResp struct {
|
||||
DNSName string `xml:"CreateLoadBalancerResult>DNSName"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) CreateLoadBalancer(options *CreateLoadBalancer) (resp *CreateLoadBalancerResp, err error) {
|
||||
params := makeParams("CreateLoadBalancer")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
|
||||
for i, v := range options.AvailZone {
|
||||
params["AvailabilityZones.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
for i, v := range options.SecurityGroups {
|
||||
params["SecurityGroups.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
for i, v := range options.Subnets {
|
||||
params["Subnets.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
for i, v := range options.Listeners {
|
||||
params["Listeners.member."+strconv.Itoa(i+1)+".LoadBalancerPort"] = strconv.FormatInt(v.LoadBalancerPort, 10)
|
||||
params["Listeners.member."+strconv.Itoa(i+1)+".InstancePort"] = strconv.FormatInt(v.InstancePort, 10)
|
||||
params["Listeners.member."+strconv.Itoa(i+1)+".Protocol"] = v.Protocol
|
||||
params["Listeners.member."+strconv.Itoa(i+1)+".InstanceProtocol"] = v.InstanceProtocol
|
||||
params["Listeners.member."+strconv.Itoa(i+1)+".SSLCertificateId"] = v.SSLCertificateId
|
||||
}
|
||||
|
||||
for i, v := range options.Tags {
|
||||
params["Tags.member."+strconv.Itoa(i+1)+".Key"] = v.Key
|
||||
params["Tags.member."+strconv.Itoa(i+1)+".Value"] = v.Value
|
||||
}
|
||||
|
||||
if options.Internal {
|
||||
params["Scheme"] = "internal"
|
||||
}
|
||||
|
||||
resp = &CreateLoadBalancerResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Destroy
|
||||
|
||||
// The DestroyLoadBalancer request parameters
|
||||
type DeleteLoadBalancer struct {
|
||||
LoadBalancerName string
|
||||
}
|
||||
|
||||
func (elb *ELB) DeleteLoadBalancer(options *DeleteLoadBalancer) (resp *SimpleResp, err error) {
|
||||
params := makeParams("DeleteLoadBalancer")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
|
||||
resp = &SimpleResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Describe
|
||||
|
||||
// An individual load balancer
|
||||
type LoadBalancer struct {
|
||||
LoadBalancerName string `xml:"LoadBalancerName"`
|
||||
Listeners []Listener `xml:"ListenerDescriptions>member"`
|
||||
Instances []Instance `xml:"Instances>member"`
|
||||
HealthCheck HealthCheck `xml:"HealthCheck"`
|
||||
AvailabilityZones []string `xml:"AvailabilityZones>member"`
|
||||
HostedZoneNameID string `xml:"CanonicalHostedZoneNameID"`
|
||||
DNSName string `xml:"DNSName"`
|
||||
SecurityGroups []string `xml:"SecurityGroups>member"`
|
||||
Scheme string `xml:"Scheme"`
|
||||
Subnets []string `xml:"Subnets>member"`
|
||||
}
|
||||
|
||||
// DescribeLoadBalancer request params
|
||||
type DescribeLoadBalancer struct {
|
||||
Names []string
|
||||
}
|
||||
|
||||
type DescribeLoadBalancersResp struct {
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
LoadBalancers []LoadBalancer `xml:"DescribeLoadBalancersResult>LoadBalancerDescriptions>member"`
|
||||
}
|
||||
|
||||
func (elb *ELB) DescribeLoadBalancers(options *DescribeLoadBalancer) (resp *DescribeLoadBalancersResp, err error) {
|
||||
params := makeParams("DescribeLoadBalancers")
|
||||
|
||||
for i, v := range options.Names {
|
||||
params["LoadBalancerNames.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
resp = &DescribeLoadBalancersResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Attributes
|
||||
|
||||
type AccessLog struct {
|
||||
EmitInterval int64
|
||||
Enabled bool
|
||||
S3BucketName string
|
||||
S3BucketPrefix string
|
||||
}
|
||||
|
||||
type ConnectionDraining struct {
|
||||
Enabled bool
|
||||
Timeout int64
|
||||
}
|
||||
|
||||
type LoadBalancerAttributes struct {
|
||||
CrossZoneLoadBalancingEnabled bool
|
||||
ConnectionSettingsIdleTimeout int64
|
||||
ConnectionDraining ConnectionDraining
|
||||
AccessLog AccessLog
|
||||
}
|
||||
|
||||
type ModifyLoadBalancerAttributes struct {
|
||||
LoadBalancerName string
|
||||
LoadBalancerAttributes LoadBalancerAttributes
|
||||
}
|
||||
|
||||
func (elb *ELB) ModifyLoadBalancerAttributes(options *ModifyLoadBalancerAttributes) (resp *SimpleResp, err error) {
|
||||
params := makeParams("ModifyLoadBalancerAttributes")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
params["LoadBalancerAttributes.CrossZoneLoadBalancing.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.CrossZoneLoadBalancingEnabled)
|
||||
if options.LoadBalancerAttributes.ConnectionSettingsIdleTimeout > 0 {
|
||||
params["LoadBalancerAttributes.ConnectionSettings.IdleTimeout"] = strconv.Itoa(int(options.LoadBalancerAttributes.ConnectionSettingsIdleTimeout))
|
||||
}
|
||||
if options.LoadBalancerAttributes.ConnectionDraining.Timeout > 0 {
|
||||
params["LoadBalancerAttributes.ConnectionDraining.Timeout"] = strconv.Itoa(int(options.LoadBalancerAttributes.ConnectionDraining.Timeout))
|
||||
}
|
||||
params["LoadBalancerAttributes.ConnectionDraining.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.ConnectionDraining.Enabled)
|
||||
params["LoadBalancerAttributes.AccessLog.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.AccessLog.Enabled)
|
||||
if options.LoadBalancerAttributes.AccessLog.Enabled {
|
||||
params["LoadBalancerAttributes.AccessLog.EmitInterval"] = strconv.Itoa(int(options.LoadBalancerAttributes.AccessLog.EmitInterval))
|
||||
params["LoadBalancerAttributes.AccessLog.S3BucketName"] = options.LoadBalancerAttributes.AccessLog.S3BucketName
|
||||
params["LoadBalancerAttributes.AccessLog.S3BucketPrefix"] = options.LoadBalancerAttributes.AccessLog.S3BucketPrefix
|
||||
}
|
||||
|
||||
resp = &SimpleResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Instance Registration / deregistration
|
||||
|
||||
// The RegisterInstancesWithLoadBalancer request parameters
|
||||
type RegisterInstancesWithLoadBalancer struct {
|
||||
LoadBalancerName string
|
||||
Instances []string
|
||||
}
|
||||
|
||||
type RegisterInstancesWithLoadBalancerResp struct {
|
||||
Instances []Instance `xml:"RegisterInstancesWithLoadBalancerResult>Instances>member"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) RegisterInstancesWithLoadBalancer(options *RegisterInstancesWithLoadBalancer) (resp *RegisterInstancesWithLoadBalancerResp, err error) {
|
||||
params := makeParams("RegisterInstancesWithLoadBalancer")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
|
||||
for i, v := range options.Instances {
|
||||
params["Instances.member."+strconv.Itoa(i+1)+".InstanceId"] = v
|
||||
}
|
||||
|
||||
resp = &RegisterInstancesWithLoadBalancerResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// The DeregisterInstancesFromLoadBalancer request parameters
|
||||
type DeregisterInstancesFromLoadBalancer struct {
|
||||
LoadBalancerName string
|
||||
Instances []string
|
||||
}
|
||||
|
||||
type DeregisterInstancesFromLoadBalancerResp struct {
|
||||
Instances []Instance `xml:"DeregisterInstancesFromLoadBalancerResult>Instances>member"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) DeregisterInstancesFromLoadBalancer(options *DeregisterInstancesFromLoadBalancer) (resp *DeregisterInstancesFromLoadBalancerResp, err error) {
|
||||
params := makeParams("DeregisterInstancesFromLoadBalancer")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
|
||||
for i, v := range options.Instances {
|
||||
params["Instances.member."+strconv.Itoa(i+1)+".InstanceId"] = v
|
||||
}
|
||||
|
||||
resp = &DeregisterInstancesFromLoadBalancerResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DescribeTags
|
||||
|
||||
type DescribeTags struct {
|
||||
LoadBalancerNames []string
|
||||
}
|
||||
|
||||
type LoadBalancerTag struct {
|
||||
Tags []Tag `xml:"Tags>member"`
|
||||
LoadBalancerName string `xml:"LoadBalancerName"`
|
||||
}
|
||||
|
||||
type DescribeTagsResp struct {
|
||||
LoadBalancerTags []LoadBalancerTag `xml:"DescribeTagsResult>TagDescriptions>member"`
|
||||
NextToken string `xml:"DescribeTagsResult>NextToken"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) DescribeTags(options *DescribeTags) (resp *DescribeTagsResp, err error) {
|
||||
params := makeParams("DescribeTags")
|
||||
|
||||
for i, v := range options.LoadBalancerNames {
|
||||
params["LoadBalancerNames.member."+strconv.Itoa(i+1)] = v
|
||||
}
|
||||
|
||||
resp = &DescribeTagsResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Health Checks
|
||||
|
||||
type HealthCheck struct {
|
||||
HealthyThreshold int64 `xml:"HealthyThreshold"`
|
||||
UnhealthyThreshold int64 `xml:"UnhealthyThreshold"`
|
||||
Interval int64 `xml:"Interval"`
|
||||
Target string `xml:"Target"`
|
||||
Timeout int64 `xml:"Timeout"`
|
||||
}
|
||||
|
||||
type ConfigureHealthCheck struct {
|
||||
LoadBalancerName string
|
||||
Check HealthCheck
|
||||
}
|
||||
|
||||
type ConfigureHealthCheckResp struct {
|
||||
Check HealthCheck `xml:"ConfigureHealthCheckResult>HealthCheck"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) ConfigureHealthCheck(options *ConfigureHealthCheck) (resp *ConfigureHealthCheckResp, err error) {
|
||||
params := makeParams("ConfigureHealthCheck")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
params["HealthCheck.HealthyThreshold"] = strconv.Itoa(int(options.Check.HealthyThreshold))
|
||||
params["HealthCheck.UnhealthyThreshold"] = strconv.Itoa(int(options.Check.UnhealthyThreshold))
|
||||
params["HealthCheck.Interval"] = strconv.Itoa(int(options.Check.Interval))
|
||||
params["HealthCheck.Target"] = options.Check.Target
|
||||
params["HealthCheck.Timeout"] = strconv.Itoa(int(options.Check.Timeout))
|
||||
|
||||
resp = &ConfigureHealthCheckResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Instance Health
|
||||
|
||||
// The DescribeInstanceHealth request parameters
|
||||
type DescribeInstanceHealth struct {
|
||||
LoadBalancerName string
|
||||
}
|
||||
|
||||
type DescribeInstanceHealthResp struct {
|
||||
InstanceStates []InstanceState `xml:"DescribeInstanceHealthResult>InstanceStates>member"`
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
func (elb *ELB) DescribeInstanceHealth(options *DescribeInstanceHealth) (resp *DescribeInstanceHealthResp, err error) {
|
||||
params := makeParams("DescribeInstanceHealth")
|
||||
|
||||
params["LoadBalancerName"] = options.LoadBalancerName
|
||||
|
||||
resp = &DescribeInstanceHealthResp{}
|
||||
|
||||
err = elb.query(params, resp)
|
||||
|
||||
if err != nil {
|
||||
resp = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Responses
|
||||
|
||||
type SimpleResp struct {
|
||||
RequestId string `xml:"ResponseMetadata>RequestId"`
|
||||
}
|
||||
|
||||
type xmlErrors struct {
|
||||
Errors []Error `xml:"Error"`
|
||||
}
|
||||
|
||||
// Error encapsulates an elb error.
|
||||
type Error struct {
|
||||
// HTTP status code of the error.
|
||||
StatusCode int
|
||||
|
||||
// AWS code of the error.
|
||||
Code string
|
||||
|
||||
// Message explaining the error.
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
var prefix string
|
||||
if e.Code != "" {
|
||||
prefix = e.Code + ": "
|
||||
}
|
||||
if prefix == "" && e.StatusCode > 0 {
|
||||
prefix = strconv.Itoa(e.StatusCode) + ": "
|
||||
}
|
||||
return prefix + e.Message
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
package elb_test
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/goamz/aws"
|
||||
"github.com/mitchellh/goamz/elb"
|
||||
"github.com/mitchellh/goamz/testutil"
|
||||
. "github.com/motain/gocheck"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
TestingT(t)
|
||||
}
|
||||
|
||||
type S struct {
|
||||
elb *elb.ELB
|
||||
}
|
||||
|
||||
var _ = Suite(&S{})
|
||||
|
||||
var testServer = testutil.NewHTTPServer()
|
||||
|
||||
func (s *S) SetUpSuite(c *C) {
|
||||
testServer.Start()
|
||||
auth := aws.Auth{"abc", "123", ""}
|
||||
s.elb = elb.NewWithClient(auth, aws.Region{ELBEndpoint: testServer.URL}, testutil.DefaultClient)
|
||||
}
|
||||
|
||||
func (s *S) TearDownTest(c *C) {
|
||||
testServer.Flush()
|
||||
}
|
||||
|
||||
func (s *S) TestAddTags(c *C) {
|
||||
testServer.Response(200, nil, AddTagsExample)
|
||||
|
||||
options := elb.AddTags{
|
||||
LoadBalancerNames: []string{"foobar"},
|
||||
Tags: []elb.Tag{
|
||||
{
|
||||
Key: "hello",
|
||||
Value: "world",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := s.elb.AddTags(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"AddTags"})
|
||||
c.Assert(req.Form["LoadBalancerNames.member.1"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(req.Form["Tags.member.1.Key"], DeepEquals, []string{"hello"})
|
||||
c.Assert(req.Form["Tags.member.1.Value"], DeepEquals, []string{"world"})
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.RequestId, Equals, "360e81f7-1100-11e4-b6ed-0f30EXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestRemoveTags(c *C) {
|
||||
testServer.Response(200, nil, RemoveTagsExample)
|
||||
|
||||
options := elb.RemoveTags{
|
||||
LoadBalancerNames: []string{"foobar"},
|
||||
TagKeys: []string{"hello"},
|
||||
}
|
||||
|
||||
resp, err := s.elb.RemoveTags(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"RemoveTags"})
|
||||
c.Assert(req.Form["LoadBalancerNames.member.1"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(req.Form["Tags.member.1.Key"], DeepEquals, []string{"hello"})
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.RequestId, Equals, "83c88b9d-12b7-11e3-8b82-87b12EXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestCreateLoadBalancer(c *C) {
|
||||
testServer.Response(200, nil, CreateLoadBalancerExample)
|
||||
|
||||
options := elb.CreateLoadBalancer{
|
||||
AvailZone: []string{"us-east-1a"},
|
||||
Listeners: []elb.Listener{elb.Listener{
|
||||
InstancePort: 80,
|
||||
InstanceProtocol: "http",
|
||||
SSLCertificateId: "needToAddASSLCertToYourAWSAccount",
|
||||
LoadBalancerPort: 80,
|
||||
Protocol: "http",
|
||||
},
|
||||
},
|
||||
LoadBalancerName: "foobar",
|
||||
Internal: false,
|
||||
SecurityGroups: []string{"sg1"},
|
||||
Subnets: []string{"sn1"},
|
||||
}
|
||||
|
||||
resp, err := s.elb.CreateLoadBalancer(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"CreateLoadBalancer"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.RequestId, Equals, "1549581b-12b7-11e3-895e-1334aEXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestDeleteLoadBalancer(c *C) {
|
||||
testServer.Response(200, nil, DeleteLoadBalancerExample)
|
||||
|
||||
options := elb.DeleteLoadBalancer{
|
||||
LoadBalancerName: "foobar",
|
||||
}
|
||||
|
||||
resp, err := s.elb.DeleteLoadBalancer(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"DeleteLoadBalancer"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.RequestId, Equals, "1549581b-12b7-11e3-895e-1334aEXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestDescribeLoadBalancers(c *C) {
|
||||
testServer.Response(200, nil, DescribeLoadBalancersExample)
|
||||
|
||||
options := elb.DescribeLoadBalancer{
|
||||
Names: []string{"foobar"},
|
||||
}
|
||||
|
||||
resp, err := s.elb.DescribeLoadBalancers(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeLoadBalancers"})
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.RequestId, Equals, "83c88b9d-12b7-11e3-8b82-87b12EXAMPLE")
|
||||
c.Assert(resp.LoadBalancers[0].LoadBalancerName, Equals, "MyLoadBalancer")
|
||||
c.Assert(resp.LoadBalancers[0].Listeners[0].Protocol, Equals, "HTTP")
|
||||
c.Assert(resp.LoadBalancers[0].Instances[0].InstanceId, Equals, "i-e4cbe38d")
|
||||
c.Assert(resp.LoadBalancers[0].AvailabilityZones[0].AvailabilityZone, Equals, "us-east-1a")
|
||||
c.Assert(resp.LoadBalancers[0].Scheme, Equals, "internet-facing")
|
||||
c.Assert(resp.LoadBalancers[0].DNSName, Equals, "MyLoadBalancer-123456789.us-east-1.elb.amazonaws.com")
|
||||
c.Assert(resp.LoadBalancers[0].HealthCheck.HealthyThreshold, Equals, int64(2))
|
||||
c.Assert(resp.LoadBalancers[0].HealthCheck.UnhealthyThreshold, Equals, int64(10))
|
||||
c.Assert(resp.LoadBalancers[0].HealthCheck.Interval, Equals, int64(90))
|
||||
c.Assert(resp.LoadBalancers[0].HealthCheck.Target, Equals, "HTTP:80/")
|
||||
c.Assert(resp.LoadBalancers[0].HealthCheck.Timeout, Equals, int64(60))
|
||||
}
|
||||
|
||||
func (s *S) TestRegisterInstancesWithLoadBalancer(c *C) {
|
||||
testServer.Response(200, nil, RegisterInstancesWithLoadBalancerExample)
|
||||
|
||||
options := elb.RegisterInstancesWithLoadBalancer{
|
||||
LoadBalancerName: "foobar",
|
||||
Instances: []string{"instance-1", "instance-2"},
|
||||
}
|
||||
|
||||
resp, err := s.elb.RegisterInstancesWithLoadBalancer(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"RegisterInstancesWithLoadBalancer"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(req.Form["Instances.member.1.InstanceId"], DeepEquals, []string{"instance-1"})
|
||||
c.Assert(req.Form["Instances.member.2.InstanceId"], DeepEquals, []string{"instance-2"})
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(resp.Instances[0].InstanceId, Equals, "i-315b7e51")
|
||||
c.Assert(resp.RequestId, Equals, "83c88b9d-12b7-11e3-8b82-87b12EXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestDeregisterInstancesFromLoadBalancer(c *C) {
|
||||
testServer.Response(200, nil, DeregisterInstancesFromLoadBalancerExample)
|
||||
|
||||
options := elb.DeregisterInstancesFromLoadBalancer{
|
||||
LoadBalancerName: "foobar",
|
||||
Instances: []string{"instance-1", "instance-2"},
|
||||
}
|
||||
|
||||
resp, err := s.elb.DeregisterInstancesFromLoadBalancer(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"DeregisterInstancesFromLoadBalancer"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(req.Form["Instances.member.1.InstanceId"], DeepEquals, []string{"instance-1"})
|
||||
c.Assert(req.Form["Instances.member.2.InstanceId"], DeepEquals, []string{"instance-2"})
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(resp.Instances[0].InstanceId, Equals, "i-6ec63d59")
|
||||
c.Assert(resp.RequestId, Equals, "83c88b9d-12b7-11e3-8b82-87b12EXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestConfigureHealthCheck(c *C) {
|
||||
testServer.Response(200, nil, ConfigureHealthCheckExample)
|
||||
|
||||
options := elb.ConfigureHealthCheck{
|
||||
LoadBalancerName: "foobar",
|
||||
Check: elb.HealthCheck{
|
||||
HealthyThreshold: 2,
|
||||
UnhealthyThreshold: 2,
|
||||
Interval: 30,
|
||||
Target: "HTTP:80/ping",
|
||||
Timeout: 3,
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := s.elb.ConfigureHealthCheck(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"ConfigureHealthCheck"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(resp.Check.HealthyThreshold, Equals, int64(2))
|
||||
c.Assert(resp.Check.UnhealthyThreshold, Equals, int64(2))
|
||||
c.Assert(resp.Check.Interval, Equals, int64(30))
|
||||
c.Assert(resp.Check.Target, Equals, "HTTP:80/ping")
|
||||
c.Assert(resp.Check.Timeout, Equals, int64(3))
|
||||
c.Assert(resp.RequestId, Equals, "83c88b9d-12b7-11e3-8b82-87b12EXAMPLE")
|
||||
}
|
||||
|
||||
func (s *S) TestDescribeInstanceHealth(c *C) {
|
||||
testServer.Response(200, nil, DescribeInstanceHealthExample)
|
||||
|
||||
options := elb.DescribeInstanceHealth{
|
||||
LoadBalancerName: "foobar",
|
||||
}
|
||||
|
||||
resp, err := s.elb.DescribeInstanceHealth(&options)
|
||||
req := testServer.WaitRequest()
|
||||
|
||||
c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeInstanceHealth"})
|
||||
c.Assert(req.Form["LoadBalancerName"], DeepEquals, []string{"foobar"})
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(resp.InstanceStates[0].InstanceId, Equals, "i-90d8c2a5")
|
||||
c.Assert(resp.InstanceStates[0].State, Equals, "InService")
|
||||
c.Assert(resp.InstanceStates[1].InstanceId, Equals, "i-06ea3e60")
|
||||
c.Assert(resp.InstanceStates[1].State, Equals, "OutOfService")
|
||||
c.Assert(resp.RequestId, Equals, "1549581b-12b7-11e3-895e-1334aEXAMPLE")
|
||||
}
|
182
Godeps/_workspace/src/github.com/mitchellh/goamz/elb/responses_test.go
generated
vendored
Normal file
182
Godeps/_workspace/src/github.com/mitchellh/goamz/elb/responses_test.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
package elb_test
|
||||
|
||||
var ErrorDump = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Response><Errors><Error><Code>UnsupportedOperation</Code>
|
||||
<Message></Message>
|
||||
</Error></Errors><RequestID>0503f4e9-bbd6-483c-b54f-c4ae9f3b30f4</RequestID></Response>
|
||||
`
|
||||
|
||||
// http://goo.gl/OkMdtJ
|
||||
var AddTagsExample = `
|
||||
<AddTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<AddTagsResult/>
|
||||
<ResponseMetadata>
|
||||
<RequestId>360e81f7-1100-11e4-b6ed-0f30EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</AddTagsResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/nT2E89
|
||||
var RemoveTagsExample = `
|
||||
<RemoveTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<RemoveTagsResult/>
|
||||
<ResponseMetadata>
|
||||
<RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</RemoveTagsResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/gQRD2H
|
||||
var CreateLoadBalancerExample = `
|
||||
<CreateLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<CreateLoadBalancerResult>
|
||||
<DNSName>MyLoadBalancer-1234567890.us-east-1.elb.amazonaws.com</DNSName>
|
||||
</CreateLoadBalancerResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</CreateLoadBalancerResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/GLZeBN
|
||||
var DeleteLoadBalancerExample = `
|
||||
<DeleteLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<ResponseMetadata>
|
||||
<RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DeleteLoadBalancerResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/8UgpQ8
|
||||
var DescribeLoadBalancersExample = `
|
||||
<DescribeLoadBalancersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<DescribeLoadBalancersResult>
|
||||
<LoadBalancerDescriptions>
|
||||
<member>
|
||||
<SecurityGroups/>
|
||||
<LoadBalancerName>MyLoadBalancer</LoadBalancerName>
|
||||
<CreatedTime>2013-05-24T21:15:31.280Z</CreatedTime>
|
||||
<HealthCheck>
|
||||
<Interval>90</Interval>
|
||||
<Target>HTTP:80/</Target>
|
||||
<HealthyThreshold>2</HealthyThreshold>
|
||||
<Timeout>60</Timeout>
|
||||
<UnhealthyThreshold>10</UnhealthyThreshold>
|
||||
</HealthCheck>
|
||||
<ListenerDescriptions>
|
||||
<member>
|
||||
<PolicyNames/>
|
||||
<Listener>
|
||||
<Protocol>HTTP</Protocol>
|
||||
<LoadBalancerPort>80</LoadBalancerPort>
|
||||
<InstanceProtocol>HTTP</InstanceProtocol>
|
||||
<SSLCertificateId>needToAddASSLCertToYourAWSAccount</SSLCertificateId>
|
||||
<InstancePort>80</InstancePort>
|
||||
</Listener>
|
||||
</member>
|
||||
</ListenerDescriptions>
|
||||
<Instances>
|
||||
<member>
|
||||
<InstanceId>i-e4cbe38d</InstanceId>
|
||||
</member>
|
||||
</Instances>
|
||||
<Policies>
|
||||
<AppCookieStickinessPolicies/>
|
||||
<OtherPolicies/>
|
||||
<LBCookieStickinessPolicies/>
|
||||
</Policies>
|
||||
<AvailabilityZones>
|
||||
<member>us-east-1a</member>
|
||||
</AvailabilityZones>
|
||||
<CanonicalHostedZoneNameID>ZZZZZZZZZZZ123X</CanonicalHostedZoneNameID>
|
||||
<CanonicalHostedZoneName>MyLoadBalancer-123456789.us-east-1.elb.amazonaws.com</CanonicalHostedZoneName>
|
||||
<Scheme>internet-facing</Scheme>
|
||||
<SourceSecurityGroup>
|
||||
<OwnerAlias>amazon-elb</OwnerAlias>
|
||||
<GroupName>amazon-elb-sg</GroupName>
|
||||
</SourceSecurityGroup>
|
||||
<DNSName>MyLoadBalancer-123456789.us-east-1.elb.amazonaws.com</DNSName>
|
||||
<BackendServerDescriptions/>
|
||||
<Subnets/>
|
||||
</member>
|
||||
</LoadBalancerDescriptions>
|
||||
</DescribeLoadBalancersResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DescribeLoadBalancersResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/Uz1N66
|
||||
var RegisterInstancesWithLoadBalancerExample = `
|
||||
<RegisterInstancesWithLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<RegisterInstancesWithLoadBalancerResult>
|
||||
<Instances>
|
||||
<member>
|
||||
<InstanceId>i-315b7e51</InstanceId>
|
||||
</member>
|
||||
</Instances>
|
||||
</RegisterInstancesWithLoadBalancerResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</RegisterInstancesWithLoadBalancerResponse>
|
||||
`
|
||||
|
||||
// http://goo.gl/5OMv62
|
||||
var DeregisterInstancesFromLoadBalancerExample = `
|
||||
<DeregisterInstancesFromLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<DeregisterInstancesFromLoadBalancerResult>
|
||||
<Instances>
|
||||
<member>
|
||||
<InstanceId>i-6ec63d59</InstanceId>
|
||||
</member>
|
||||
</Instances>
|
||||
</DeregisterInstancesFromLoadBalancerResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DeregisterInstancesFromLoadBalancerResponse>
|
||||
`
|
||||
|
||||
// http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/API_ConfigureHealthCheck.html
|
||||
var ConfigureHealthCheckExample = `
|
||||
<ConfigureHealthCheckResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<ConfigureHealthCheckResult>
|
||||
<HealthCheck>
|
||||
<Interval>30</Interval>
|
||||
<Target>HTTP:80/ping</Target>
|
||||
<HealthyThreshold>2</HealthyThreshold>
|
||||
<Timeout>3</Timeout>
|
||||
<UnhealthyThreshold>2</UnhealthyThreshold>
|
||||
</HealthCheck>
|
||||
</ConfigureHealthCheckResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</ConfigureHealthCheckResponse>`
|
||||
|
||||
// http://goo.gl/cGNxfj
|
||||
var DescribeInstanceHealthExample = `
|
||||
<DescribeInstanceHealthResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<DescribeInstanceHealthResult>
|
||||
<InstanceStates>
|
||||
<member>
|
||||
<Description>N/A</Description>
|
||||
<InstanceId>i-90d8c2a5</InstanceId>
|
||||
<State>InService</State>
|
||||
<ReasonCode>N/A</ReasonCode>
|
||||
</member>
|
||||
<member>
|
||||
<Description>N/A</Description>
|
||||
<InstanceId>i-06ea3e60</InstanceId>
|
||||
<State>OutOfService</State>
|
||||
<ReasonCode>N/A</ReasonCode>
|
||||
</member>
|
||||
</InstanceStates>
|
||||
</DescribeInstanceHealthResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DescribeInstanceHealthResponse>`
|
|
@ -0,0 +1,38 @@
|
|||
package elb
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"github.com/mitchellh/goamz/aws"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Version 2 signing (http://goo.gl/RSRp5)
|
||||
|
||||
var b64 = base64.StdEncoding
|
||||
|
||||
func sign(auth aws.Auth, method, path string, params map[string]string, host string) {
|
||||
params["AWSAccessKeyId"] = auth.AccessKey
|
||||
params["SignatureVersion"] = "2"
|
||||
params["SignatureMethod"] = "HmacSHA256"
|
||||
if auth.Token != "" {
|
||||
params["SecurityToken"] = auth.Token
|
||||
}
|
||||
|
||||
var sarray []string
|
||||
for k, v := range params {
|
||||
sarray = append(sarray, aws.Encode(k)+"="+aws.Encode(v))
|
||||
}
|
||||
sort.StringSlice(sarray).Sort()
|
||||
joined := strings.Join(sarray, "&")
|
||||
payload := method + "\n" + host + "\n" + path + "\n" + joined
|
||||
hash := hmac.New(sha256.New, []byte(auth.SecretKey))
|
||||
hash.Write([]byte(payload))
|
||||
signature := make([]byte, b64.EncodedLen(hash.Size()))
|
||||
b64.Encode(signature, hash.Sum(nil))
|
||||
|
||||
params["Signature"] = string(signature)
|
||||
}
|
Loading…
Reference in New Issue