1// +build !providerless 2 3/* 4Copyright 2017 The Kubernetes Authors. 5 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17*/ 18 19package aws 20 21import ( 22 "fmt" 23 "sort" 24 "strings" 25 26 "github.com/aws/aws-sdk-go/aws" 27 "github.com/aws/aws-sdk-go/service/autoscaling" 28 "github.com/aws/aws-sdk-go/service/ec2" 29 "github.com/aws/aws-sdk-go/service/elb" 30 "github.com/aws/aws-sdk-go/service/elbv2" 31 "github.com/aws/aws-sdk-go/service/kms" 32 "k8s.io/klog/v2" 33) 34 35// FakeAWSServices is an fake AWS session used for testing 36type FakeAWSServices struct { 37 region string 38 instances []*ec2.Instance 39 selfInstance *ec2.Instance 40 networkInterfacesMacs []string 41 networkInterfacesPrivateIPs [][]string 42 networkInterfacesVpcIDs []string 43 44 ec2 FakeEC2 45 elb ELB 46 elbv2 ELBV2 47 asg *FakeASG 48 metadata *FakeMetadata 49 kms *FakeKMS 50} 51 52// NewFakeAWSServices creates a new FakeAWSServices 53func NewFakeAWSServices(clusterID string) *FakeAWSServices { 54 s := &FakeAWSServices{} 55 s.region = "us-east-1" 56 s.ec2 = &FakeEC2Impl{aws: s} 57 s.elb = &FakeELB{aws: s} 58 s.elbv2 = &FakeELBV2{aws: s} 59 s.asg = &FakeASG{aws: s} 60 s.metadata = &FakeMetadata{aws: s} 61 s.kms = &FakeKMS{aws: s} 62 63 s.networkInterfacesMacs = []string{"aa:bb:cc:dd:ee:00", "aa:bb:cc:dd:ee:01"} 64 s.networkInterfacesVpcIDs = []string{"vpc-mac0", "vpc-mac1"} 65 66 selfInstance := &ec2.Instance{} 67 selfInstance.InstanceId = aws.String("i-self") 68 selfInstance.Placement = &ec2.Placement{ 69 AvailabilityZone: aws.String("us-east-1a"), 70 } 71 selfInstance.PrivateDnsName = aws.String("ip-172-20-0-100.ec2.internal") 72 selfInstance.PrivateIpAddress = aws.String("192.168.0.1") 73 selfInstance.PublicIpAddress = aws.String("1.2.3.4") 74 s.selfInstance = selfInstance 75 s.instances = []*ec2.Instance{selfInstance} 76 77 var tag ec2.Tag 78 tag.Key = aws.String(TagNameKubernetesClusterLegacy) 79 tag.Value = aws.String(clusterID) 80 selfInstance.Tags = []*ec2.Tag{&tag} 81 82 return s 83} 84 85// WithAz sets the ec2 placement availability zone 86func (s *FakeAWSServices) WithAz(az string) *FakeAWSServices { 87 if s.selfInstance.Placement == nil { 88 s.selfInstance.Placement = &ec2.Placement{} 89 } 90 s.selfInstance.Placement.AvailabilityZone = aws.String(az) 91 return s 92} 93 94// Compute returns a fake EC2 client 95func (s *FakeAWSServices) Compute(region string) (EC2, error) { 96 return s.ec2, nil 97} 98 99// LoadBalancing returns a fake ELB client 100func (s *FakeAWSServices) LoadBalancing(region string) (ELB, error) { 101 return s.elb, nil 102} 103 104// LoadBalancingV2 returns a fake ELBV2 client 105func (s *FakeAWSServices) LoadBalancingV2(region string) (ELBV2, error) { 106 return s.elbv2, nil 107} 108 109// Autoscaling returns a fake ASG client 110func (s *FakeAWSServices) Autoscaling(region string) (ASG, error) { 111 return s.asg, nil 112} 113 114// Metadata returns a fake EC2Metadata client 115func (s *FakeAWSServices) Metadata() (EC2Metadata, error) { 116 return s.metadata, nil 117} 118 119// KeyManagement returns a fake KMS client 120func (s *FakeAWSServices) KeyManagement(region string) (KMS, error) { 121 return s.kms, nil 122} 123 124// FakeEC2 is a fake EC2 client used for testing 125type FakeEC2 interface { 126 EC2 127 CreateSubnet(*ec2.Subnet) (*ec2.CreateSubnetOutput, error) 128 RemoveSubnets() 129 CreateRouteTable(*ec2.RouteTable) (*ec2.CreateRouteTableOutput, error) 130 RemoveRouteTables() 131} 132 133// FakeEC2Impl is an implementation of the FakeEC2 interface used for testing 134type FakeEC2Impl struct { 135 aws *FakeAWSServices 136 Subnets []*ec2.Subnet 137 DescribeSubnetsInput *ec2.DescribeSubnetsInput 138 RouteTables []*ec2.RouteTable 139 DescribeRouteTablesInput *ec2.DescribeRouteTablesInput 140} 141 142// DescribeInstances returns fake instance descriptions 143func (ec2i *FakeEC2Impl) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { 144 matches := []*ec2.Instance{} 145 for _, instance := range ec2i.aws.instances { 146 if request.InstanceIds != nil { 147 if instance.InstanceId == nil { 148 klog.Warning("Instance with no instance id: ", instance) 149 continue 150 } 151 152 found := false 153 for _, instanceID := range request.InstanceIds { 154 if *instanceID == *instance.InstanceId { 155 found = true 156 break 157 } 158 } 159 if !found { 160 continue 161 } 162 } 163 if request.Filters != nil { 164 allMatch := true 165 for _, filter := range request.Filters { 166 if !instanceMatchesFilter(instance, filter) { 167 allMatch = false 168 break 169 } 170 } 171 if !allMatch { 172 continue 173 } 174 } 175 matches = append(matches, instance) 176 } 177 178 return matches, nil 179} 180 181// AttachVolume is not implemented but is required for interface conformance 182func (ec2i *FakeEC2Impl) AttachVolume(request *ec2.AttachVolumeInput) (resp *ec2.VolumeAttachment, err error) { 183 panic("Not implemented") 184} 185 186// DetachVolume is not implemented but is required for interface conformance 187func (ec2i *FakeEC2Impl) DetachVolume(request *ec2.DetachVolumeInput) (resp *ec2.VolumeAttachment, err error) { 188 panic("Not implemented") 189} 190 191// DescribeVolumes is not implemented but is required for interface conformance 192func (ec2i *FakeEC2Impl) DescribeVolumes(request *ec2.DescribeVolumesInput) ([]*ec2.Volume, error) { 193 panic("Not implemented") 194} 195 196// CreateVolume is not implemented but is required for interface conformance 197func (ec2i *FakeEC2Impl) CreateVolume(request *ec2.CreateVolumeInput) (resp *ec2.Volume, err error) { 198 panic("Not implemented") 199} 200 201// DeleteVolume is not implemented but is required for interface conformance 202func (ec2i *FakeEC2Impl) DeleteVolume(request *ec2.DeleteVolumeInput) (resp *ec2.DeleteVolumeOutput, err error) { 203 panic("Not implemented") 204} 205 206// DescribeSecurityGroups is not implemented but is required for interface 207// conformance 208func (ec2i *FakeEC2Impl) DescribeSecurityGroups(request *ec2.DescribeSecurityGroupsInput) ([]*ec2.SecurityGroup, error) { 209 panic("Not implemented") 210} 211 212// CreateSecurityGroup is not implemented but is required for interface 213// conformance 214func (ec2i *FakeEC2Impl) CreateSecurityGroup(*ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) { 215 panic("Not implemented") 216} 217 218// DeleteSecurityGroup is not implemented but is required for interface 219// conformance 220func (ec2i *FakeEC2Impl) DeleteSecurityGroup(*ec2.DeleteSecurityGroupInput) (*ec2.DeleteSecurityGroupOutput, error) { 221 panic("Not implemented") 222} 223 224// AuthorizeSecurityGroupIngress is not implemented but is required for 225// interface conformance 226func (ec2i *FakeEC2Impl) AuthorizeSecurityGroupIngress(*ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) { 227 panic("Not implemented") 228} 229 230// RevokeSecurityGroupIngress is not implemented but is required for interface 231// conformance 232func (ec2i *FakeEC2Impl) RevokeSecurityGroupIngress(*ec2.RevokeSecurityGroupIngressInput) (*ec2.RevokeSecurityGroupIngressOutput, error) { 233 panic("Not implemented") 234} 235 236// DescribeVolumeModifications is not implemented but is required for interface 237// conformance 238func (ec2i *FakeEC2Impl) DescribeVolumeModifications(*ec2.DescribeVolumesModificationsInput) ([]*ec2.VolumeModification, error) { 239 panic("Not implemented") 240} 241 242// ModifyVolume is not implemented but is required for interface conformance 243func (ec2i *FakeEC2Impl) ModifyVolume(*ec2.ModifyVolumeInput) (*ec2.ModifyVolumeOutput, error) { 244 panic("Not implemented") 245} 246 247// CreateSubnet creates fake subnets 248func (ec2i *FakeEC2Impl) CreateSubnet(request *ec2.Subnet) (*ec2.CreateSubnetOutput, error) { 249 ec2i.Subnets = append(ec2i.Subnets, request) 250 response := &ec2.CreateSubnetOutput{ 251 Subnet: request, 252 } 253 return response, nil 254} 255 256// DescribeSubnets returns fake subnet descriptions 257func (ec2i *FakeEC2Impl) DescribeSubnets(request *ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) { 258 ec2i.DescribeSubnetsInput = request 259 return ec2i.Subnets, nil 260} 261 262// RemoveSubnets clears subnets on client 263func (ec2i *FakeEC2Impl) RemoveSubnets() { 264 ec2i.Subnets = ec2i.Subnets[:0] 265} 266 267// CreateTags is not implemented but is required for interface conformance 268func (ec2i *FakeEC2Impl) CreateTags(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) { 269 panic("Not implemented") 270} 271 272// DescribeRouteTables returns fake route table descriptions 273func (ec2i *FakeEC2Impl) DescribeRouteTables(request *ec2.DescribeRouteTablesInput) ([]*ec2.RouteTable, error) { 274 ec2i.DescribeRouteTablesInput = request 275 return ec2i.RouteTables, nil 276} 277 278// CreateRouteTable creates fake route tables 279func (ec2i *FakeEC2Impl) CreateRouteTable(request *ec2.RouteTable) (*ec2.CreateRouteTableOutput, error) { 280 ec2i.RouteTables = append(ec2i.RouteTables, request) 281 response := &ec2.CreateRouteTableOutput{ 282 RouteTable: request, 283 } 284 return response, nil 285} 286 287// RemoveRouteTables clears route tables on client 288func (ec2i *FakeEC2Impl) RemoveRouteTables() { 289 ec2i.RouteTables = ec2i.RouteTables[:0] 290} 291 292// CreateRoute is not implemented but is required for interface conformance 293func (ec2i *FakeEC2Impl) CreateRoute(request *ec2.CreateRouteInput) (*ec2.CreateRouteOutput, error) { 294 panic("Not implemented") 295} 296 297// DeleteRoute is not implemented but is required for interface conformance 298func (ec2i *FakeEC2Impl) DeleteRoute(request *ec2.DeleteRouteInput) (*ec2.DeleteRouteOutput, error) { 299 panic("Not implemented") 300} 301 302// ModifyInstanceAttribute is not implemented but is required for interface 303// conformance 304func (ec2i *FakeEC2Impl) ModifyInstanceAttribute(request *ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) { 305 panic("Not implemented") 306} 307 308// DescribeVpcs returns fake VPC descriptions 309func (ec2i *FakeEC2Impl) DescribeVpcs(request *ec2.DescribeVpcsInput) (*ec2.DescribeVpcsOutput, error) { 310 return &ec2.DescribeVpcsOutput{Vpcs: []*ec2.Vpc{{CidrBlock: aws.String("172.20.0.0/16")}}}, nil 311} 312 313// FakeMetadata is a fake EC2 metadata service client used for testing 314type FakeMetadata struct { 315 aws *FakeAWSServices 316} 317 318// GetMetadata returns fake EC2 metadata for testing 319func (m *FakeMetadata) GetMetadata(key string) (string, error) { 320 networkInterfacesPrefix := "network/interfaces/macs/" 321 i := m.aws.selfInstance 322 if key == "placement/availability-zone" { 323 az := "" 324 if i.Placement != nil { 325 az = aws.StringValue(i.Placement.AvailabilityZone) 326 } 327 return az, nil 328 } else if key == "instance-id" { 329 return aws.StringValue(i.InstanceId), nil 330 } else if key == "local-hostname" { 331 return aws.StringValue(i.PrivateDnsName), nil 332 } else if key == "public-hostname" { 333 return aws.StringValue(i.PublicDnsName), nil 334 } else if key == "local-ipv4" { 335 return aws.StringValue(i.PrivateIpAddress), nil 336 } else if key == "public-ipv4" { 337 return aws.StringValue(i.PublicIpAddress), nil 338 } else if strings.HasPrefix(key, networkInterfacesPrefix) { 339 if key == networkInterfacesPrefix { 340 // Return the MACs sorted lexically rather than in device-number 341 // order; this matches AWS's observed behavior and lets us test 342 // that we fix up the ordering correctly in NodeAddresses(). 343 macs := make([]string, len(m.aws.networkInterfacesMacs)) 344 copy(macs, m.aws.networkInterfacesMacs) 345 sort.Strings(macs) 346 return strings.Join(macs, "/\n") + "/\n", nil 347 } 348 349 keySplit := strings.Split(key, "/") 350 macParam := keySplit[3] 351 if len(keySplit) == 5 && keySplit[4] == "vpc-id" { 352 for i, macElem := range m.aws.networkInterfacesMacs { 353 if macParam == macElem { 354 return m.aws.networkInterfacesVpcIDs[i], nil 355 } 356 } 357 } 358 if len(keySplit) == 5 && keySplit[4] == "device-number" { 359 for i, macElem := range m.aws.networkInterfacesMacs { 360 if macParam == macElem { 361 n := i 362 if n > 0 { 363 // Introduce an artificial gap, just to test eg: [eth0, eth2] 364 n++ 365 } 366 return fmt.Sprintf("%d\n", n), nil 367 } 368 } 369 } 370 if len(keySplit) == 5 && keySplit[4] == "local-ipv4s" { 371 for i, macElem := range m.aws.networkInterfacesMacs { 372 if macParam == macElem { 373 return strings.Join(m.aws.networkInterfacesPrivateIPs[i], "/\n"), nil 374 } 375 } 376 } 377 378 return "", nil 379 } 380 381 return "", nil 382} 383 384// FakeELB is a fake ELB client used for testing 385type FakeELB struct { 386 aws *FakeAWSServices 387} 388 389// CreateLoadBalancer is not implemented but is required for interface 390// conformance 391func (elb *FakeELB) CreateLoadBalancer(*elb.CreateLoadBalancerInput) (*elb.CreateLoadBalancerOutput, error) { 392 panic("Not implemented") 393} 394 395// DeleteLoadBalancer is not implemented but is required for interface 396// conformance 397func (elb *FakeELB) DeleteLoadBalancer(input *elb.DeleteLoadBalancerInput) (*elb.DeleteLoadBalancerOutput, error) { 398 panic("Not implemented") 399} 400 401// DescribeLoadBalancers is not implemented but is required for interface 402// conformance 403func (elb *FakeELB) DescribeLoadBalancers(input *elb.DescribeLoadBalancersInput) (*elb.DescribeLoadBalancersOutput, error) { 404 panic("Not implemented") 405} 406 407// AddTags is not implemented but is required for interface conformance 408func (elb *FakeELB) AddTags(input *elb.AddTagsInput) (*elb.AddTagsOutput, error) { 409 panic("Not implemented") 410} 411 412// RegisterInstancesWithLoadBalancer is not implemented but is required for 413// interface conformance 414func (elb *FakeELB) RegisterInstancesWithLoadBalancer(*elb.RegisterInstancesWithLoadBalancerInput) (*elb.RegisterInstancesWithLoadBalancerOutput, error) { 415 panic("Not implemented") 416} 417 418// DeregisterInstancesFromLoadBalancer is not implemented but is required for 419// interface conformance 420func (elb *FakeELB) DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstancesFromLoadBalancerInput) (*elb.DeregisterInstancesFromLoadBalancerOutput, error) { 421 panic("Not implemented") 422} 423 424// DetachLoadBalancerFromSubnets is not implemented but is required for 425// interface conformance 426func (elb *FakeELB) DetachLoadBalancerFromSubnets(*elb.DetachLoadBalancerFromSubnetsInput) (*elb.DetachLoadBalancerFromSubnetsOutput, error) { 427 panic("Not implemented") 428} 429 430// AttachLoadBalancerToSubnets is not implemented but is required for interface 431// conformance 432func (elb *FakeELB) AttachLoadBalancerToSubnets(*elb.AttachLoadBalancerToSubnetsInput) (*elb.AttachLoadBalancerToSubnetsOutput, error) { 433 panic("Not implemented") 434} 435 436// CreateLoadBalancerListeners is not implemented but is required for interface 437// conformance 438func (elb *FakeELB) CreateLoadBalancerListeners(*elb.CreateLoadBalancerListenersInput) (*elb.CreateLoadBalancerListenersOutput, error) { 439 panic("Not implemented") 440} 441 442// DeleteLoadBalancerListeners is not implemented but is required for interface 443// conformance 444func (elb *FakeELB) DeleteLoadBalancerListeners(*elb.DeleteLoadBalancerListenersInput) (*elb.DeleteLoadBalancerListenersOutput, error) { 445 panic("Not implemented") 446} 447 448// ApplySecurityGroupsToLoadBalancer is not implemented but is required for 449// interface conformance 450func (elb *FakeELB) ApplySecurityGroupsToLoadBalancer(*elb.ApplySecurityGroupsToLoadBalancerInput) (*elb.ApplySecurityGroupsToLoadBalancerOutput, error) { 451 panic("Not implemented") 452} 453 454// ConfigureHealthCheck is not implemented but is required for interface 455// conformance 456func (elb *FakeELB) ConfigureHealthCheck(*elb.ConfigureHealthCheckInput) (*elb.ConfigureHealthCheckOutput, error) { 457 panic("Not implemented") 458} 459 460// CreateLoadBalancerPolicy is not implemented but is required for interface 461// conformance 462func (elb *FakeELB) CreateLoadBalancerPolicy(*elb.CreateLoadBalancerPolicyInput) (*elb.CreateLoadBalancerPolicyOutput, error) { 463 panic("Not implemented") 464} 465 466// SetLoadBalancerPoliciesForBackendServer is not implemented but is required 467// for interface conformance 468func (elb *FakeELB) SetLoadBalancerPoliciesForBackendServer(*elb.SetLoadBalancerPoliciesForBackendServerInput) (*elb.SetLoadBalancerPoliciesForBackendServerOutput, error) { 469 panic("Not implemented") 470} 471 472// SetLoadBalancerPoliciesOfListener is not implemented but is required for 473// interface conformance 474func (elb *FakeELB) SetLoadBalancerPoliciesOfListener(input *elb.SetLoadBalancerPoliciesOfListenerInput) (*elb.SetLoadBalancerPoliciesOfListenerOutput, error) { 475 panic("Not implemented") 476} 477 478// DescribeLoadBalancerPolicies is not implemented but is required for 479// interface conformance 480func (elb *FakeELB) DescribeLoadBalancerPolicies(input *elb.DescribeLoadBalancerPoliciesInput) (*elb.DescribeLoadBalancerPoliciesOutput, error) { 481 panic("Not implemented") 482} 483 484// DescribeLoadBalancerAttributes is not implemented but is required for 485// interface conformance 486func (elb *FakeELB) DescribeLoadBalancerAttributes(*elb.DescribeLoadBalancerAttributesInput) (*elb.DescribeLoadBalancerAttributesOutput, error) { 487 panic("Not implemented") 488} 489 490// ModifyLoadBalancerAttributes is not implemented but is required for 491// interface conformance 492func (elb *FakeELB) ModifyLoadBalancerAttributes(*elb.ModifyLoadBalancerAttributesInput) (*elb.ModifyLoadBalancerAttributesOutput, error) { 493 panic("Not implemented") 494} 495 496// FakeELBV2 is a fake ELBV2 client used for testing 497type FakeELBV2 struct { 498 aws *FakeAWSServices 499} 500 501// AddTags is not implemented but is required for interface conformance 502func (elb *FakeELBV2) AddTags(input *elbv2.AddTagsInput) (*elbv2.AddTagsOutput, error) { 503 panic("Not implemented") 504} 505 506// CreateLoadBalancer is not implemented but is required for interface 507// conformance 508func (elb *FakeELBV2) CreateLoadBalancer(*elbv2.CreateLoadBalancerInput) (*elbv2.CreateLoadBalancerOutput, error) { 509 panic("Not implemented") 510} 511 512// DescribeLoadBalancers is not implemented but is required for interface 513// conformance 514func (elb *FakeELBV2) DescribeLoadBalancers(*elbv2.DescribeLoadBalancersInput) (*elbv2.DescribeLoadBalancersOutput, error) { 515 panic("Not implemented") 516} 517 518// DeleteLoadBalancer is not implemented but is required for interface 519// conformance 520func (elb *FakeELBV2) DeleteLoadBalancer(*elbv2.DeleteLoadBalancerInput) (*elbv2.DeleteLoadBalancerOutput, error) { 521 panic("Not implemented") 522} 523 524// ModifyLoadBalancerAttributes is not implemented but is required for 525// interface conformance 526func (elb *FakeELBV2) ModifyLoadBalancerAttributes(*elbv2.ModifyLoadBalancerAttributesInput) (*elbv2.ModifyLoadBalancerAttributesOutput, error) { 527 panic("Not implemented") 528} 529 530// DescribeLoadBalancerAttributes is not implemented but is required for 531// interface conformance 532func (elb *FakeELBV2) DescribeLoadBalancerAttributes(*elbv2.DescribeLoadBalancerAttributesInput) (*elbv2.DescribeLoadBalancerAttributesOutput, error) { 533 panic("Not implemented") 534} 535 536// CreateTargetGroup is not implemented but is required for interface 537// conformance 538func (elb *FakeELBV2) CreateTargetGroup(*elbv2.CreateTargetGroupInput) (*elbv2.CreateTargetGroupOutput, error) { 539 panic("Not implemented") 540} 541 542// DescribeTargetGroups is not implemented but is required for interface 543// conformance 544func (elb *FakeELBV2) DescribeTargetGroups(*elbv2.DescribeTargetGroupsInput) (*elbv2.DescribeTargetGroupsOutput, error) { 545 panic("Not implemented") 546} 547 548// ModifyTargetGroup is not implemented but is required for interface 549// conformance 550func (elb *FakeELBV2) ModifyTargetGroup(*elbv2.ModifyTargetGroupInput) (*elbv2.ModifyTargetGroupOutput, error) { 551 panic("Not implemented") 552} 553 554// DeleteTargetGroup is not implemented but is required for interface 555// conformance 556func (elb *FakeELBV2) DeleteTargetGroup(*elbv2.DeleteTargetGroupInput) (*elbv2.DeleteTargetGroupOutput, error) { 557 panic("Not implemented") 558} 559 560// DescribeTargetHealth is not implemented but is required for interface 561// conformance 562func (elb *FakeELBV2) DescribeTargetHealth(input *elbv2.DescribeTargetHealthInput) (*elbv2.DescribeTargetHealthOutput, error) { 563 panic("Not implemented") 564} 565 566// DescribeTargetGroupAttributes is not implemented but is required for 567// interface conformance 568func (elb *FakeELBV2) DescribeTargetGroupAttributes(*elbv2.DescribeTargetGroupAttributesInput) (*elbv2.DescribeTargetGroupAttributesOutput, error) { 569 panic("Not implemented") 570} 571 572// ModifyTargetGroupAttributes is not implemented but is required for interface 573// conformance 574func (elb *FakeELBV2) ModifyTargetGroupAttributes(*elbv2.ModifyTargetGroupAttributesInput) (*elbv2.ModifyTargetGroupAttributesOutput, error) { 575 panic("Not implemented") 576} 577 578// RegisterTargets is not implemented but is required for interface conformance 579func (elb *FakeELBV2) RegisterTargets(*elbv2.RegisterTargetsInput) (*elbv2.RegisterTargetsOutput, error) { 580 panic("Not implemented") 581} 582 583// DeregisterTargets is not implemented but is required for interface 584// conformance 585func (elb *FakeELBV2) DeregisterTargets(*elbv2.DeregisterTargetsInput) (*elbv2.DeregisterTargetsOutput, error) { 586 panic("Not implemented") 587} 588 589// CreateListener is not implemented but is required for interface conformance 590func (elb *FakeELBV2) CreateListener(*elbv2.CreateListenerInput) (*elbv2.CreateListenerOutput, error) { 591 panic("Not implemented") 592} 593 594// DescribeListeners is not implemented but is required for interface 595// conformance 596func (elb *FakeELBV2) DescribeListeners(*elbv2.DescribeListenersInput) (*elbv2.DescribeListenersOutput, error) { 597 panic("Not implemented") 598} 599 600// DeleteListener is not implemented but is required for interface conformance 601func (elb *FakeELBV2) DeleteListener(*elbv2.DeleteListenerInput) (*elbv2.DeleteListenerOutput, error) { 602 panic("Not implemented") 603} 604 605// ModifyListener is not implemented but is required for interface conformance 606func (elb *FakeELBV2) ModifyListener(*elbv2.ModifyListenerInput) (*elbv2.ModifyListenerOutput, error) { 607 panic("Not implemented") 608} 609 610// WaitUntilLoadBalancersDeleted is not implemented but is required for 611// interface conformance 612func (elb *FakeELBV2) WaitUntilLoadBalancersDeleted(*elbv2.DescribeLoadBalancersInput) error { 613 panic("Not implemented") 614} 615 616// FakeASG is a fake Autoscaling client used for testing 617type FakeASG struct { 618 aws *FakeAWSServices 619} 620 621// UpdateAutoScalingGroup is not implemented but is required for interface 622// conformance 623func (a *FakeASG) UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error) { 624 panic("Not implemented") 625} 626 627// DescribeAutoScalingGroups is not implemented but is required for interface 628// conformance 629func (a *FakeASG) DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error) { 630 panic("Not implemented") 631} 632 633// FakeKMS is a fake KMS client used for testing 634type FakeKMS struct { 635 aws *FakeAWSServices 636} 637 638// DescribeKey is not implemented but is required for interface conformance 639func (kms *FakeKMS) DescribeKey(*kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error) { 640 panic("Not implemented") 641} 642 643func instanceMatchesFilter(instance *ec2.Instance, filter *ec2.Filter) bool { 644 name := *filter.Name 645 if name == "private-dns-name" { 646 if instance.PrivateDnsName == nil { 647 return false 648 } 649 return contains(filter.Values, *instance.PrivateDnsName) 650 } 651 652 if name == "instance-state-name" { 653 return contains(filter.Values, *instance.State.Name) 654 } 655 656 if name == "tag-key" { 657 for _, instanceTag := range instance.Tags { 658 if contains(filter.Values, aws.StringValue(instanceTag.Key)) { 659 return true 660 } 661 } 662 return false 663 } 664 665 if strings.HasPrefix(name, "tag:") { 666 tagName := name[4:] 667 for _, instanceTag := range instance.Tags { 668 if aws.StringValue(instanceTag.Key) == tagName && contains(filter.Values, aws.StringValue(instanceTag.Value)) { 669 return true 670 } 671 } 672 return false 673 } 674 675 panic("Unknown filter name: " + name) 676} 677 678func contains(haystack []*string, needle string) bool { 679 for _, s := range haystack { 680 // (deliberately panic if s == nil) 681 if needle == *s { 682 return true 683 } 684 } 685 return false 686} 687