mirror of https://github.com/k3s-io/k3s
687 lines
23 KiB
Go
687 lines
23 KiB
Go
// +build !providerless
|
|
|
|
/*
|
|
Copyright 2017 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package aws
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/service/autoscaling"
|
|
"github.com/aws/aws-sdk-go/service/ec2"
|
|
"github.com/aws/aws-sdk-go/service/elb"
|
|
"github.com/aws/aws-sdk-go/service/elbv2"
|
|
"github.com/aws/aws-sdk-go/service/kms"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
// FakeAWSServices is an fake AWS session used for testing
|
|
type FakeAWSServices struct {
|
|
region string
|
|
instances []*ec2.Instance
|
|
selfInstance *ec2.Instance
|
|
networkInterfacesMacs []string
|
|
networkInterfacesPrivateIPs [][]string
|
|
networkInterfacesVpcIDs []string
|
|
|
|
ec2 FakeEC2
|
|
elb ELB
|
|
elbv2 ELBV2
|
|
asg *FakeASG
|
|
metadata *FakeMetadata
|
|
kms *FakeKMS
|
|
}
|
|
|
|
// NewFakeAWSServices creates a new FakeAWSServices
|
|
func NewFakeAWSServices(clusterID string) *FakeAWSServices {
|
|
s := &FakeAWSServices{}
|
|
s.region = "us-east-1"
|
|
s.ec2 = &FakeEC2Impl{aws: s}
|
|
s.elb = &FakeELB{aws: s}
|
|
s.elbv2 = &FakeELBV2{aws: s}
|
|
s.asg = &FakeASG{aws: s}
|
|
s.metadata = &FakeMetadata{aws: s}
|
|
s.kms = &FakeKMS{aws: s}
|
|
|
|
s.networkInterfacesMacs = []string{"aa:bb:cc:dd:ee:00", "aa:bb:cc:dd:ee:01"}
|
|
s.networkInterfacesVpcIDs = []string{"vpc-mac0", "vpc-mac1"}
|
|
|
|
selfInstance := &ec2.Instance{}
|
|
selfInstance.InstanceId = aws.String("i-self")
|
|
selfInstance.Placement = &ec2.Placement{
|
|
AvailabilityZone: aws.String("us-east-1a"),
|
|
}
|
|
selfInstance.PrivateDnsName = aws.String("ip-172-20-0-100.ec2.internal")
|
|
selfInstance.PrivateIpAddress = aws.String("192.168.0.1")
|
|
selfInstance.PublicIpAddress = aws.String("1.2.3.4")
|
|
s.selfInstance = selfInstance
|
|
s.instances = []*ec2.Instance{selfInstance}
|
|
|
|
var tag ec2.Tag
|
|
tag.Key = aws.String(TagNameKubernetesClusterLegacy)
|
|
tag.Value = aws.String(clusterID)
|
|
selfInstance.Tags = []*ec2.Tag{&tag}
|
|
|
|
return s
|
|
}
|
|
|
|
// WithAz sets the ec2 placement availability zone
|
|
func (s *FakeAWSServices) WithAz(az string) *FakeAWSServices {
|
|
if s.selfInstance.Placement == nil {
|
|
s.selfInstance.Placement = &ec2.Placement{}
|
|
}
|
|
s.selfInstance.Placement.AvailabilityZone = aws.String(az)
|
|
return s
|
|
}
|
|
|
|
// Compute returns a fake EC2 client
|
|
func (s *FakeAWSServices) Compute(region string) (EC2, error) {
|
|
return s.ec2, nil
|
|
}
|
|
|
|
// LoadBalancing returns a fake ELB client
|
|
func (s *FakeAWSServices) LoadBalancing(region string) (ELB, error) {
|
|
return s.elb, nil
|
|
}
|
|
|
|
// LoadBalancingV2 returns a fake ELBV2 client
|
|
func (s *FakeAWSServices) LoadBalancingV2(region string) (ELBV2, error) {
|
|
return s.elbv2, nil
|
|
}
|
|
|
|
// Autoscaling returns a fake ASG client
|
|
func (s *FakeAWSServices) Autoscaling(region string) (ASG, error) {
|
|
return s.asg, nil
|
|
}
|
|
|
|
// Metadata returns a fake EC2Metadata client
|
|
func (s *FakeAWSServices) Metadata() (EC2Metadata, error) {
|
|
return s.metadata, nil
|
|
}
|
|
|
|
// KeyManagement returns a fake KMS client
|
|
func (s *FakeAWSServices) KeyManagement(region string) (KMS, error) {
|
|
return s.kms, nil
|
|
}
|
|
|
|
// FakeEC2 is a fake EC2 client used for testing
|
|
type FakeEC2 interface {
|
|
EC2
|
|
CreateSubnet(*ec2.Subnet) (*ec2.CreateSubnetOutput, error)
|
|
RemoveSubnets()
|
|
CreateRouteTable(*ec2.RouteTable) (*ec2.CreateRouteTableOutput, error)
|
|
RemoveRouteTables()
|
|
}
|
|
|
|
// FakeEC2Impl is an implementation of the FakeEC2 interface used for testing
|
|
type FakeEC2Impl struct {
|
|
aws *FakeAWSServices
|
|
Subnets []*ec2.Subnet
|
|
DescribeSubnetsInput *ec2.DescribeSubnetsInput
|
|
RouteTables []*ec2.RouteTable
|
|
DescribeRouteTablesInput *ec2.DescribeRouteTablesInput
|
|
}
|
|
|
|
// DescribeInstances returns fake instance descriptions
|
|
func (ec2i *FakeEC2Impl) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) {
|
|
matches := []*ec2.Instance{}
|
|
for _, instance := range ec2i.aws.instances {
|
|
if request.InstanceIds != nil {
|
|
if instance.InstanceId == nil {
|
|
klog.Warning("Instance with no instance id: ", instance)
|
|
continue
|
|
}
|
|
|
|
found := false
|
|
for _, instanceID := range request.InstanceIds {
|
|
if *instanceID == *instance.InstanceId {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
continue
|
|
}
|
|
}
|
|
if request.Filters != nil {
|
|
allMatch := true
|
|
for _, filter := range request.Filters {
|
|
if !instanceMatchesFilter(instance, filter) {
|
|
allMatch = false
|
|
break
|
|
}
|
|
}
|
|
if !allMatch {
|
|
continue
|
|
}
|
|
}
|
|
matches = append(matches, instance)
|
|
}
|
|
|
|
return matches, nil
|
|
}
|
|
|
|
// AttachVolume is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) AttachVolume(request *ec2.AttachVolumeInput) (resp *ec2.VolumeAttachment, err error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DetachVolume is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) DetachVolume(request *ec2.DetachVolumeInput) (resp *ec2.VolumeAttachment, err error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeVolumes is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) DescribeVolumes(request *ec2.DescribeVolumesInput) ([]*ec2.Volume, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateVolume is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) CreateVolume(request *ec2.CreateVolumeInput) (resp *ec2.Volume, err error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteVolume is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) DeleteVolume(request *ec2.DeleteVolumeInput) (resp *ec2.DeleteVolumeOutput, err error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeSecurityGroups is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) DescribeSecurityGroups(request *ec2.DescribeSecurityGroupsInput) ([]*ec2.SecurityGroup, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateSecurityGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) CreateSecurityGroup(*ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteSecurityGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) DeleteSecurityGroup(*ec2.DeleteSecurityGroupInput) (*ec2.DeleteSecurityGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// AuthorizeSecurityGroupIngress is not implemented but is required for
|
|
// interface conformance
|
|
func (ec2i *FakeEC2Impl) AuthorizeSecurityGroupIngress(*ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// RevokeSecurityGroupIngress is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) RevokeSecurityGroupIngress(*ec2.RevokeSecurityGroupIngressInput) (*ec2.RevokeSecurityGroupIngressOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeVolumeModifications is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) DescribeVolumeModifications(*ec2.DescribeVolumesModificationsInput) ([]*ec2.VolumeModification, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyVolume is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) ModifyVolume(*ec2.ModifyVolumeInput) (*ec2.ModifyVolumeOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateSubnet creates fake subnets
|
|
func (ec2i *FakeEC2Impl) CreateSubnet(request *ec2.Subnet) (*ec2.CreateSubnetOutput, error) {
|
|
ec2i.Subnets = append(ec2i.Subnets, request)
|
|
response := &ec2.CreateSubnetOutput{
|
|
Subnet: request,
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
// DescribeSubnets returns fake subnet descriptions
|
|
func (ec2i *FakeEC2Impl) DescribeSubnets(request *ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) {
|
|
ec2i.DescribeSubnetsInput = request
|
|
return ec2i.Subnets, nil
|
|
}
|
|
|
|
// RemoveSubnets clears subnets on client
|
|
func (ec2i *FakeEC2Impl) RemoveSubnets() {
|
|
ec2i.Subnets = ec2i.Subnets[:0]
|
|
}
|
|
|
|
// CreateTags is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) CreateTags(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeRouteTables returns fake route table descriptions
|
|
func (ec2i *FakeEC2Impl) DescribeRouteTables(request *ec2.DescribeRouteTablesInput) ([]*ec2.RouteTable, error) {
|
|
ec2i.DescribeRouteTablesInput = request
|
|
return ec2i.RouteTables, nil
|
|
}
|
|
|
|
// CreateRouteTable creates fake route tables
|
|
func (ec2i *FakeEC2Impl) CreateRouteTable(request *ec2.RouteTable) (*ec2.CreateRouteTableOutput, error) {
|
|
ec2i.RouteTables = append(ec2i.RouteTables, request)
|
|
response := &ec2.CreateRouteTableOutput{
|
|
RouteTable: request,
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
// RemoveRouteTables clears route tables on client
|
|
func (ec2i *FakeEC2Impl) RemoveRouteTables() {
|
|
ec2i.RouteTables = ec2i.RouteTables[:0]
|
|
}
|
|
|
|
// CreateRoute is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) CreateRoute(request *ec2.CreateRouteInput) (*ec2.CreateRouteOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteRoute is not implemented but is required for interface conformance
|
|
func (ec2i *FakeEC2Impl) DeleteRoute(request *ec2.DeleteRouteInput) (*ec2.DeleteRouteOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyInstanceAttribute is not implemented but is required for interface
|
|
// conformance
|
|
func (ec2i *FakeEC2Impl) ModifyInstanceAttribute(request *ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeVpcs returns fake VPC descriptions
|
|
func (ec2i *FakeEC2Impl) DescribeVpcs(request *ec2.DescribeVpcsInput) (*ec2.DescribeVpcsOutput, error) {
|
|
return &ec2.DescribeVpcsOutput{Vpcs: []*ec2.Vpc{{CidrBlock: aws.String("172.20.0.0/16")}}}, nil
|
|
}
|
|
|
|
// FakeMetadata is a fake EC2 metadata service client used for testing
|
|
type FakeMetadata struct {
|
|
aws *FakeAWSServices
|
|
}
|
|
|
|
// GetMetadata returns fake EC2 metadata for testing
|
|
func (m *FakeMetadata) GetMetadata(key string) (string, error) {
|
|
networkInterfacesPrefix := "network/interfaces/macs/"
|
|
i := m.aws.selfInstance
|
|
if key == "placement/availability-zone" {
|
|
az := ""
|
|
if i.Placement != nil {
|
|
az = aws.StringValue(i.Placement.AvailabilityZone)
|
|
}
|
|
return az, nil
|
|
} else if key == "instance-id" {
|
|
return aws.StringValue(i.InstanceId), nil
|
|
} else if key == "local-hostname" {
|
|
return aws.StringValue(i.PrivateDnsName), nil
|
|
} else if key == "public-hostname" {
|
|
return aws.StringValue(i.PublicDnsName), nil
|
|
} else if key == "local-ipv4" {
|
|
return aws.StringValue(i.PrivateIpAddress), nil
|
|
} else if key == "public-ipv4" {
|
|
return aws.StringValue(i.PublicIpAddress), nil
|
|
} else if strings.HasPrefix(key, networkInterfacesPrefix) {
|
|
if key == networkInterfacesPrefix {
|
|
// Return the MACs sorted lexically rather than in device-number
|
|
// order; this matches AWS's observed behavior and lets us test
|
|
// that we fix up the ordering correctly in NodeAddresses().
|
|
macs := make([]string, len(m.aws.networkInterfacesMacs))
|
|
copy(macs, m.aws.networkInterfacesMacs)
|
|
sort.Strings(macs)
|
|
return strings.Join(macs, "/\n") + "/\n", nil
|
|
}
|
|
|
|
keySplit := strings.Split(key, "/")
|
|
macParam := keySplit[3]
|
|
if len(keySplit) == 5 && keySplit[4] == "vpc-id" {
|
|
for i, macElem := range m.aws.networkInterfacesMacs {
|
|
if macParam == macElem {
|
|
return m.aws.networkInterfacesVpcIDs[i], nil
|
|
}
|
|
}
|
|
}
|
|
if len(keySplit) == 5 && keySplit[4] == "device-number" {
|
|
for i, macElem := range m.aws.networkInterfacesMacs {
|
|
if macParam == macElem {
|
|
n := i
|
|
if n > 0 {
|
|
// Introduce an artificial gap, just to test eg: [eth0, eth2]
|
|
n++
|
|
}
|
|
return fmt.Sprintf("%d\n", n), nil
|
|
}
|
|
}
|
|
}
|
|
if len(keySplit) == 5 && keySplit[4] == "local-ipv4s" {
|
|
for i, macElem := range m.aws.networkInterfacesMacs {
|
|
if macParam == macElem {
|
|
return strings.Join(m.aws.networkInterfacesPrivateIPs[i], "/\n"), nil
|
|
}
|
|
}
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
// FakeELB is a fake ELB client used for testing
|
|
type FakeELB struct {
|
|
aws *FakeAWSServices
|
|
}
|
|
|
|
// CreateLoadBalancer is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) CreateLoadBalancer(*elb.CreateLoadBalancerInput) (*elb.CreateLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteLoadBalancer is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) DeleteLoadBalancer(input *elb.DeleteLoadBalancerInput) (*elb.DeleteLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeLoadBalancers is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) DescribeLoadBalancers(input *elb.DescribeLoadBalancersInput) (*elb.DescribeLoadBalancersOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// AddTags is not implemented but is required for interface conformance
|
|
func (elb *FakeELB) AddTags(input *elb.AddTagsInput) (*elb.AddTagsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// RegisterInstancesWithLoadBalancer is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) RegisterInstancesWithLoadBalancer(*elb.RegisterInstancesWithLoadBalancerInput) (*elb.RegisterInstancesWithLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeregisterInstancesFromLoadBalancer is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstancesFromLoadBalancerInput) (*elb.DeregisterInstancesFromLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DetachLoadBalancerFromSubnets is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) DetachLoadBalancerFromSubnets(*elb.DetachLoadBalancerFromSubnetsInput) (*elb.DetachLoadBalancerFromSubnetsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// AttachLoadBalancerToSubnets is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) AttachLoadBalancerToSubnets(*elb.AttachLoadBalancerToSubnetsInput) (*elb.AttachLoadBalancerToSubnetsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateLoadBalancerListeners is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) CreateLoadBalancerListeners(*elb.CreateLoadBalancerListenersInput) (*elb.CreateLoadBalancerListenersOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteLoadBalancerListeners is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) DeleteLoadBalancerListeners(*elb.DeleteLoadBalancerListenersInput) (*elb.DeleteLoadBalancerListenersOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ApplySecurityGroupsToLoadBalancer is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) ApplySecurityGroupsToLoadBalancer(*elb.ApplySecurityGroupsToLoadBalancerInput) (*elb.ApplySecurityGroupsToLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ConfigureHealthCheck is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) ConfigureHealthCheck(*elb.ConfigureHealthCheckInput) (*elb.ConfigureHealthCheckOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateLoadBalancerPolicy is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELB) CreateLoadBalancerPolicy(*elb.CreateLoadBalancerPolicyInput) (*elb.CreateLoadBalancerPolicyOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// SetLoadBalancerPoliciesForBackendServer is not implemented but is required
|
|
// for interface conformance
|
|
func (elb *FakeELB) SetLoadBalancerPoliciesForBackendServer(*elb.SetLoadBalancerPoliciesForBackendServerInput) (*elb.SetLoadBalancerPoliciesForBackendServerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// SetLoadBalancerPoliciesOfListener is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) SetLoadBalancerPoliciesOfListener(input *elb.SetLoadBalancerPoliciesOfListenerInput) (*elb.SetLoadBalancerPoliciesOfListenerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeLoadBalancerPolicies is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) DescribeLoadBalancerPolicies(input *elb.DescribeLoadBalancerPoliciesInput) (*elb.DescribeLoadBalancerPoliciesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeLoadBalancerAttributes is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) DescribeLoadBalancerAttributes(*elb.DescribeLoadBalancerAttributesInput) (*elb.DescribeLoadBalancerAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyLoadBalancerAttributes is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELB) ModifyLoadBalancerAttributes(*elb.ModifyLoadBalancerAttributesInput) (*elb.ModifyLoadBalancerAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// FakeELBV2 is a fake ELBV2 client used for testing
|
|
type FakeELBV2 struct {
|
|
aws *FakeAWSServices
|
|
}
|
|
|
|
// AddTags is not implemented but is required for interface conformance
|
|
func (elb *FakeELBV2) AddTags(input *elbv2.AddTagsInput) (*elbv2.AddTagsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateLoadBalancer is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) CreateLoadBalancer(*elbv2.CreateLoadBalancerInput) (*elbv2.CreateLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeLoadBalancers is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DescribeLoadBalancers(*elbv2.DescribeLoadBalancersInput) (*elbv2.DescribeLoadBalancersOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteLoadBalancer is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DeleteLoadBalancer(*elbv2.DeleteLoadBalancerInput) (*elbv2.DeleteLoadBalancerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyLoadBalancerAttributes is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELBV2) ModifyLoadBalancerAttributes(*elbv2.ModifyLoadBalancerAttributesInput) (*elbv2.ModifyLoadBalancerAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeLoadBalancerAttributes is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELBV2) DescribeLoadBalancerAttributes(*elbv2.DescribeLoadBalancerAttributesInput) (*elbv2.DescribeLoadBalancerAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateTargetGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) CreateTargetGroup(*elbv2.CreateTargetGroupInput) (*elbv2.CreateTargetGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeTargetGroups is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DescribeTargetGroups(*elbv2.DescribeTargetGroupsInput) (*elbv2.DescribeTargetGroupsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyTargetGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) ModifyTargetGroup(*elbv2.ModifyTargetGroupInput) (*elbv2.ModifyTargetGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteTargetGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DeleteTargetGroup(*elbv2.DeleteTargetGroupInput) (*elbv2.DeleteTargetGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeTargetHealth is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DescribeTargetHealth(input *elbv2.DescribeTargetHealthInput) (*elbv2.DescribeTargetHealthOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeTargetGroupAttributes is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELBV2) DescribeTargetGroupAttributes(*elbv2.DescribeTargetGroupAttributesInput) (*elbv2.DescribeTargetGroupAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyTargetGroupAttributes is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) ModifyTargetGroupAttributes(*elbv2.ModifyTargetGroupAttributesInput) (*elbv2.ModifyTargetGroupAttributesOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// RegisterTargets is not implemented but is required for interface conformance
|
|
func (elb *FakeELBV2) RegisterTargets(*elbv2.RegisterTargetsInput) (*elbv2.RegisterTargetsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeregisterTargets is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DeregisterTargets(*elbv2.DeregisterTargetsInput) (*elbv2.DeregisterTargetsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// CreateListener is not implemented but is required for interface conformance
|
|
func (elb *FakeELBV2) CreateListener(*elbv2.CreateListenerInput) (*elbv2.CreateListenerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeListeners is not implemented but is required for interface
|
|
// conformance
|
|
func (elb *FakeELBV2) DescribeListeners(*elbv2.DescribeListenersInput) (*elbv2.DescribeListenersOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DeleteListener is not implemented but is required for interface conformance
|
|
func (elb *FakeELBV2) DeleteListener(*elbv2.DeleteListenerInput) (*elbv2.DeleteListenerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// ModifyListener is not implemented but is required for interface conformance
|
|
func (elb *FakeELBV2) ModifyListener(*elbv2.ModifyListenerInput) (*elbv2.ModifyListenerOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// WaitUntilLoadBalancersDeleted is not implemented but is required for
|
|
// interface conformance
|
|
func (elb *FakeELBV2) WaitUntilLoadBalancersDeleted(*elbv2.DescribeLoadBalancersInput) error {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// FakeASG is a fake Autoscaling client used for testing
|
|
type FakeASG struct {
|
|
aws *FakeAWSServices
|
|
}
|
|
|
|
// UpdateAutoScalingGroup is not implemented but is required for interface
|
|
// conformance
|
|
func (a *FakeASG) UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// DescribeAutoScalingGroups is not implemented but is required for interface
|
|
// conformance
|
|
func (a *FakeASG) DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// FakeKMS is a fake KMS client used for testing
|
|
type FakeKMS struct {
|
|
aws *FakeAWSServices
|
|
}
|
|
|
|
// DescribeKey is not implemented but is required for interface conformance
|
|
func (kms *FakeKMS) DescribeKey(*kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
func instanceMatchesFilter(instance *ec2.Instance, filter *ec2.Filter) bool {
|
|
name := *filter.Name
|
|
if name == "private-dns-name" {
|
|
if instance.PrivateDnsName == nil {
|
|
return false
|
|
}
|
|
return contains(filter.Values, *instance.PrivateDnsName)
|
|
}
|
|
|
|
if name == "instance-state-name" {
|
|
return contains(filter.Values, *instance.State.Name)
|
|
}
|
|
|
|
if name == "tag-key" {
|
|
for _, instanceTag := range instance.Tags {
|
|
if contains(filter.Values, aws.StringValue(instanceTag.Key)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
if strings.HasPrefix(name, "tag:") {
|
|
tagName := name[4:]
|
|
for _, instanceTag := range instance.Tags {
|
|
if aws.StringValue(instanceTag.Key) == tagName && contains(filter.Values, aws.StringValue(instanceTag.Value)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
panic("Unknown filter name: " + name)
|
|
}
|
|
|
|
func contains(haystack []*string, needle string) bool {
|
|
for _, s := range haystack {
|
|
// (deliberately panic if s == nil)
|
|
if needle == *s {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|