Merge pull request #9922 from justinsb/aws_resize_tests

AWS: Enable resize tests
pull/6/head
Maxwell Forbes 2015-06-24 16:43:37 -07:00
commit e71d162e9a
11 changed files with 5980 additions and 28 deletions

5
Godeps/Godeps.json generated
View File

@ -88,6 +88,11 @@
"Comment": "v0.6.0-7-gcea3a42", "Comment": "v0.6.0-7-gcea3a42",
"Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f"
}, },
{
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
"Comment": "v0.6.0-7-gcea3a42",
"Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f"
},
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2", "ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
"Comment": "v0.6.0-7-gcea3a42", "Comment": "v0.6.0-7-gcea3a42",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,101 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
// Package autoscalingiface provides an interface for the Auto Scaling.
package autoscalingiface
import (
"github.com/aws/aws-sdk-go/service/autoscaling"
)
// AutoScalingAPI is the interface type for autoscaling.AutoScaling.
type AutoScalingAPI interface {
AttachInstances(*autoscaling.AttachInstancesInput) (*autoscaling.AttachInstancesOutput, error)
CompleteLifecycleAction(*autoscaling.CompleteLifecycleActionInput) (*autoscaling.CompleteLifecycleActionOutput, error)
CreateAutoScalingGroup(*autoscaling.CreateAutoScalingGroupInput) (*autoscaling.CreateAutoScalingGroupOutput, error)
CreateLaunchConfiguration(*autoscaling.CreateLaunchConfigurationInput) (*autoscaling.CreateLaunchConfigurationOutput, error)
CreateOrUpdateTags(*autoscaling.CreateOrUpdateTagsInput) (*autoscaling.CreateOrUpdateTagsOutput, error)
DeleteAutoScalingGroup(*autoscaling.DeleteAutoScalingGroupInput) (*autoscaling.DeleteAutoScalingGroupOutput, error)
DeleteLaunchConfiguration(*autoscaling.DeleteLaunchConfigurationInput) (*autoscaling.DeleteLaunchConfigurationOutput, error)
DeleteLifecycleHook(*autoscaling.DeleteLifecycleHookInput) (*autoscaling.DeleteLifecycleHookOutput, error)
DeleteNotificationConfiguration(*autoscaling.DeleteNotificationConfigurationInput) (*autoscaling.DeleteNotificationConfigurationOutput, error)
DeletePolicy(*autoscaling.DeletePolicyInput) (*autoscaling.DeletePolicyOutput, error)
DeleteScheduledAction(*autoscaling.DeleteScheduledActionInput) (*autoscaling.DeleteScheduledActionOutput, error)
DeleteTags(*autoscaling.DeleteTagsInput) (*autoscaling.DeleteTagsOutput, error)
DescribeAccountLimits(*autoscaling.DescribeAccountLimitsInput) (*autoscaling.DescribeAccountLimitsOutput, error)
DescribeAdjustmentTypes(*autoscaling.DescribeAdjustmentTypesInput) (*autoscaling.DescribeAdjustmentTypesOutput, error)
DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error)
DescribeAutoScalingInstances(*autoscaling.DescribeAutoScalingInstancesInput) (*autoscaling.DescribeAutoScalingInstancesOutput, error)
DescribeAutoScalingNotificationTypes(*autoscaling.DescribeAutoScalingNotificationTypesInput) (*autoscaling.DescribeAutoScalingNotificationTypesOutput, error)
DescribeLaunchConfigurations(*autoscaling.DescribeLaunchConfigurationsInput) (*autoscaling.DescribeLaunchConfigurationsOutput, error)
DescribeLifecycleHookTypes(*autoscaling.DescribeLifecycleHookTypesInput) (*autoscaling.DescribeLifecycleHookTypesOutput, error)
DescribeLifecycleHooks(*autoscaling.DescribeLifecycleHooksInput) (*autoscaling.DescribeLifecycleHooksOutput, error)
DescribeMetricCollectionTypes(*autoscaling.DescribeMetricCollectionTypesInput) (*autoscaling.DescribeMetricCollectionTypesOutput, error)
DescribeNotificationConfigurations(*autoscaling.DescribeNotificationConfigurationsInput) (*autoscaling.DescribeNotificationConfigurationsOutput, error)
DescribePolicies(*autoscaling.DescribePoliciesInput) (*autoscaling.DescribePoliciesOutput, error)
DescribeScalingActivities(*autoscaling.DescribeScalingActivitiesInput) (*autoscaling.DescribeScalingActivitiesOutput, error)
DescribeScalingProcessTypes(*autoscaling.DescribeScalingProcessTypesInput) (*autoscaling.DescribeScalingProcessTypesOutput, error)
DescribeScheduledActions(*autoscaling.DescribeScheduledActionsInput) (*autoscaling.DescribeScheduledActionsOutput, error)
DescribeTags(*autoscaling.DescribeTagsInput) (*autoscaling.DescribeTagsOutput, error)
DescribeTerminationPolicyTypes(*autoscaling.DescribeTerminationPolicyTypesInput) (*autoscaling.DescribeTerminationPolicyTypesOutput, error)
DetachInstances(*autoscaling.DetachInstancesInput) (*autoscaling.DetachInstancesOutput, error)
DisableMetricsCollection(*autoscaling.DisableMetricsCollectionInput) (*autoscaling.DisableMetricsCollectionOutput, error)
EnableMetricsCollection(*autoscaling.EnableMetricsCollectionInput) (*autoscaling.EnableMetricsCollectionOutput, error)
EnterStandby(*autoscaling.EnterStandbyInput) (*autoscaling.EnterStandbyOutput, error)
ExecutePolicy(*autoscaling.ExecutePolicyInput) (*autoscaling.ExecutePolicyOutput, error)
ExitStandby(*autoscaling.ExitStandbyInput) (*autoscaling.ExitStandbyOutput, error)
PutLifecycleHook(*autoscaling.PutLifecycleHookInput) (*autoscaling.PutLifecycleHookOutput, error)
PutNotificationConfiguration(*autoscaling.PutNotificationConfigurationInput) (*autoscaling.PutNotificationConfigurationOutput, error)
PutScalingPolicy(*autoscaling.PutScalingPolicyInput) (*autoscaling.PutScalingPolicyOutput, error)
PutScheduledUpdateGroupAction(*autoscaling.PutScheduledUpdateGroupActionInput) (*autoscaling.PutScheduledUpdateGroupActionOutput, error)
RecordLifecycleActionHeartbeat(*autoscaling.RecordLifecycleActionHeartbeatInput) (*autoscaling.RecordLifecycleActionHeartbeatOutput, error)
ResumeProcesses(*autoscaling.ScalingProcessQuery) (*autoscaling.ResumeProcessesOutput, error)
SetDesiredCapacity(*autoscaling.SetDesiredCapacityInput) (*autoscaling.SetDesiredCapacityOutput, error)
SetInstanceHealth(*autoscaling.SetInstanceHealthInput) (*autoscaling.SetInstanceHealthOutput, error)
SuspendProcesses(*autoscaling.ScalingProcessQuery) (*autoscaling.SuspendProcessesOutput, error)
TerminateInstanceInAutoScalingGroup(*autoscaling.TerminateInstanceInAutoScalingGroupInput) (*autoscaling.TerminateInstanceInAutoScalingGroupOutput, error)
UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error)
}

