summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/elb/elbtest/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/elb/elbtest/server.go')
-rw-r--r--vendor/github.com/goamz/goamz/elb/elbtest/server.go551
1 files changed, 0 insertions, 551 deletions
diff --git a/vendor/github.com/goamz/goamz/elb/elbtest/server.go b/vendor/github.com/goamz/goamz/elb/elbtest/server.go
deleted file mode 100644
index 9b8f79d4e..000000000
--- a/vendor/github.com/goamz/goamz/elb/elbtest/server.go
+++ /dev/null
@@ -1,551 +0,0 @@
-// Package elbtest implements a fake ELB provider with the capability of
-// inducing errors on any given operation, and retrospectively determining what
-// operations have been carried out.
-package elbtest
-
-import (
- "encoding/xml"
- "fmt"
- "github.com/goamz/goamz/elb"
- "net"
- "net/http"
- "net/url"
- "regexp"
- "strconv"
- "strings"
- "sync"
-)
-
-// Server implements an ELB simulator for use in testing.
-type Server struct {
- url string
- listener net.Listener
- mutex sync.Mutex
- reqId int
- lbs map[string]*elb.LoadBalancerDescription
- lbsReqs map[string]url.Values
- instances []string
- instanceStates map[string][]*elb.InstanceState
- instCount int
-}
-
-// Starts and returns a new server
-func NewServer() (*Server, error) {
- l, err := net.Listen("tcp", "localhost:0")
- if err != nil {
- return nil, fmt.Errorf("cannot listen on localhost: %v", err)
- }
- srv := &Server{
- listener: l,
- url: "http://" + l.Addr().String(),
- lbs: make(map[string]*elb.LoadBalancerDescription),
- instanceStates: make(map[string][]*elb.InstanceState),
- }
- go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- srv.serveHTTP(w, req)
- }))
- return srv, nil
-}
-
-// Quit closes down the server.
-func (srv *Server) Quit() {
- srv.listener.Close()
-}
-
-// URL returns the URL of the server.
-func (srv *Server) URL() string {
- return srv.url
-}
-
-type xmlErrors struct {
- XMLName string `xml:"ErrorResponse"`
- Error elb.Error
-}
-
-func (srv *Server) error(w http.ResponseWriter, err *elb.Error) {
- w.WriteHeader(err.StatusCode)
- xmlErr := xmlErrors{Error: *err}
- if e := xml.NewEncoder(w).Encode(xmlErr); e != nil {
- panic(e)
- }
-}
-
-func (srv *Server) serveHTTP(w http.ResponseWriter, req *http.Request) {
- req.ParseForm()
- srv.mutex.Lock()
- defer srv.mutex.Unlock()
- f := actions[req.Form.Get("Action")]
- if f == nil {
- srv.error(w, &elb.Error{
- StatusCode: 400,
- Code: "InvalidParameterValue",
- Message: "Unrecognized Action",
- })
- }
- reqId := fmt.Sprintf("req%0X", srv.reqId)
- srv.reqId++
- if resp, err := f(srv, w, req, reqId); err == nil {
- if err := xml.NewEncoder(w).Encode(resp); err != nil {
- panic(err)
- }
- } else {
- switch err.(type) {
- case *elb.Error:
- srv.error(w, err.(*elb.Error))
- default:
- panic(err)
- }
- }
-}
-
-func (srv *Server) createLoadBalancer(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- composition := map[string]string{
- "AvailabilityZones.member.1": "Subnets.member.1",
- }
- if err := srv.validateComposition(req, composition); err != nil {
- return nil, err
- }
- required := []string{
- "Listeners.member.1.InstancePort",
- "Listeners.member.1.InstanceProtocol",
- "Listeners.member.1.Protocol",
- "Listeners.member.1.LoadBalancerPort",
- "LoadBalancerName",
- }
- if err := srv.validate(req, required); err != nil {
- return nil, err
- }
- path := req.FormValue("Path")
- if path == "" {
- path = "/"
- }
- lbName := req.FormValue("LoadBalancerName")
- srv.lbs[lbName] = srv.makeLoadBalancerDescription(req.Form)
- srv.lbs[lbName].DNSName = fmt.Sprintf("%s-some-aws-stuff.us-east-1.elb.amazonaws.com", lbName)
- return elb.CreateLoadBalancerResp{
- DNSName: srv.lbs[lbName].DNSName,
- }, nil
-}
-
-func (srv *Server) deleteLoadBalancer(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- if err := srv.validate(req, []string{"LoadBalancerName"}); err != nil {
- return nil, err
- }
- srv.RemoveLoadBalancer(req.FormValue("LoadBalancerName"))
- return elb.SimpleResp{RequestId: reqId}, nil
-}
-
-func (srv *Server) registerInstancesWithLoadBalancer(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- required := []string{"LoadBalancerName", "Instances.member.1.InstanceId"}
- if err := srv.validate(req, required); err != nil {
- return nil, err
- }
- lbName := req.FormValue("LoadBalancerName")
- if err := srv.lbExists(lbName); err != nil {
- return nil, err
- }
- instIds := []string{}
- instances := []elb.Instance{}
- i := 1
- instId := req.FormValue(fmt.Sprintf("Instances.member.%d.InstanceId", i))
- for instId != "" {
- if err := srv.instanceExists(instId); err != nil {
- return nil, err
- }
- instIds = append(instIds, instId)
- instances = append(instances, elb.Instance{InstanceId: instId})
- i++
- instId = req.FormValue(fmt.Sprintf("Instances.member.%d.InstanceId", i))
- }
- srv.instanceStates[lbName] = append(srv.instanceStates[lbName], srv.makeInstanceState(instId))
- srv.lbs[lbName].Instances = append(srv.lbs[lbName].Instances, instances...)
- return elb.RegisterInstancesResp{InstanceIds: instIds}, nil
-}
-
-func (srv *Server) deregisterInstancesFromLoadBalancer(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- required := []string{"LoadBalancerName"}
- if err := srv.validate(req, required); err != nil {
- return nil, err
- }
- lbName := req.FormValue("LoadBalancerName")
- if err := srv.lbExists(lbName); err != nil {
- return nil, err
- }
- i := 1
- lb := srv.lbs[lbName]
- instId := req.FormValue(fmt.Sprintf("Instances.member.%d.InstanceId", i))
- for instId != "" {
- if err := srv.instanceExists(instId); err != nil {
- return nil, err
- }
- i++
- removeInstanceFromLB(lb, instId)
- instId = req.FormValue(fmt.Sprintf("Instances.member.%d.InstanceId", i))
- }
- srv.lbs[lbName] = lb
- srv.removeInstanceStatesFromLoadBalancer(lbName, instId)
- return elb.SimpleResp{RequestId: reqId}, nil
-}
-
-func (srv *Server) describeLoadBalancers(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- i := 1
- lbName := req.FormValue(fmt.Sprintf("LoadBalancerNames.member.%d", i))
- for lbName != "" {
- key := fmt.Sprintf("LoadBalancerNames.member.%d", i)
- if req.FormValue(key) != "" {
- if err := srv.lbExists(req.FormValue(key)); err != nil {
- return nil, err
- }
- }
- i++
- lbName = req.FormValue(fmt.Sprintf("LoadBalancerNames.member.%d", i))
- }
- lbsDesc := make([]elb.LoadBalancerDescription, len(srv.lbs))
- i = 0
- for _, lb := range srv.lbs {
- lbsDesc[i] = *lb
- i++
- }
- resp := elb.DescribeLoadBalancerResp{
- LoadBalancerDescriptions: lbsDesc,
- }
- return resp, nil
-}
-
-// getParameters returns the value all parameters from a request that matches a
-// prefix.
-//
-// For example, for the prefix "Subnets.member.", it will return a slice
-// containing the value of keys "Subnets.member.1", "Subnets.member.2" ...
-// "Subnets.member.N". The prefix must include the trailing dot.
-func (srv *Server) getParameters(prefix string, values url.Values) []string {
- i, key := 1, ""
- var k = func(n int) string {
- return fmt.Sprintf(prefix+"%d", n)
- }
- var result []string
- for i, key = 2, k(i); values.Get(key) != ""; i, key = i+1, k(i) {
- result = append(result, values.Get(key))
- }
- return result
-}
-
-func (srv *Server) makeInstanceState(id string) *elb.InstanceState {
- return &elb.InstanceState{
- Description: "Instance is in pending state.",
- InstanceId: id,
- State: "OutOfService",
- ReasonCode: "Instance",
- }
-}
-
-func removeInstanceFromLB(lb *elb.LoadBalancerDescription, id string) {
- index := -1
- for i, instance := range lb.Instances {
- if instance.InstanceId == id {
- index = i
- break
- }
- }
- if index > -1 {
- copy(lb.Instances[index:], lb.Instances[index+1:])
- lb.Instances = lb.Instances[:len(lb.Instances)-1]
- }
-}
-
-func (srv *Server) removeInstanceStatesFromLoadBalancer(lb, id string) {
- for i, state := range srv.instanceStates[lb] {
- if state.InstanceId == id {
- a := srv.instanceStates[lb]
- a[i], a = a[len(a)-1], a[:len(a)-1]
- srv.instanceStates[lb] = a
- return
- }
- }
-}
-
-func (srv *Server) makeLoadBalancerDescription(value url.Values) *elb.LoadBalancerDescription {
- lds := []elb.ListenerDescription{}
- i := 1
- protocol := value.Get(fmt.Sprintf("Listeners.member.%d.Protocol", i))
- for protocol != "" {
- key := fmt.Sprintf("Listeners.member.%d.", i)
- lInstPort, _ := strconv.Atoi(value.Get(key + "InstancePort"))
- lLBPort, _ := strconv.Atoi(value.Get(key + "LoadBalancerPort"))
- lDescription := elb.ListenerDescription{
- Listener: elb.Listener{
- Protocol: strings.ToUpper(protocol),
- InstanceProtocol: strings.ToUpper(value.Get(key + "InstanceProtocol")),
- LoadBalancerPort: lLBPort,
- InstancePort: lInstPort,
- },
- }
- i++
- protocol = value.Get(fmt.Sprintf("Listeners.member.%d.Protocol", i))
- lds = append(lds, lDescription)
- }
- sourceSecGroup := srv.makeSourceSecGroup(value)
- lbDesc := elb.LoadBalancerDescription{
- AvailabilityZones: srv.getParameters("AvailabilityZones.member.", value),
- Subnets: srv.getParameters("Subnets.member.", value),
- SecurityGroups: srv.getParameters("SecurityGroups.member.", value),
- HealthCheck: srv.makeHealthCheck(value),
- ListenerDescriptions: lds,
- Scheme: value.Get("Scheme"),
- SourceSecurityGroup: sourceSecGroup,
- LoadBalancerName: value.Get("LoadBalancerName"),
- }
- if lbDesc.Scheme == "" {
- lbDesc.Scheme = "internet-facing"
- }
- return &lbDesc
-}
-
-func (srv *Server) makeHealthCheck(value url.Values) elb.HealthCheck {
- ht := 10
- timeout := 5
- ut := 2
- interval := 30
- target := "TCP:80"
- if v := value.Get("HealthCheck.HealthyThreshold"); v != "" {
- ht, _ = strconv.Atoi(v)
- }
- if v := value.Get("HealthCheck.Timeout"); v != "" {
- timeout, _ = strconv.Atoi(v)
- }
- if v := value.Get("HealthCheck.UnhealthyThreshold"); v != "" {
- ut, _ = strconv.Atoi(v)
- }
- if v := value.Get("HealthCheck.Interval"); v != "" {
- interval, _ = strconv.Atoi(v)
- }
- if v := value.Get("HealthCheck.Target"); v != "" {
- target = v
- }
- return elb.HealthCheck{
- HealthyThreshold: ht,
- Interval: interval,
- Target: target,
- Timeout: timeout,
- UnhealthyThreshold: ut,
- }
-}
-
-func (srv *Server) makeSourceSecGroup(value url.Values) elb.SourceSecurityGroup {
- name := "amazon-elb-sg"
- alias := "amazon-elb"
- if v := value.Get("SourceSecurityGroup.GroupName"); v != "" {
- name = v
- }
- if v := value.Get("SourceSecurityGroup.OwnerAlias"); v != "" {
- alias = v
- }
- return elb.SourceSecurityGroup{
- GroupName: name,
- OwnerAlias: alias,
- }
-}
-
-func (srv *Server) describeInstanceHealth(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- if err := srv.lbExists(req.FormValue("LoadBalancerName")); err != nil {
- return nil, err
- }
- resp := elb.DescribeInstanceHealthResp{
- InstanceStates: []elb.InstanceState{},
- }
- for _, state := range srv.instanceStates[req.FormValue("LoadBalancerName")] {
- resp.InstanceStates = append(resp.InstanceStates, *state)
- }
- i := 1
- instanceId := req.FormValue("Instances.member.1.InstanceId")
- for instanceId != "" {
- if err := srv.instanceExists(instanceId); err != nil {
- return nil, err
- }
- is := elb.InstanceState{
- Description: "Instance is in pending state.",
- InstanceId: instanceId,
- State: "OutOfService",
- ReasonCode: "Instance",
- }
- resp.InstanceStates = append(resp.InstanceStates, is)
- i++
- instanceId = req.FormValue(fmt.Sprintf("Instances.member.%d.InstanceId", i))
- }
- return resp, nil
-}
-
-func (srv *Server) configureHealthCheck(w http.ResponseWriter, req *http.Request, reqId string) (interface{}, error) {
- required := []string{
- "LoadBalancerName",
- "HealthCheck.HealthyThreshold",
- "HealthCheck.Interval",
- "HealthCheck.Target",
- "HealthCheck.Timeout",
- "HealthCheck.UnhealthyThreshold",
- }
- if err := srv.validate(req, required); err != nil {
- return nil, err
- }
- target := req.FormValue("HealthCheck.Target")
- r, err := regexp.Compile(`[\w]+:[\d]+\/+`)
- if err != nil {
- panic(err)
- }
- if m := r.FindStringSubmatch(target); m == nil {
- return nil, &elb.Error{
- StatusCode: 400,
- Code: "ValidationError",
- Message: "HealthCheck HTTP Target must specify a port followed by a path that begins with a slash. e.g. HTTP:80/ping/this/path",
- }
- }
- ht, _ := strconv.Atoi(req.FormValue("HealthCheck.HealthyThreshold"))
- interval, _ := strconv.Atoi(req.FormValue("HealthCheck.Interval"))
- timeout, _ := strconv.Atoi(req.FormValue("HealthCheck.Timeout"))
- ut, _ := strconv.Atoi(req.FormValue("HealthCheck.UnhealthyThreshold"))
- return elb.HealthCheckResp{
- HealthCheck: &elb.HealthCheck{
- HealthyThreshold: ht,
- Interval: interval,
- Target: target,
- Timeout: timeout,
- UnhealthyThreshold: ut,
- },
- }, nil
-}
-
-func (srv *Server) instanceExists(id string) error {
- for _, instId := range srv.instances {
- if instId == id {
- return nil
- }
- }
- return &elb.Error{
- StatusCode: 400,
- Code: "InvalidInstance",
- Message: fmt.Sprintf("InvalidInstance found in [%s]. Invalid id: \"%s\"", id, id),
- }
-}
-
-func (srv *Server) lbExists(name string) error {
- if _, ok := srv.lbs[name]; !ok {
- return &elb.Error{
- StatusCode: 400,
- Code: "LoadBalancerNotFound",
- Message: fmt.Sprintf("There is no ACTIVE Load Balancer named '%s'", name),
- }
- }
- return nil
-}
-
-func (srv *Server) validate(req *http.Request, required []string) error {
- for _, field := range required {
- if req.FormValue(field) == "" {
- return &elb.Error{
- StatusCode: 400,
- Code: "ValidationError",
- Message: fmt.Sprintf("%s is required.", field),
- }
- }
- }
- return nil
-}
-
-// Validates the composition of the fields.
-//
-// Some fields cannot be together in the same request, such as AvailabilityZones and Subnets.
-// A sample map with the above requirement would be
-// c := map[string]string{
-// "AvailabilityZones.member.1": "Subnets.member.1",
-// }
-//
-// The server also requires that at least one of those fields are specified.
-func (srv *Server) validateComposition(req *http.Request, composition map[string]string) error {
- for k, v := range composition {
- if req.FormValue(k) != "" && req.FormValue(v) != "" {
- return &elb.Error{
- StatusCode: 400,
- Code: "ValidationError",
- Message: fmt.Sprintf("Only one of %s or %s may be specified", k, v),
- }
- }
- if req.FormValue(k) == "" && req.FormValue(v) == "" {
- return &elb.Error{
- StatusCode: 400,
- Code: "ValidationError",
- Message: fmt.Sprintf("Either %s or %s must be specified", k, v),
- }
- }
- }
- return nil
-}
-
-// Creates a fake instance in the server
-func (srv *Server) NewInstance() string {
- srv.instCount++
- instId := fmt.Sprintf("i-%d", srv.instCount)
- srv.instances = append(srv.instances, instId)
- return instId
-}
-
-// Removes a fake instance from the server
-//
-// If no instance is found it does nothing
-func (srv *Server) RemoveInstance(instId string) {
- for i, id := range srv.instances {
- if id == instId {
- srv.instances[i], srv.instances = srv.instances[len(srv.instances)-1], srv.instances[:len(srv.instances)-1]
- }
- }
-}
-
-// Creates a fake load balancer in the fake server
-func (srv *Server) NewLoadBalancer(name string) {
- srv.lbs[name] = &elb.LoadBalancerDescription{
- LoadBalancerName: name,
- DNSName: fmt.Sprintf("%s-some-aws-stuff.sa-east-1.amazonaws.com", name),
- }
-}
-
-// Removes a fake load balancer from the fake server
-func (srv *Server) RemoveLoadBalancer(name string) {
- delete(srv.lbs, name)
-}
-
-// Register a fake instance with a fake Load Balancer
-//
-// If the Load Balancer does not exists it does nothing
-func (srv *Server) RegisterInstance(instId, lbName string) {
- lb, ok := srv.lbs[lbName]
- if !ok {
- fmt.Println("lb not found :/")
- return
- }
- lb.Instances = append(lb.Instances, elb.Instance{InstanceId: instId})
- srv.instanceStates[lbName] = append(srv.instanceStates[lbName], srv.makeInstanceState(instId))
-}
-
-func (srv *Server) DeregisterInstance(instId, lbName string) {
- removeInstanceFromLB(srv.lbs[lbName], instId)
- srv.removeInstanceStatesFromLoadBalancer(lbName, instId)
-}
-
-func (srv *Server) ChangeInstanceState(lb string, state elb.InstanceState) {
- states := srv.instanceStates[lb]
- for i, s := range states {
- if s.InstanceId == state.InstanceId {
- srv.instanceStates[lb][i] = &state
- return
- }
- }
-}
-
-var actions = map[string]func(*Server, http.ResponseWriter, *http.Request, string) (interface{}, error){
- "CreateLoadBalancer": (*Server).createLoadBalancer,
- "DeleteLoadBalancer": (*Server).deleteLoadBalancer,
- "RegisterInstancesWithLoadBalancer": (*Server).registerInstancesWithLoadBalancer,
- "DeregisterInstancesFromLoadBalancer": (*Server).deregisterInstancesFromLoadBalancer,
- "DescribeLoadBalancers": (*Server).describeLoadBalancers,
- "DescribeInstanceHealth": (*Server).describeInstanceHealth,
- "ConfigureHealthCheck": (*Server).configureHealthCheck,
-}