View File

@ -0,0 +1,15 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package autoscalingiface_test
import (
"testing"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
"github.com/stretchr/testify/assert"
)
func TestInterface(t *testing.T) {
assert.Implements(t, (*autoscalingiface.AutoScalingAPI)(nil), autoscaling.New(nil))
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package autoscaling
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/internal/protocol/query"
"github.com/aws/aws-sdk-go/internal/signer/v4"
)
// AutoScaling is a client for Auto Scaling.
type AutoScaling struct {
*aws.Service
}
// Used for custom service initialization logic
var initService func(*aws.Service)
// Used for custom request initialization logic
var initRequest func(*aws.Request)
// New returns a new AutoScaling client.
func New(config *aws.Config) *AutoScaling {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "autoscaling",
APIVersion: "2011-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(query.Build)
service.Handlers.Unmarshal.PushBack(query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
// Run custom service initialization if present
if initService != nil {
initService(service)
}
return &AutoScaling{service}
}
// newRequest creates a new request for a AutoScaling operation and runs any
// custom request initialization.
func (c *AutoScaling) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

View File

@ -33,6 +33,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/elb"
@ -52,6 +53,7 @@ const TagNameKubernetesCluster = "KubernetesCluster"
type AWSServices interface { type AWSServices interface {
Compute(region string) (EC2, error) Compute(region string) (EC2, error)
LoadBalancing(region string) (ELB, error) LoadBalancing(region string) (ELB, error)
Autoscaling(region string) (ASG, error)
Metadata() AWSMetadata Metadata() AWSMetadata
} }
@ -103,6 +105,12 @@ type ELB interface {
DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstancesFromLoadBalancerInput) (*elb.DeregisterInstancesFromLoadBalancerOutput, error) DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstancesFromLoadBalancerInput) (*elb.DeregisterInstancesFromLoadBalancerOutput, error)
} }
// This is a simple pass-through of the Autoscaling client interface, which allows for testing
type ASG interface {
UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error)
DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error)
}
// Abstraction over the AWS metadata service // Abstraction over the AWS metadata service
type AWSMetadata interface { type AWSMetadata interface {
// Query the EC2 metadata service (used to discover instance-id etc) // Query the EC2 metadata service (used to discover instance-id etc)
@ -114,6 +122,7 @@ type VolumeOptions struct {
} }
// Volumes is an interface for managing cloud-provisioned volumes // Volumes is an interface for managing cloud-provisioned volumes
// TODO: Allow other clouds to implement this
type Volumes interface { type Volumes interface {
// Attach the disk to the specified instance // Attach the disk to the specified instance
// instanceName can be empty to mean "the instance on which we are running" // instanceName can be empty to mean "the instance on which we are running"
@ -128,10 +137,26 @@ type Volumes interface {
DeleteVolume(volumeName string) error DeleteVolume(volumeName string) error
} }
// InstanceGroups is an interface for managing cloud-managed instance groups / autoscaling instance groups
// TODO: Allow other clouds to implement this
type InstanceGroups interface {
// Set the size to the fixed size
ResizeInstanceGroup(instanceGroupName string, size int) error
// Queries the cloud provider for information about the specified instance group
DescribeInstanceGroup(instanceGroupName string) (InstanceGroupInfo, error)
}
// InstanceGroupInfo is returned by InstanceGroups.Describe, and exposes information about the group.
type InstanceGroupInfo interface {
// The number of instances currently running under control of this group
CurrentSize() (int, error)
}
// AWSCloud is an implementation of Interface, TCPLoadBalancer and Instances for Amazon Web Services. // AWSCloud is an implementation of Interface, TCPLoadBalancer and Instances for Amazon Web Services.
type AWSCloud struct { type AWSCloud struct {
awsServices AWSServices awsServices AWSServices
ec2 EC2 ec2 EC2
asg ASG
cfg *AWSCloudConfig cfg *AWSCloudConfig
availabilityZone string availabilityZone string
region string region string
@ -183,6 +208,14 @@ func (p *awsSDKProvider) LoadBalancing(regionName string) (ELB, error) {
return elbClient, nil return elbClient, nil
} }
func (p *awsSDKProvider) Autoscaling(regionName string) (ASG, error) {
client := autoscaling.New(&aws.Config{
Region: regionName,
Credentials: p.creds,
})
return client, nil
}
func (p *awsSDKProvider) Metadata() AWSMetadata { func (p *awsSDKProvider) Metadata() AWSMetadata {
return &awsSdkMetadata{} return &awsSdkMetadata{}
} }
@ -512,10 +545,19 @@ func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) {
} }
ec2, err := awsServices.Compute(regionName) ec2, err := awsServices.Compute(regionName)
if err != nil {
return nil, fmt.Errorf("error creating AWS EC2 client: %v", err)
}
asg, err := awsServices.Autoscaling(regionName)
if err != nil {
return nil, fmt.Errorf("error creating AWS autoscaling client: %v", err)
}
awsCloud := &AWSCloud{ awsCloud := &AWSCloud{
awsServices: awsServices, awsServices: awsServices,
ec2: ec2, ec2: ec2,
asg: asg,
cfg: cfg, cfg: cfg,
region: regionName, region: regionName,
availabilityZone: zone, availabilityZone: zone,

View File

@ -0,0 +1,75 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
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_cloud
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/golang/glog"
)
// AWSCloud implements InstanceGroups
var _ InstanceGroups = &AWSCloud{}
// Implement InstanceGroups.ResizeInstanceGroup
// Set the size to the fixed size
func (a *AWSCloud) ResizeInstanceGroup(instanceGroupName string, size int) error {
request := &autoscaling.UpdateAutoScalingGroupInput{
AutoScalingGroupName: aws.String(instanceGroupName),
MinSize: aws.Long(int64(size)),
MaxSize: aws.Long(int64(size)),
}
if _, err := a.asg.UpdateAutoScalingGroup(request); err != nil {
return fmt.Errorf("error resizing AWS autoscaling group: %v", err)
}
return nil
}
// Implement InstanceGroups.DescribeInstanceGroup
// Queries the cloud provider for information about the specified instance group
func (a *AWSCloud) DescribeInstanceGroup(instanceGroupName string) (InstanceGroupInfo, error) {
request := &autoscaling.DescribeAutoScalingGroupsInput{
AutoScalingGroupNames: []*string{aws.String(instanceGroupName)},
}
response, err := a.asg.DescribeAutoScalingGroups(request)
if err != nil {
return nil, fmt.Errorf("error listing AWS autoscaling group (%s): %v", instanceGroupName, err)
}
if len(response.AutoScalingGroups) == 0 {
return nil, nil
}
if len(response.AutoScalingGroups) > 1 {
glog.Warning("AWS returned multiple autoscaling groups with name ", instanceGroupName)
}
group := response.AutoScalingGroups[0]
return &awsInstanceGroup{group: group}, nil
}
// awsInstanceGroup implements InstanceGroupInfo
var _ InstanceGroupInfo = &awsInstanceGroup{}
type awsInstanceGroup struct {
group *autoscaling.Group
}
// Implement InstanceGroupInfo.CurrentSize
// The number of instances currently running under control of this group
func (g *awsInstanceGroup) CurrentSize() (int, error) {
return len(g.group.Instances), nil
}

View File

@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/golang/glog" "github.com/golang/glog"
) )
@ -110,6 +111,7 @@ type FakeAWSServices struct {
ec2 *FakeEC2 ec2 *FakeEC2
elb *FakeELB elb *FakeELB
asg *FakeASG
metadata *FakeMetadata metadata *FakeMetadata
} }
@ -118,6 +120,7 @@ func NewFakeAWSServices() *FakeAWSServices {
s.availabilityZone = "us-east-1a" s.availabilityZone = "us-east-1a"
s.ec2 = &FakeEC2{aws: s} s.ec2 = &FakeEC2{aws: s}
s.elb = &FakeELB{aws: s} s.elb = &FakeELB{aws: s}
s.asg = &FakeASG{aws: s}
s.metadata = &FakeMetadata{aws: s} s.metadata = &FakeMetadata{aws: s}
s.instanceId = "i-self" s.instanceId = "i-self"
@ -151,6 +154,10 @@ func (s *FakeAWSServices) LoadBalancing(region string) (ELB, error) {
return s.elb, nil return s.elb, nil
} }
func (s *FakeAWSServices) Autoscaling(region string) (ASG, error) {
return s.asg, nil
}
func (s *FakeAWSServices) Metadata() AWSMetadata { func (s *FakeAWSServices) Metadata() AWSMetadata {
return s.metadata return s.metadata
} }
@ -396,6 +403,18 @@ func (ec2 *FakeELB) DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstances
panic("Not implemented") panic("Not implemented")
} }
type FakeASG struct {
aws *FakeAWSServices
}
func (a *FakeASG) UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error) {
panic("Not implemented")
}
func (a *FakeASG) DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error) {
panic("Not implemented")
}
func mockInstancesResp(instances []*ec2.Instance) *AWSCloud { func mockInstancesResp(instances []*ec2.Instance) *AWSCloud {
awsServices := NewFakeAWSServices().withInstances(instances) awsServices := NewFakeAWSServices().withInstances(instances)
return &AWSCloud{ return &AWSCloud{

View File

@ -90,7 +90,7 @@ func init() {
flag.StringVar(&cloudConfig.ProjectID, "gce-project", "", "The GCE project being used, if applicable") flag.StringVar(&cloudConfig.ProjectID, "gce-project", "", "The GCE project being used, if applicable")
flag.StringVar(&cloudConfig.Zone, "gce-zone", "", "GCE zone being used, if applicable") flag.StringVar(&cloudConfig.Zone, "gce-zone", "", "GCE zone being used, if applicable")
flag.StringVar(&cloudConfig.Cluster, "gke-cluster", "", "GKE name of cluster being used, if applicable") flag.StringVar(&cloudConfig.Cluster, "gke-cluster", "", "GKE name of cluster being used, if applicable")
flag.StringVar(&cloudConfig.NodeInstanceGroup, "node-instance-group", "", "Name of the managed instance group for nodes. Valid only for gce") flag.StringVar(&cloudConfig.NodeInstanceGroup, "node-instance-group", "", "Name of the managed instance group for nodes. Valid only for gce, gke or aws")
flag.IntVar(&cloudConfig.NumNodes, "num-nodes", -1, "Number of nodes in the cluster") flag.IntVar(&cloudConfig.NumNodes, "num-nodes", -1, "Number of nodes in the cluster")
flag.StringVar(&cloudConfig.ClusterTag, "cluster-tag", "", "Tag used to identify resources. Only required if provider is aws.") flag.StringVar(&cloudConfig.ClusterTag, "cluster-tag", "", "Tag used to identify resources. Only required if provider is aws.")

View File

@ -31,6 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/aws"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )
@ -38,38 +39,65 @@ import (
const serveHostnameImage = "gcr.io/google_containers/serve_hostname:1.1" const serveHostnameImage = "gcr.io/google_containers/serve_hostname:1.1"
func resizeGroup(size int) error { func resizeGroup(size int) error {
// TODO: make this hit the compute API directly instread of shelling out to gcloud. if testContext.Provider == "gce" || testContext.Provider == "gke" {
output, err := exec.Command("gcloud", "preview", "managed-instance-groups", "--project="+testContext.CloudConfig.ProjectID, "--zone="+testContext.CloudConfig.Zone, // TODO: make this hit the compute API directly instread of shelling out to gcloud.
"resize", testContext.CloudConfig.NodeInstanceGroup, fmt.Sprintf("--new-size=%v", size)).CombinedOutput() // TODO: make gce/gke implement InstanceGroups, so we can eliminate the per-provider logic
if err != nil { output, err := exec.Command("gcloud", "preview", "managed-instance-groups", "--project="+testContext.CloudConfig.ProjectID, "--zone="+testContext.CloudConfig.Zone,
Logf("Failed to resize node instance group: %v", string(output)) "resize", testContext.CloudConfig.NodeInstanceGroup, fmt.Sprintf("--new-size=%v", size)).CombinedOutput()
if err != nil {
Logf("Failed to resize node instance group: %v", string(output))
}
return err
} else {
// Supported by aws
instanceGroups, ok := testContext.CloudConfig.Provider.(aws_cloud.InstanceGroups)
if !ok {
return fmt.Errorf("Provider does not support InstanceGroups")
}
return instanceGroups.ResizeInstanceGroup(testContext.CloudConfig.NodeInstanceGroup, size)
} }
return err
} }
func groupSize() (int, error) { func groupSize() (int, error) {
// TODO: make this hit the compute API directly instread of shelling out to gcloud. if testContext.Provider == "gce" || testContext.Provider == "gke" {
output, err := exec.Command("gcloud", "preview", "managed-instance-groups", "--project="+testContext.CloudConfig.ProjectID, // TODO: make this hit the compute API directly instread of shelling out to gcloud.
"--zone="+testContext.CloudConfig.Zone, "describe", testContext.CloudConfig.NodeInstanceGroup).CombinedOutput() // TODO: make gce/gke implement InstanceGroups, so we can eliminate the per-provider logic
if err != nil { output, err := exec.Command("gcloud", "preview", "managed-instance-groups", "--project="+testContext.CloudConfig.ProjectID,
return -1, err "--zone="+testContext.CloudConfig.Zone, "describe", testContext.CloudConfig.NodeInstanceGroup).CombinedOutput()
} if err != nil {
pattern := "currentSize: " return -1, err
i := strings.Index(string(output), pattern) }
if i == -1 { pattern := "currentSize: "
return -1, fmt.Errorf("could not find '%s' in the output '%s'", pattern, output) i := strings.Index(string(output), pattern)
} if i == -1 {
truncated := output[i+len(pattern):] return -1, fmt.Errorf("could not find '%s' in the output '%s'", pattern, output)
j := strings.Index(string(truncated), "\n") }
if j == -1 { truncated := output[i+len(pattern):]
return -1, fmt.Errorf("could not find new line in the truncated output '%s'", truncated) j := strings.Index(string(truncated), "\n")
} if j == -1 {
return -1, fmt.Errorf("could not find new line in the truncated output '%s'", truncated)
}
currentSize, err := strconv.Atoi(string(truncated[:j])) currentSize, err := strconv.Atoi(string(truncated[:j]))
if err != nil { if err != nil {
return -1, err return -1, err
}
return currentSize, nil
} else {
// Supported by aws
instanceGroups, ok := testContext.CloudConfig.Provider.(aws_cloud.InstanceGroups)
if !ok {
return -1, fmt.Errorf("provider does not support InstanceGroups")
}
instanceGroup, err := instanceGroups.DescribeInstanceGroup(testContext.CloudConfig.NodeInstanceGroup)
if err != nil {
return -1, fmt.Errorf("error describing instance group: %v", err)
}
if instanceGroup == nil {
return -1, fmt.Errorf("instance group not found: %s", testContext.CloudConfig.NodeInstanceGroup)
}
return instanceGroup.CurrentSize()
} }
return currentSize, nil
} }
func waitForGroupSize(size int) error { func waitForGroupSize(size int) error {
@ -358,7 +386,7 @@ func performTemporaryNetworkFailure(c *client.Client, ns, rcName string, replica
} }
var _ = Describe("Nodes", func() { var _ = Describe("Nodes", func() {
supportedProviders := []string{"gce", "gke"} supportedProviders := []string{"aws", "gce", "gke"}
var testName string var testName string
var c *client.Client var c *client.Client
var ns string var ns string