diff --git a/pkg/cloudprovider/providers/aws/aws.go b/pkg/cloudprovider/providers/aws/aws.go index df406e06450..1d933551d2a 100644 --- a/pkg/cloudprovider/providers/aws/aws.go +++ b/pkg/cloudprovider/providers/aws/aws.go @@ -51,42 +51,54 @@ import ( "k8s.io/kubernetes/pkg/volume" ) +// ProviderName is the name of this cloud provider. const ProviderName = "aws" -// The tag name we use to differentiate multiple logically independent clusters running in the same AZ +// TagNameKubernetesCluster is the tag name we use to differentiate multiple +// logically independent clusters running in the same AZ const TagNameKubernetesCluster = "KubernetesCluster" -// The tag name we use to differentiate multiple services. Used currently for ELBs only. +// TagNameKubernetesService is the tag name we use to differentiate multiple +// services. Used currently for ELBs only. const TagNameKubernetesService = "kubernetes.io/service-name" -// The tag name used on a subnet to designate that it should be used for internal ELBs +// TagNameSubnetInternalELB is the tag name used on a subnet to designate that +// it should be used for internal ELBs const TagNameSubnetInternalELB = "kubernetes.io/role/internal-elb" -// The tag name used on a subnet to designate that it should be used for internet ELBs +// TagNameSubnetPublicELB is the tag name used on a subnet to designate that +// it should be used for internet ELBs const TagNameSubnetPublicELB = "kubernetes.io/role/elb" -// Annotation used on the service to indicate that we want an internal ELB. +// ServiceAnnotationLoadBalancerInternal is the annotation used on the service +// to indicate that we want an internal ELB. // Currently we accept only the value "0.0.0.0/0" - other values are an error. // This lets us define more advanced semantics in future. const ServiceAnnotationLoadBalancerInternal = "service.beta.kubernetes.io/aws-load-balancer-internal" -// Annotation used on the service to enable the proxy protocol on an ELB. Right now we only -// accept the value "*" which means enable the proxy protocol on all ELB backends. In the -// future we could adjust this to allow setting the proxy protocol only on certain backends. +// ServiceAnnotationLoadBalancerProxyProtocol is the annotation used on the +// service to enable the proxy protocol on an ELB. Right now we only accept the +// value "*" which means enable the proxy protocol on all ELB backends. In the +// future we could adjust this to allow setting the proxy protocol only on +// certain backends. const ServiceAnnotationLoadBalancerProxyProtocol = "service.beta.kubernetes.io/aws-load-balancer-proxy-protocol" -// Service annotation requesting a secure listener. Value is a valid certificate ARN. +// ServiceAnnotationLoadBalancerCertificate is the annotation used on the +// service to request a secure listener. Value is a valid certificate ARN. // For more, see http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html // CertARN is an IAM or CM certificate ARN, e.g. arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 const ServiceAnnotationLoadBalancerCertificate = "service.beta.kubernetes.io/aws-load-balancer-ssl-cert" -// Service annotation specifying a comma-separated list of ports that will use SSL/HTTPS +// ServiceAnnotationLoadBalancerSSLPorts is the annotation used on the service +// to specify a comma-separated list of ports that will use SSL/HTTPS // listeners. Defaults to '*' (all). const ServiceAnnotationLoadBalancerSSLPorts = "service.beta.kubernetes.io/aws-load-balancer-ssl-ports" -// Service annotation specifying the protocol spoken by the backend (pod) behind a secure listener. +// ServiceAnnotationLoadBalancerBEProtocol is the annotation used on the service +// to specify the protocol spoken by the backend (pod) behind a secure listener. // Only inspected when `aws-load-balancer-ssl-cert` is used. -// If `http` (default) or `https`, an HTTPS listener that terminates the connection and parses headers is created. +// If `http` (default) or `https`, an HTTPS listener that terminates the +// connection and parses headers is created. // If set to `ssl` or `tcp`, a "raw" SSL listener is used. const ServiceAnnotationLoadBalancerBEProtocol = "service.beta.kubernetes.io/aws-load-balancer-backend-protocol" @@ -98,36 +110,36 @@ var backendProtocolMapping = map[string]string{ "tcp": "ssl", } -// We sometimes read to see if something exists; then try to create it if we didn't find it +// MaxReadThenCreateRetries sets the maximum number of attempts we will make when +// we read to see if something exists and then try to create it if we didn't find it. // This can fail once in a consistent system if done in parallel // In an eventually consistent system, it could fail unboundedly -// MaxReadThenCreateRetries sets the maximum number of attempts we will make const MaxReadThenCreateRetries = 30 -// Default volume type for newly created Volumes +// DefaultVolumeType specifies which storage to use for newly created Volumes // TODO: Remove when user/admin can configure volume types and thus we don't // need hardcoded defaults. const DefaultVolumeType = "gp2" -// Amazon recommends having no more that 40 volumes attached to an instance, -// and at least one of those is for the system root volume. +// DefaultMaxEBSVolumes is the limit for volumes attached to an instance. +// Amazon recommends no more than 40; the system root volume uses at least one. // See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html#linux-specific-volume-limits const DefaultMaxEBSVolumes = 39 // Used to call aws_credentials.Init() just once var once sync.Once -// Abstraction over AWS, to allow mocking/other implementations -type AWSServices interface { +// Services is an abstraction over AWS, to allow mocking/other implementations +type Services interface { Compute(region string) (EC2, error) LoadBalancing(region string) (ELB, error) Autoscaling(region string) (ASG, error) Metadata() (EC2Metadata, error) } -// TODO: Should we rename this to AWS (EBS & ELB are not technically part of EC2) -// Abstraction over EC2, to allow mocking/other implementations +// EC2 is an abstraction over AWS', to allow mocking/other implementations // Note that the DescribeX functions return a list, so callers don't need to deal with paging +// TODO: Should we rename this to AWS (EBS & ELB are not technically part of EC2) type EC2 interface { // Query EC2 for instances matching the filter DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) @@ -162,7 +174,7 @@ type EC2 interface { ModifyInstanceAttribute(request *ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) } -// This is a simple pass-through of the ELB client interface, which allows for testing +// ELB is a simple pass-through of AWS' ELB client interface, which allows for testing type ELB interface { CreateLoadBalancer(*elb.CreateLoadBalancerInput) (*elb.CreateLoadBalancerOutput, error) DeleteLoadBalancer(*elb.DeleteLoadBalancerInput) (*elb.DeleteLoadBalancerOutput, error) @@ -183,18 +195,20 @@ type ELB interface { ConfigureHealthCheck(*elb.ConfigureHealthCheckInput) (*elb.ConfigureHealthCheckOutput, error) } -// This is a simple pass-through of the Autoscaling client interface, which allows for testing +// ASG 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 +// EC2Metadata is an abstraction over the AWS metadata service. type EC2Metadata interface { // Query the EC2 metadata service (used to discover instance-id etc) GetMetadata(path string) (string, error) } +// VolumeOptions specifies capacity and tags for a volume. type VolumeOptions struct { CapacityGB int Tags map[string]string @@ -246,13 +260,13 @@ type InstanceGroupInfo interface { CurrentSize() (int, error) } -// AWSCloud is an implementation of Interface, LoadBalancer and Instances for Amazon Web Services. -type AWSCloud struct { +// Cloud is an implementation of Interface, LoadBalancer and Instances for Amazon Web Services. +type Cloud struct { ec2 EC2 elb ELB asg ASG metadata EC2Metadata - cfg *AWSCloudConfig + cfg *CloudConfig region string vpcID string @@ -267,9 +281,10 @@ type AWSCloud struct { lastInstancesByNodeNames []*ec2.Instance } -var _ Volumes = &AWSCloud{} +var _ Volumes = &Cloud{} -type AWSCloudConfig struct { +// CloudConfig wraps the settings for the AWS cloud provider. +type CloudConfig struct { Global struct { // TODO: Is there any use for this? We can get it from the instance metadata service // Maybe if we're not running on AWS, e.g. bootstrap; for now it is not very useful @@ -421,22 +436,24 @@ func newEc2Filter(name string, value string) *ec2.Filter { return filter } -func (self *AWSCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { +// AddSSHKeyToAllInstances is currently not implemented. +func (c *Cloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } -func (c *AWSCloud) CurrentNodeName(hostname string) (string, error) { +// CurrentNodeName returns the name of the current node +func (c *Cloud) CurrentNodeName(hostname string) (string, error) { return c.selfAWSInstance.nodeName, nil } // Implementation of EC2.Instances -func (self *awsSdkEC2) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { +func (s *awsSdkEC2) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { // Instances are paged results := []*ec2.Instance{} var nextToken *string for { - response, err := self.ec2.DescribeInstances(request) + response, err := s.ec2.DescribeInstances(request) if err != nil { return nil, fmt.Errorf("error listing AWS instances: %v", err) } @@ -571,8 +588,8 @@ func init() { } // readAWSCloudConfig reads an instance of AWSCloudConfig from config reader. -func readAWSCloudConfig(config io.Reader, metadata EC2Metadata) (*AWSCloudConfig, error) { - var cfg AWSCloudConfig +func readAWSCloudConfig(config io.Reader, metadata EC2Metadata) (*CloudConfig, error) { + var cfg CloudConfig var err error if config != nil { @@ -627,7 +644,7 @@ func azToRegion(az string) (string, error) { // newAWSCloud creates a new instance of AWSCloud. // AWSProvider and instanceId are primarily for tests -func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) { +func newAWSCloud(config io.Reader, awsServices Services) (*Cloud, error) { metadata, err := awsServices.Metadata() if err != nil { return nil, fmt.Errorf("error creating AWS metadata client: %v", err) @@ -667,7 +684,7 @@ func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) { return nil, fmt.Errorf("error creating AWS autoscaling client: %v", err) } - awsCloud := &AWSCloud{ + awsCloud := &Cloud{ ec2: ec2, elb: elb, asg: asg, @@ -719,42 +736,43 @@ func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) { return awsCloud, nil } -func (aws *AWSCloud) Clusters() (cloudprovider.Clusters, bool) { +// Clusters returns the list of clusters. +func (c *Cloud) Clusters() (cloudprovider.Clusters, bool) { return nil, false } // ProviderName returns the cloud provider ID. -func (aws *AWSCloud) ProviderName() string { +func (c *Cloud) ProviderName() string { return ProviderName } // ScrubDNS filters DNS settings for pods. -func (aws *AWSCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) { +func (c *Cloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) { return nameservers, searches } // LoadBalancer returns an implementation of LoadBalancer for Amazon Web Services. -func (s *AWSCloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) { - return s, true +func (c *Cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) { + return c, true } // Instances returns an implementation of Instances for Amazon Web Services. -func (aws *AWSCloud) Instances() (cloudprovider.Instances, bool) { - return aws, true +func (c *Cloud) Instances() (cloudprovider.Instances, bool) { + return c, true } // Zones returns an implementation of Zones for Amazon Web Services. -func (aws *AWSCloud) Zones() (cloudprovider.Zones, bool) { - return aws, true +func (c *Cloud) Zones() (cloudprovider.Zones, bool) { + return c, true } // Routes returns an implementation of Routes for Amazon Web Services. -func (aws *AWSCloud) Routes() (cloudprovider.Routes, bool) { - return aws, true +func (c *Cloud) Routes() (cloudprovider.Routes, bool) { + return c, true } // NodeAddresses is an implementation of Instances.NodeAddresses. -func (c *AWSCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { +func (c *Cloud) NodeAddresses(name string) ([]api.NodeAddress, error) { if c.selfAWSInstance.nodeName == name || len(name) == 0 { addresses := []api.NodeAddress{} @@ -810,61 +828,58 @@ func (c *AWSCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { } // ExternalID returns the cloud provider ID of the specified instance (deprecated). -func (c *AWSCloud) ExternalID(name string) (string, error) { +func (c *Cloud) ExternalID(name string) (string, error) { if c.selfAWSInstance.nodeName == name { // We assume that if this is run on the instance itself, the instance exists and is alive return c.selfAWSInstance.awsID, nil - } else { - // We must verify that the instance still exists - // Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound) - instance, err := c.findInstanceByNodeName(name) - if err != nil { - return "", err - } - if instance == nil { - return "", cloudprovider.InstanceNotFound - } - return orEmpty(instance.InstanceId), nil } + // We must verify that the instance still exists + // Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound) + instance, err := c.findInstanceByNodeName(name) + if err != nil { + return "", err + } + if instance == nil { + return "", cloudprovider.InstanceNotFound + } + return orEmpty(instance.InstanceId), nil } // InstanceID returns the cloud provider ID of the specified instance. -func (c *AWSCloud) InstanceID(name string) (string, error) { +func (c *Cloud) InstanceID(name string) (string, error) { // In the future it is possible to also return an endpoint as: // // if c.selfAWSInstance.nodeName == name { return "/" + c.selfAWSInstance.availabilityZone + "/" + c.selfAWSInstance.awsID, nil - } else { - inst, err := c.getInstanceByNodeName(name) - if err != nil { - return "", err - } - return "/" + orEmpty(inst.Placement.AvailabilityZone) + "/" + orEmpty(inst.InstanceId), nil } + inst, err := c.getInstanceByNodeName(name) + if err != nil { + return "", err + } + return "/" + orEmpty(inst.Placement.AvailabilityZone) + "/" + orEmpty(inst.InstanceId), nil } // InstanceType returns the type of the specified instance. -func (c *AWSCloud) InstanceType(name string) (string, error) { +func (c *Cloud) InstanceType(name string) (string, error) { if c.selfAWSInstance.nodeName == name { return c.selfAWSInstance.instanceType, nil - } else { - inst, err := c.getInstanceByNodeName(name) - if err != nil { - return "", err - } - return orEmpty(inst.InstanceType), nil } + inst, err := c.getInstanceByNodeName(name) + if err != nil { + return "", err + } + return orEmpty(inst.InstanceType), nil } // Return a list of instances matching regex string. -func (s *AWSCloud) getInstancesByRegex(regex string) ([]string, error) { +func (c *Cloud) getInstancesByRegex(regex string) ([]string, error) { filters := []*ec2.Filter{newEc2Filter("instance-state-name", "running")} - filters = s.addFilters(filters) + filters = c.addFilters(filters) request := &ec2.DescribeInstancesInput{ Filters: filters, } - instances, err := s.ec2.DescribeInstances(request) + instances, err := c.ec2.DescribeInstances(request) if err != nil { return []string{}, err } @@ -910,14 +925,14 @@ func (s *AWSCloud) getInstancesByRegex(regex string) ([]string, error) { } // List is an implementation of Instances.List. -func (aws *AWSCloud) List(filter string) ([]string, error) { +func (c *Cloud) List(filter string) ([]string, error) { // TODO: Should really use tag query. No need to go regexp. - return aws.getInstancesByRegex(filter) + return c.getInstancesByRegex(filter) } // getAllZones retrieves a list of all the zones in which nodes are running // It currently involves querying all instances -func (c *AWSCloud) getAllZones() (sets.String, error) { +func (c *Cloud) getAllZones() (sets.String, error) { // We don't currently cache this; it is currently used only in volume // creation which is expected to be a comparatively rare occurence. @@ -959,7 +974,7 @@ func (c *AWSCloud) getAllZones() (sets.String, error) { } // GetZone implements Zones.GetZone -func (c *AWSCloud) GetZone() (cloudprovider.Zone, error) { +func (c *Cloud) GetZone() (cloudprovider.Zone, error) { return cloudprovider.Zone{ FailureDomain: c.selfAWSInstance.availabilityZone, Region: c.region, @@ -1026,28 +1041,28 @@ func newAWSInstance(ec2Service EC2, instance *ec2.Instance) *awsInstance { } // Gets the awsInstanceType that models the instance type of this instance -func (self *awsInstance) getInstanceType() *awsInstanceType { +func (i *awsInstance) getInstanceType() *awsInstanceType { // TODO: Make this real awsInstanceType := &awsInstanceType{} return awsInstanceType } // Gets the full information about this instance from the EC2 API -func (self *awsInstance) describeInstance() (*ec2.Instance, error) { - instanceID := self.awsID +func (i *awsInstance) describeInstance() (*ec2.Instance, error) { + instanceID := i.awsID request := &ec2.DescribeInstancesInput{ InstanceIds: []*string{&instanceID}, } - instances, err := self.ec2.DescribeInstances(request) + instances, err := i.ec2.DescribeInstances(request) if err != nil { return nil, err } if len(instances) == 0 { - return nil, fmt.Errorf("no instances found for instance: %s", self.awsID) + return nil, fmt.Errorf("no instances found for instance: %s", i.awsID) } if len(instances) > 1 { - return nil, fmt.Errorf("multiple instances found for instance: %s", self.awsID) + return nil, fmt.Errorf("multiple instances found for instance: %s", i.awsID) } return instances[0], nil } @@ -1055,19 +1070,19 @@ func (self *awsInstance) describeInstance() (*ec2.Instance, error) { // Gets the mountDevice already assigned to the volume, or assigns an unused mountDevice. // If the volume is already assigned, this will return the existing mountDevice with alreadyAttached=true. // Otherwise the mountDevice is assigned by finding the first available mountDevice, and it is returned with alreadyAttached=false. -func (self *awsInstance) getMountDevice(volumeID string, assign bool) (assigned mountDevice, alreadyAttached bool, err error) { - instanceType := self.getInstanceType() +func (i *awsInstance) getMountDevice(volumeID string, assign bool) (assigned mountDevice, alreadyAttached bool, err error) { + instanceType := i.getInstanceType() if instanceType == nil { - return "", false, fmt.Errorf("could not get instance type for instance: %s", self.awsID) + return "", false, fmt.Errorf("could not get instance type for instance: %s", i.awsID) } // We lock to prevent concurrent mounts from conflicting // We may still conflict if someone calls the API concurrently, // but the AWS API will then fail one of the two attach operations - self.mutex.Lock() - defer self.mutex.Unlock() + i.mutex.Lock() + defer i.mutex.Unlock() - info, err := self.describeInstance() + info, err := i.describeInstance() if err != nil { return "", false, err } @@ -1086,7 +1101,7 @@ func (self *awsInstance) getMountDevice(volumeID string, assign bool) (assigned deviceMappings[mountDevice(name)] = aws.StringValue(blockDevice.Ebs.VolumeId) } - for mountDevice, volume := range self.attaching { + for mountDevice, volume := range i.attaching { deviceMappings[mountDevice] = volume } @@ -1118,20 +1133,20 @@ func (self *awsInstance) getMountDevice(volumeID string, assign bool) (assigned if chosen == "" { glog.Warningf("Could not assign a mount device (all in use?). mappings=%v", deviceMappings) - return "", false, fmt.Errorf("Too many EBS volumes attached to node %s.", self.nodeName) + return "", false, fmt.Errorf("Too many EBS volumes attached to node %s.", i.nodeName) } - self.attaching[chosen] = volumeID + i.attaching[chosen] = volumeID glog.V(2).Infof("Assigned mount device %s -> volume %s", chosen, volumeID) return chosen, false, nil } -func (self *awsInstance) endAttaching(volumeID string, mountDevice mountDevice) { - self.mutex.Lock() - defer self.mutex.Unlock() +func (i *awsInstance) endAttaching(volumeID string, mountDevice mountDevice) { + i.mutex.Lock() + defer i.mutex.Unlock() - existingVolumeID, found := self.attaching[mountDevice] + existingVolumeID, found := i.attaching[mountDevice] if !found { glog.Errorf("endAttaching on non-allocated device") return @@ -1141,7 +1156,7 @@ func (self *awsInstance) endAttaching(volumeID string, mountDevice mountDevice) return } glog.V(2).Infof("Releasing mount device mapping: %s -> volume %s", mountDevice, volumeID) - delete(self.attaching, mountDevice) + delete(i.attaching, mountDevice) } type awsDisk struct { @@ -1153,7 +1168,7 @@ type awsDisk struct { awsID string } -func newAWSDisk(aws *AWSCloud, name string) (*awsDisk, error) { +func newAWSDisk(aws *Cloud, name string) (*awsDisk, error) { // name looks like aws://availability-zone/id // The original idea of the URL-style name was to put the AZ into the @@ -1191,35 +1206,35 @@ func newAWSDisk(aws *AWSCloud, name string) (*awsDisk, error) { } // Gets the full information about this volume from the EC2 API -func (self *awsDisk) describeVolume() (*ec2.Volume, error) { - volumeID := self.awsID +func (d *awsDisk) describeVolume() (*ec2.Volume, error) { + volumeID := d.awsID request := &ec2.DescribeVolumesInput{ VolumeIds: []*string{&volumeID}, } - volumes, err := self.ec2.DescribeVolumes(request) + volumes, err := d.ec2.DescribeVolumes(request) if err != nil { return nil, fmt.Errorf("error querying ec2 for volume info: %v", err) } if len(volumes) == 0 { - return nil, fmt.Errorf("no volumes found for volume: %s", self.awsID) + return nil, fmt.Errorf("no volumes found for volume: %s", d.awsID) } if len(volumes) > 1 { - return nil, fmt.Errorf("multiple volumes found for volume: %s", self.awsID) + return nil, fmt.Errorf("multiple volumes found for volume: %s", d.awsID) } return volumes[0], nil } // waitForAttachmentStatus polls until the attachment status is the expected value // TODO(justinsb): return (bool, error) -func (self *awsDisk) waitForAttachmentStatus(status string) error { +func (d *awsDisk) waitForAttachmentStatus(status string) error { // TODO: There may be a faster way to get this when we're attaching locally attempt := 0 maxAttempts := 60 for { - info, err := self.describeVolume() + info, err := d.describeVolume() if err != nil { return err } @@ -1258,9 +1273,9 @@ func (self *awsDisk) waitForAttachmentStatus(status string) error { } // Deletes the EBS disk -func (self *awsDisk) deleteVolume() (bool, error) { - request := &ec2.DeleteVolumeInput{VolumeId: aws.String(self.awsID)} - _, err := self.ec2.DeleteVolume(request) +func (d *awsDisk) deleteVolume() (bool, error) { + request := &ec2.DeleteVolumeInput{VolumeId: aws.String(d.awsID)} + _, err := d.ec2.DeleteVolume(request) if err != nil { if awsError, ok := err.(awserr.Error); ok { if awsError.Code() == "InvalidVolume.NotFound" { @@ -1274,11 +1289,11 @@ func (self *awsDisk) deleteVolume() (bool, error) { // Builds the awsInstance for the EC2 instance on which we are running. // This is called when the AWSCloud is initialized, and should not be called otherwise (because the awsInstance for the local instance is a singleton with drive mapping state) -func (c *AWSCloud) buildSelfAWSInstance() (*awsInstance, error) { +func (c *Cloud) buildSelfAWSInstance() (*awsInstance, error) { if c.selfAWSInstance != nil { panic("do not call buildSelfAWSInstance directly") } - instanceId, err := c.metadata.GetMetadata("instance-id") + instanceID, err := c.metadata.GetMetadata("instance-id") if err != nil { return nil, fmt.Errorf("error fetching instance-id from ec2 metadata service: %v", err) } @@ -1291,15 +1306,15 @@ func (c *AWSCloud) buildSelfAWSInstance() (*awsInstance, error) { // information from the instance returned by the EC2 API - it is a // single API call to get all the information, and it means we don't // have two code paths. - instance, err := c.getInstanceByID(instanceId) + instance, err := c.getInstanceByID(instanceID) if err != nil { - return nil, fmt.Errorf("error finding instance %s: %v", instanceId, err) + return nil, fmt.Errorf("error finding instance %s: %v", instanceID, err) } return newAWSInstance(c.ec2, instance), nil } // Gets the awsInstance with node-name nodeName, or the 'self' instance if nodeName == "" -func (c *AWSCloud) getAwsInstance(nodeName string) (*awsInstance, error) { +func (c *Cloud) getAwsInstance(nodeName string) (*awsInstance, error) { var awsInstance *awsInstance if nodeName == "" { awsInstance = c.selfAWSInstance @@ -1315,8 +1330,8 @@ func (c *AWSCloud) getAwsInstance(nodeName string) (*awsInstance, error) { return awsInstance, nil } -// Implements Volumes.AttachDisk -func (c *AWSCloud) AttachDisk(diskName string, instanceName string, readOnly bool) (string, error) { +// AttachDisk implements Volumes.AttachDisk +func (c *Cloud) AttachDisk(diskName string, instanceName string, readOnly bool) (string, error) { disk, err := newAWSDisk(c, diskName) if err != nil { return "", err @@ -1380,14 +1395,14 @@ func (c *AWSCloud) AttachDisk(diskName string, instanceName string, readOnly boo return hostDevice, nil } -// Implements Volumes.DetachDisk -func (aws *AWSCloud) DetachDisk(diskName string, instanceName string) (string, error) { - disk, err := newAWSDisk(aws, diskName) +// DetachDisk implements Volumes.DetachDisk +func (c *Cloud) DetachDisk(diskName string, instanceName string) (string, error) { + disk, err := newAWSDisk(c, diskName) if err != nil { return "", err } - awsInstance, err := aws.getAwsInstance(instanceName) + awsInstance, err := c.getAwsInstance(instanceName) if err != nil { return "", err } @@ -1407,7 +1422,7 @@ func (aws *AWSCloud) DetachDisk(diskName string, instanceName string) (string, e VolumeId: &disk.awsID, } - response, err := aws.ec2.DetachVolume(&request) + response, err := c.ec2.DetachVolume(&request) if err != nil { return "", fmt.Errorf("error detaching EBS volume: %v", err) } @@ -1429,8 +1444,8 @@ func (aws *AWSCloud) DetachDisk(diskName string, instanceName string) (string, e } // CreateDisk implements Volumes.CreateDisk -func (s *AWSCloud) CreateDisk(volumeOptions *VolumeOptions) (string, error) { - allZones, err := s.getAllZones() +func (c *Cloud) CreateDisk(volumeOptions *VolumeOptions) (string, error) { + allZones, err := c.getAllZones() if err != nil { return "", fmt.Errorf("error querying for all zones: %v", err) } @@ -1443,7 +1458,7 @@ func (s *AWSCloud) CreateDisk(volumeOptions *VolumeOptions) (string, error) { volSize := int64(volumeOptions.CapacityGB) request.Size = &volSize request.VolumeType = aws.String(DefaultVolumeType) - response, err := s.ec2.CreateVolume(request) + response, err := c.ec2.CreateVolume(request) if err != nil { return "", err } @@ -1459,14 +1474,14 @@ func (s *AWSCloud) CreateDisk(volumeOptions *VolumeOptions) (string, error) { tags[k] = v } - if s.getClusterName() != "" { - tags[TagNameKubernetesCluster] = s.getClusterName() + if c.getClusterName() != "" { + tags[TagNameKubernetesCluster] = c.getClusterName() } if len(tags) != 0 { - if err := s.createTags(awsID, tags); err != nil { + if err := c.createTags(awsID, tags); err != nil { // delete the volume and hope it succeeds - _, delerr := s.DeleteDisk(volumeName) + _, delerr := c.DeleteDisk(volumeName) if delerr != nil { // delete did not succeed, we have a stray volume! return "", fmt.Errorf("error tagging volume %s, could not delete the volume: %v", volumeName, delerr) @@ -1477,8 +1492,8 @@ func (s *AWSCloud) CreateDisk(volumeOptions *VolumeOptions) (string, error) { return volumeName, nil } -// Implements Volumes.DeleteDisk -func (c *AWSCloud) DeleteDisk(volumeName string) (bool, error) { +// DeleteDisk implements Volumes.DeleteDisk +func (c *Cloud) DeleteDisk(volumeName string) (bool, error) { awsDisk, err := newAWSDisk(c, volumeName) if err != nil { return false, err @@ -1486,8 +1501,8 @@ func (c *AWSCloud) DeleteDisk(volumeName string) (bool, error) { return awsDisk.deleteVolume() } -// Implements Volumes.GetVolumeLabels -func (c *AWSCloud) GetVolumeLabels(volumeName string) (map[string]string, error) { +// GetVolumeLabels implements Volumes.GetVolumeLabels +func (c *Cloud) GetVolumeLabels(volumeName string) (map[string]string, error) { awsDisk, err := newAWSDisk(c, volumeName) if err != nil { return nil, err @@ -1512,8 +1527,8 @@ func (c *AWSCloud) GetVolumeLabels(volumeName string) (map[string]string, error) return labels, nil } -// Implement Volumes.GetDiskPath -func (c *AWSCloud) GetDiskPath(volumeName string) (string, error) { +// GetDiskPath implements Volumes.GetDiskPath +func (c *Cloud) GetDiskPath(volumeName string) (string, error) { awsDisk, err := newAWSDisk(c, volumeName) if err != nil { return "", err @@ -1528,8 +1543,8 @@ func (c *AWSCloud) GetDiskPath(volumeName string) (string, error) { return aws.StringValue(info.Attachments[0].Device), nil } -// Implement Volumes.DiskIsAttached -func (c *AWSCloud) DiskIsAttached(diskName, instanceID string) (bool, error) { +// DiskIsAttached implements Volumes.DiskIsAttached +func (c *Cloud) DiskIsAttached(diskName, instanceID string) (bool, error) { awsInstance, err := c.getAwsInstance(instanceID) if err != nil { return false, err @@ -1549,11 +1564,11 @@ func (c *AWSCloud) DiskIsAttached(diskName, instanceID string) (bool, error) { } // Gets the current load balancer state -func (s *AWSCloud) describeLoadBalancer(name string) (*elb.LoadBalancerDescription, error) { +func (c *Cloud) describeLoadBalancer(name string) (*elb.LoadBalancerDescription, error) { request := &elb.DescribeLoadBalancersInput{} request.LoadBalancerNames = []*string{&name} - response, err := s.elb.DescribeLoadBalancers(request) + response, err := c.elb.DescribeLoadBalancers(request) if err != nil { if awsError, ok := err.(awserr.Error); ok { if awsError.Code() == "LoadBalancerNotFound" { @@ -1574,8 +1589,8 @@ func (s *AWSCloud) describeLoadBalancer(name string) (*elb.LoadBalancerDescripti } // Retrieves instance's vpc id from metadata -func (self *AWSCloud) findVPCID() (string, error) { - macs, err := self.metadata.GetMetadata("network/interfaces/macs/") +func (c *Cloud) findVPCID() (string, error) { + macs, err := c.metadata.GetMetadata("network/interfaces/macs/") if err != nil { return "", fmt.Errorf("Could not list interfaces of the instance: %v", err) } @@ -1586,7 +1601,7 @@ func (self *AWSCloud) findVPCID() (string, error) { continue } url := fmt.Sprintf("network/interfaces/macs/%svpc-id", macPath) - vpcID, err := self.metadata.GetMetadata(url) + vpcID, err := c.metadata.GetMetadata(url) if err != nil { continue } @@ -1596,13 +1611,13 @@ func (self *AWSCloud) findVPCID() (string, error) { } // Retrieves the specified security group from the AWS API, or returns nil if not found -func (s *AWSCloud) findSecurityGroup(securityGroupId string) (*ec2.SecurityGroup, error) { +func (c *Cloud) findSecurityGroup(securityGroupID string) (*ec2.SecurityGroup, error) { describeSecurityGroupsRequest := &ec2.DescribeSecurityGroupsInput{ - GroupIds: []*string{&securityGroupId}, + GroupIds: []*string{&securityGroupID}, } // We don't apply our tag filters because we are retrieving by ID - groups, err := s.ec2.DescribeSecurityGroups(describeSecurityGroupsRequest) + groups, err := c.ec2.DescribeSecurityGroups(describeSecurityGroupsRequest) if err != nil { glog.Warningf("Error retrieving security group: %q", err) return nil, err @@ -1613,7 +1628,7 @@ func (s *AWSCloud) findSecurityGroup(securityGroupId string) (*ec2.SecurityGroup } if len(groups) != 1 { // This should not be possible - ids should be unique - return nil, fmt.Errorf("multiple security groups found with same id %q", securityGroupId) + return nil, fmt.Errorf("multiple security groups found with same id %q", securityGroupID) } group := groups[0] return group, nil @@ -1698,18 +1713,18 @@ func isEqualUserGroupPair(l, r *ec2.UserIdGroupPair, compareGroupUserIDs bool) b // Makes sure the security group ingress is exactly the specified permissions // Returns true if and only if changes were made // The security group must already exist -func (s *AWSCloud) setSecurityGroupIngress(securityGroupId string, permissions IPPermissionSet) (bool, error) { - group, err := s.findSecurityGroup(securityGroupId) +func (c *Cloud) setSecurityGroupIngress(securityGroupID string, permissions IPPermissionSet) (bool, error) { + group, err := c.findSecurityGroup(securityGroupID) if err != nil { glog.Warning("Error retrieving security group", err) return false, err } if group == nil { - return false, fmt.Errorf("security group not found: %s", securityGroupId) + return false, fmt.Errorf("security group not found: %s", securityGroupID) } - glog.V(2).Infof("Existing security group ingress: %s %v", securityGroupId, group.IpPermissions) + glog.V(2).Infof("Existing security group ingress: %s %v", securityGroupID, group.IpPermissions) actual := NewIPPermissionSet(group.IpPermissions...) @@ -1740,23 +1755,23 @@ func (s *AWSCloud) setSecurityGroupIngress(securityGroupId string, permissions I // don't want to accidentally open more than intended while we're // applying changes. if add.Len() != 0 { - glog.V(2).Infof("Adding security group ingress: %s %v", securityGroupId, add.List()) + glog.V(2).Infof("Adding security group ingress: %s %v", securityGroupID, add.List()) request := &ec2.AuthorizeSecurityGroupIngressInput{} - request.GroupId = &securityGroupId + request.GroupId = &securityGroupID request.IpPermissions = add.List() - _, err = s.ec2.AuthorizeSecurityGroupIngress(request) + _, err = c.ec2.AuthorizeSecurityGroupIngress(request) if err != nil { return false, fmt.Errorf("error authorizing security group ingress: %v", err) } } if remove.Len() != 0 { - glog.V(2).Infof("Remove security group ingress: %s %v", securityGroupId, remove.List()) + glog.V(2).Infof("Remove security group ingress: %s %v", securityGroupID, remove.List()) request := &ec2.RevokeSecurityGroupIngressInput{} - request.GroupId = &securityGroupId + request.GroupId = &securityGroupID request.IpPermissions = remove.List() - _, err = s.ec2.RevokeSecurityGroupIngress(request) + _, err = c.ec2.RevokeSecurityGroupIngress(request) if err != nil { return false, fmt.Errorf("error revoking security group ingress: %v", err) } @@ -1768,18 +1783,18 @@ func (s *AWSCloud) setSecurityGroupIngress(securityGroupId string, permissions I // Makes sure the security group includes the specified permissions // Returns true if and only if changes were made // The security group must already exist -func (s *AWSCloud) addSecurityGroupIngress(securityGroupId string, addPermissions []*ec2.IpPermission) (bool, error) { - group, err := s.findSecurityGroup(securityGroupId) +func (c *Cloud) addSecurityGroupIngress(securityGroupID string, addPermissions []*ec2.IpPermission) (bool, error) { + group, err := c.findSecurityGroup(securityGroupID) if err != nil { glog.Warningf("Error retrieving security group: %v", err) return false, err } if group == nil { - return false, fmt.Errorf("security group not found: %s", securityGroupId) + return false, fmt.Errorf("security group not found: %s", securityGroupID) } - glog.V(2).Infof("Existing security group ingress: %s %v", securityGroupId, group.IpPermissions) + glog.V(2).Infof("Existing security group ingress: %s %v", securityGroupID, group.IpPermissions) changes := []*ec2.IpPermission{} for _, addPermission := range addPermissions { @@ -1807,12 +1822,12 @@ func (s *AWSCloud) addSecurityGroupIngress(securityGroupId string, addPermission return false, nil } - glog.V(2).Infof("Adding security group ingress: %s %v", securityGroupId, changes) + glog.V(2).Infof("Adding security group ingress: %s %v", securityGroupID, changes) request := &ec2.AuthorizeSecurityGroupIngressInput{} - request.GroupId = &securityGroupId + request.GroupId = &securityGroupID request.IpPermissions = changes - _, err = s.ec2.AuthorizeSecurityGroupIngress(request) + _, err = c.ec2.AuthorizeSecurityGroupIngress(request) if err != nil { glog.Warning("Error authorizing security group ingress", err) return false, fmt.Errorf("error authorizing security group ingress: %v", err) @@ -1824,15 +1839,15 @@ func (s *AWSCloud) addSecurityGroupIngress(securityGroupId string, addPermission // Makes sure the security group no longer includes the specified permissions // Returns true if and only if changes were made // If the security group no longer exists, will return (false, nil) -func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePermissions []*ec2.IpPermission) (bool, error) { - group, err := s.findSecurityGroup(securityGroupId) +func (c *Cloud) removeSecurityGroupIngress(securityGroupID string, removePermissions []*ec2.IpPermission) (bool, error) { + group, err := c.findSecurityGroup(securityGroupID) if err != nil { glog.Warningf("Error retrieving security group: %v", err) return false, err } if group == nil { - glog.Warning("Security group not found: ", securityGroupId) + glog.Warning("Security group not found: ", securityGroupID) return false, nil } @@ -1862,12 +1877,12 @@ func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePerm return false, nil } - glog.V(2).Infof("Removing security group ingress: %s %v", securityGroupId, changes) + glog.V(2).Infof("Removing security group ingress: %s %v", securityGroupID, changes) request := &ec2.RevokeSecurityGroupIngressInput{} - request.GroupId = &securityGroupId + request.GroupId = &securityGroupID request.IpPermissions = changes - _, err = s.ec2.RevokeSecurityGroupIngress(request) + _, err = c.ec2.RevokeSecurityGroupIngress(request) if err != nil { glog.Warningf("Error revoking security group ingress: %v", err) return false, err @@ -1879,14 +1894,14 @@ func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePerm // Ensure that a resource has the correct tags // If it has no tags, we assume that this was a problem caused by an error in between creation and tagging, // and we add the tags. If it has a different cluster's tags, that is an error. -func (s *AWSCloud) ensureClusterTags(resourceID string, tags []*ec2.Tag) error { +func (c *Cloud) ensureClusterTags(resourceID string, tags []*ec2.Tag) error { actualTags := make(map[string]string) for _, tag := range tags { actualTags[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value) } addTags := make(map[string]string) - for k, expected := range s.filterTags { + for k, expected := range c.filterTags { actual := actualTags[k] if actual == expected { continue @@ -1899,7 +1914,7 @@ func (s *AWSCloud) ensureClusterTags(resourceID string, tags []*ec2.Tag) error { } } - if err := s.createTags(resourceID, addTags); err != nil { + if err := c.createTags(resourceID, addTags); err != nil { return fmt.Errorf("error adding missing tags to resource %q: %v", resourceID, err) } @@ -1909,7 +1924,7 @@ func (s *AWSCloud) ensureClusterTags(resourceID string, tags []*ec2.Tag) error { // Makes sure the security group exists. // For multi-cluster isolation, name must be globally unique, for example derived from the service UUID. // Returns the security group id or error -func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, error) { +func (c *Cloud) ensureSecurityGroup(name string, description string) (string, error) { groupID := "" attempt := 0 for { @@ -1918,7 +1933,7 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, request := &ec2.DescribeSecurityGroupsInput{} filters := []*ec2.Filter{ newEc2Filter("group-name", name), - newEc2Filter("vpc-id", s.vpcID), + newEc2Filter("vpc-id", c.vpcID), } // Note that we do _not_ add our tag filters; group-name + vpc-id is the EC2 primary key. // However, we do check that it matches our tags. @@ -1927,7 +1942,7 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, // This shouldn't happen because name is expected to be globally unique (UUID derived) request.Filters = filters - securityGroups, err := s.ec2.DescribeSecurityGroups(request) + securityGroups, err := c.ec2.DescribeSecurityGroups(request) if err != nil { return "", err } @@ -1936,7 +1951,7 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, if len(securityGroups) > 1 { glog.Warningf("Found multiple security groups with name: %q", name) } - err := s.ensureClusterTags(aws.StringValue(securityGroups[0].GroupId), securityGroups[0].Tags) + err := c.ensureClusterTags(aws.StringValue(securityGroups[0].GroupId), securityGroups[0].Tags) if err != nil { return "", err } @@ -1945,11 +1960,11 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, } createRequest := &ec2.CreateSecurityGroupInput{} - createRequest.VpcId = &s.vpcID + createRequest.VpcId = &c.vpcID createRequest.GroupName = &name createRequest.Description = &description - createResponse, err := s.ec2.CreateSecurityGroup(createRequest) + createResponse, err := c.ec2.CreateSecurityGroup(createRequest) if err != nil { ignore := false switch err := err.(type) { @@ -1973,7 +1988,7 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, return "", fmt.Errorf("created security group, but id was not returned: %s", name) } - err := s.createTags(groupID, s.filterTags) + err := c.createTags(groupID, c.filterTags) if err != nil { // If we retry, ensureClusterTags will recover from this - it // will add the missing tags. We could delete the security @@ -1987,7 +2002,7 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string) (string, // createTags calls EC2 CreateTags, but adds retry-on-failure logic // We retry mainly because if we create an object, we cannot tag it until it is "fully created" (eventual consistency) // The error code varies though (depending on what we are tagging), so we simply retry on all errors -func (s *AWSCloud) createTags(resourceID string, tags map[string]string) error { +func (c *Cloud) createTags(resourceID string, tags map[string]string) error { if tags == nil || len(tags) == 0 { return nil } @@ -2010,7 +2025,7 @@ func (s *AWSCloud) createTags(resourceID string, tags map[string]string) error { maxAttempts := 60 for { - _, err := s.ec2.CreateTags(request) + _, err := c.ec2.CreateTags(request) if err == nil { return nil } @@ -2040,7 +2055,7 @@ func findTag(tags []*ec2.Tag, key string) (string, bool) { // Finds the subnets associated with the cluster, by matching tags. // For maximal backwards compatibility, if no subnets are tagged, it will fall-back to the current subnet. // However, in future this will likely be treated as an error. -func (c *AWSCloud) findSubnets() ([]*ec2.Subnet, error) { +func (c *Cloud) findSubnets() ([]*ec2.Subnet, error) { request := &ec2.DescribeSubnetsInput{} vpcIDFilter := newEc2Filter("vpc-id", c.vpcID) filters := []*ec2.Filter{vpcIDFilter} @@ -2074,17 +2089,17 @@ func (c *AWSCloud) findSubnets() ([]*ec2.Subnet, error) { // Finds the subnets to use for an ELB we are creating. // Normal (Internet-facing) ELBs must use public subnets, so we skip private subnets. // Internal ELBs can use public or private subnets, but if we have a private subnet we should prefer that. -func (s *AWSCloud) findELBSubnets(internalELB bool) ([]string, error) { - vpcIDFilter := newEc2Filter("vpc-id", s.vpcID) +func (c *Cloud) findELBSubnets(internalELB bool) ([]string, error) { + vpcIDFilter := newEc2Filter("vpc-id", c.vpcID) - subnets, err := s.findSubnets() + subnets, err := c.findSubnets() if err != nil { return nil, err } rRequest := &ec2.DescribeRouteTablesInput{} rRequest.Filters = []*ec2.Filter{vpcIDFilter} - rt, err := s.ec2.DescribeRouteTables(rRequest) + rt, err := c.ec2.DescribeRouteTables(rRequest) if err != nil { return nil, fmt.Errorf("error describe route table: %v", err) } @@ -2249,10 +2264,10 @@ func buildListener(port api.ServicePort, annotations map[string]string, sslPorts } // EnsureLoadBalancer implements LoadBalancer.EnsureLoadBalancer -func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) (*api.LoadBalancerStatus, error) { +func (c *Cloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) (*api.LoadBalancerStatus, error) { annotations := apiService.Annotations glog.V(2).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)", - apiService.Namespace, apiService.Name, s.region, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, hosts, annotations) + apiService.Namespace, apiService.Name, c.region, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, hosts, annotations) if apiService.Spec.SessionAffinity != api.ServiceAffinityNone { // ELB supports sticky sessions, but only when configured for HTTP/HTTPS @@ -2286,7 +2301,7 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( } hostSet := sets.NewString(hosts...) - instances, err := s.getInstancesByNodeNamesCached(hostSet) + instances, err := c.getInstancesByNodeNamesCached(hostSet) if err != nil { return nil, err } @@ -2321,7 +2336,7 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( } // Find the subnets that the ELB will live in - subnetIDs, err := s.findELBSubnets(internalELB) + subnetIDs, err := c.findELBSubnets(internalELB) if err != nil { glog.Error("Error listing subnets in VPC: ", err) return nil, err @@ -2340,7 +2355,7 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( { sgName := "k8s-elb-" + loadBalancerName sgDescription := fmt.Sprintf("Security group for Kubernetes ELB %s (%v)", loadBalancerName, serviceName) - securityGroupID, err = s.ensureSecurityGroup(sgName, sgDescription) + securityGroupID, err = c.ensureSecurityGroup(sgName, sgDescription) if err != nil { glog.Error("Error creating load balancer security group: ", err) return nil, err @@ -2377,7 +2392,7 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( permissions.Insert(permission) } - _, err = s.setSecurityGroupIngress(securityGroupID, permissions) + _, err = c.setSecurityGroupIngress(securityGroupID, permissions) if err != nil { return nil, err } @@ -2385,7 +2400,7 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( securityGroupIDs := []string{securityGroupID} // Build the load balancer itself - loadBalancer, err := s.ensureLoadBalancer( + loadBalancer, err := c.ensureLoadBalancer( serviceName, loadBalancerName, listeners, @@ -2398,18 +2413,18 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( return nil, err } - err = s.ensureLoadBalancerHealthCheck(loadBalancer, listeners) + err = c.ensureLoadBalancerHealthCheck(loadBalancer, listeners) if err != nil { return nil, err } - err = s.updateInstanceSecurityGroupsForLoadBalancer(loadBalancer, instances) + err = c.updateInstanceSecurityGroupsForLoadBalancer(loadBalancer, instances) if err != nil { glog.Warningf("Error opening ingress rules for the load balancer to the instances: %v", err) return nil, err } - err = s.ensureLoadBalancerInstances(orEmpty(loadBalancer.LoadBalancerName), loadBalancer.Instances, instances) + err = c.ensureLoadBalancerInstances(orEmpty(loadBalancer.LoadBalancerName), loadBalancer.Instances, instances) if err != nil { glog.Warningf("Error registering instances with the load balancer: %v", err) return nil, err @@ -2424,9 +2439,9 @@ func (s *AWSCloud) EnsureLoadBalancer(apiService *api.Service, hosts []string) ( } // GetLoadBalancer is an implementation of LoadBalancer.GetLoadBalancer -func (s *AWSCloud) GetLoadBalancer(service *api.Service) (*api.LoadBalancerStatus, bool, error) { +func (c *Cloud) GetLoadBalancer(service *api.Service) (*api.LoadBalancerStatus, bool, error) { loadBalancerName := cloudprovider.GetLoadBalancerName(service) - lb, err := s.describeLoadBalancer(loadBalancerName) + lb, err := c.describeLoadBalancer(loadBalancerName) if err != nil { return nil, false, err } @@ -2496,10 +2511,10 @@ func findSecurityGroupForInstance(instance *ec2.Instance, taggedSecurityGroups m } // Return all the security groups that are tagged as being part of our cluster -func (s *AWSCloud) getTaggedSecurityGroups() (map[string]*ec2.SecurityGroup, error) { +func (c *Cloud) getTaggedSecurityGroups() (map[string]*ec2.SecurityGroup, error) { request := &ec2.DescribeSecurityGroupsInput{} - request.Filters = s.addFilters(nil) - groups, err := s.ec2.DescribeSecurityGroups(request) + request.Filters = c.addFilters(nil) + groups, err := c.ec2.DescribeSecurityGroups(request) if err != nil { return nil, fmt.Errorf("error querying security groups: %v", err) } @@ -2518,38 +2533,38 @@ func (s *AWSCloud) getTaggedSecurityGroups() (map[string]*ec2.SecurityGroup, err // Open security group ingress rules on the instances so that the load balancer can talk to them // Will also remove any security groups ingress rules for the load balancer that are _not_ needed for allInstances -func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, allInstances []*ec2.Instance) error { - if s.cfg.Global.DisableSecurityGroupIngress { +func (c *Cloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, allInstances []*ec2.Instance) error { + if c.cfg.Global.DisableSecurityGroupIngress { return nil } // Determine the load balancer security group id - loadBalancerSecurityGroupId := "" + loadBalancerSecurityGroupID := "" for _, securityGroup := range lb.SecurityGroups { if isNilOrEmpty(securityGroup) { continue } - if loadBalancerSecurityGroupId != "" { + if loadBalancerSecurityGroupID != "" { // We create LBs with one SG glog.Warningf("Multiple security groups for load balancer: %q", orEmpty(lb.LoadBalancerName)) } - loadBalancerSecurityGroupId = *securityGroup + loadBalancerSecurityGroupID = *securityGroup } - if loadBalancerSecurityGroupId == "" { + if loadBalancerSecurityGroupID == "" { return fmt.Errorf("Could not determine security group for load balancer: %s", orEmpty(lb.LoadBalancerName)) } // Get the actual list of groups that allow ingress from the load-balancer describeRequest := &ec2.DescribeSecurityGroupsInput{} filters := []*ec2.Filter{} - filters = append(filters, newEc2Filter("ip-permission.group-id", loadBalancerSecurityGroupId)) - describeRequest.Filters = s.addFilters(filters) - actualGroups, err := s.ec2.DescribeSecurityGroups(describeRequest) + filters = append(filters, newEc2Filter("ip-permission.group-id", loadBalancerSecurityGroupID)) + describeRequest.Filters = c.addFilters(filters) + actualGroups, err := c.ec2.DescribeSecurityGroups(describeRequest) if err != nil { return fmt.Errorf("error querying security groups for ELB: %v", err) } - taggedSecurityGroups, err := s.getTaggedSecurityGroups() + taggedSecurityGroups, err := c.getTaggedSecurityGroups() if err != nil { return fmt.Errorf("error querying for tagged security groups: %v", err) } @@ -2600,38 +2615,38 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan } } - for instanceSecurityGroupId, add := range instanceSecurityGroupIds { + for instanceSecurityGroupID, add := range instanceSecurityGroupIds { if add { - glog.V(2).Infof("Adding rule for traffic from the load balancer (%s) to instances (%s)", loadBalancerSecurityGroupId, instanceSecurityGroupId) + glog.V(2).Infof("Adding rule for traffic from the load balancer (%s) to instances (%s)", loadBalancerSecurityGroupID, instanceSecurityGroupID) } else { - glog.V(2).Infof("Removing rule for traffic from the load balancer (%s) to instance (%s)", loadBalancerSecurityGroupId, instanceSecurityGroupId) + glog.V(2).Infof("Removing rule for traffic from the load balancer (%s) to instance (%s)", loadBalancerSecurityGroupID, instanceSecurityGroupID) } - sourceGroupId := &ec2.UserIdGroupPair{} - sourceGroupId.GroupId = &loadBalancerSecurityGroupId + sourceGroupID := &ec2.UserIdGroupPair{} + sourceGroupID.GroupId = &loadBalancerSecurityGroupID allProtocols := "-1" permission := &ec2.IpPermission{} permission.IpProtocol = &allProtocols - permission.UserIdGroupPairs = []*ec2.UserIdGroupPair{sourceGroupId} + permission.UserIdGroupPairs = []*ec2.UserIdGroupPair{sourceGroupID} permissions := []*ec2.IpPermission{permission} if add { - changed, err := s.addSecurityGroupIngress(instanceSecurityGroupId, permissions) + changed, err := c.addSecurityGroupIngress(instanceSecurityGroupID, permissions) if err != nil { return err } if !changed { - glog.Warning("Allowing ingress was not needed; concurrent change? groupId=", instanceSecurityGroupId) + glog.Warning("Allowing ingress was not needed; concurrent change? groupId=", instanceSecurityGroupID) } } else { - changed, err := s.removeSecurityGroupIngress(instanceSecurityGroupId, permissions) + changed, err := c.removeSecurityGroupIngress(instanceSecurityGroupID, permissions) if err != nil { return err } if !changed { - glog.Warning("Revoking ingress was not needed; concurrent change? groupId=", instanceSecurityGroupId) + glog.Warning("Revoking ingress was not needed; concurrent change? groupId=", instanceSecurityGroupID) } } } @@ -2640,9 +2655,9 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan } // EnsureLoadBalancerDeleted implements LoadBalancer.EnsureLoadBalancerDeleted. -func (s *AWSCloud) EnsureLoadBalancerDeleted(service *api.Service) error { +func (c *Cloud) EnsureLoadBalancerDeleted(service *api.Service) error { loadBalancerName := cloudprovider.GetLoadBalancerName(service) - lb, err := s.describeLoadBalancer(loadBalancerName) + lb, err := c.describeLoadBalancer(loadBalancerName) if err != nil { return err } @@ -2654,7 +2669,7 @@ func (s *AWSCloud) EnsureLoadBalancerDeleted(service *api.Service) error { { // De-authorize the load balancer security group from the instances security group - err = s.updateInstanceSecurityGroupsForLoadBalancer(lb, nil) + err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, nil) if err != nil { glog.Error("Error deregistering load balancer from instance security groups: ", err) return err @@ -2666,7 +2681,7 @@ func (s *AWSCloud) EnsureLoadBalancerDeleted(service *api.Service) error { request := &elb.DeleteLoadBalancerInput{} request.LoadBalancerName = lb.LoadBalancerName - _, err = s.elb.DeleteLoadBalancer(request) + _, err = c.elb.DeleteLoadBalancer(request) if err != nil { // TODO: Check if error was because load balancer was concurrently deleted glog.Error("Error deleting load balancer: ", err) @@ -2695,7 +2710,7 @@ func (s *AWSCloud) EnsureLoadBalancerDeleted(service *api.Service) error { for securityGroupID := range securityGroupIDs { request := &ec2.DeleteSecurityGroupInput{} request.GroupId = &securityGroupID - _, err := s.ec2.DeleteSecurityGroup(request) + _, err := c.ec2.DeleteSecurityGroup(request) if err == nil { delete(securityGroupIDs, securityGroupID) } else { @@ -2736,15 +2751,15 @@ func (s *AWSCloud) EnsureLoadBalancerDeleted(service *api.Service) error { } // UpdateLoadBalancer implements LoadBalancer.UpdateLoadBalancer -func (s *AWSCloud) UpdateLoadBalancer(service *api.Service, hosts []string) error { +func (c *Cloud) UpdateLoadBalancer(service *api.Service, hosts []string) error { hostSet := sets.NewString(hosts...) - instances, err := s.getInstancesByNodeNamesCached(hostSet) + instances, err := c.getInstancesByNodeNamesCached(hostSet) if err != nil { return err } loadBalancerName := cloudprovider.GetLoadBalancerName(service) - lb, err := s.describeLoadBalancer(loadBalancerName) + lb, err := c.describeLoadBalancer(loadBalancerName) if err != nil { return err } @@ -2753,12 +2768,12 @@ func (s *AWSCloud) UpdateLoadBalancer(service *api.Service, hosts []string) erro return fmt.Errorf("Load balancer not found") } - err = s.ensureLoadBalancerInstances(orEmpty(lb.LoadBalancerName), lb.Instances, instances) + err = c.ensureLoadBalancerInstances(orEmpty(lb.LoadBalancerName), lb.Instances, instances) if err != nil { return nil } - err = s.updateInstanceSecurityGroupsForLoadBalancer(lb, instances) + err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, instances) if err != nil { return err } @@ -2767,8 +2782,8 @@ func (s *AWSCloud) UpdateLoadBalancer(service *api.Service, hosts []string) erro } // Returns the instance with the specified ID -func (a *AWSCloud) getInstanceByID(instanceID string) (*ec2.Instance, error) { - instances, err := a.getInstancesByIDs([]*string{&instanceID}) +func (c *Cloud) getInstanceByID(instanceID string) (*ec2.Instance, error) { + instances, err := c.getInstancesByIDs([]*string{&instanceID}) if err != nil { return nil, err } @@ -2783,7 +2798,7 @@ func (a *AWSCloud) getInstanceByID(instanceID string) (*ec2.Instance, error) { return instances[instanceID], nil } -func (a *AWSCloud) getInstancesByIDs(instanceIDs []*string) (map[string]*ec2.Instance, error) { +func (c *Cloud) getInstancesByIDs(instanceIDs []*string) (map[string]*ec2.Instance, error) { instancesByID := make(map[string]*ec2.Instance) if len(instanceIDs) == 0 { return instancesByID, nil @@ -2793,7 +2808,7 @@ func (a *AWSCloud) getInstancesByIDs(instanceIDs []*string) (map[string]*ec2.Ins InstanceIds: instanceIDs, } - instances, err := a.ec2.DescribeInstances(request) + instances, err := c.ec2.DescribeInstances(request) if err != nil { return nil, err } @@ -2813,15 +2828,15 @@ func (a *AWSCloud) getInstancesByIDs(instanceIDs []*string) (map[string]*ec2.Ins // Fetches and caches instances by node names; returns an error if any cannot be found. // This is implemented with a multi value filter on the node names, fetching the desired instances with a single query. // TODO(therc): make all the caching more rational during the 1.4 timeframe -func (a *AWSCloud) getInstancesByNodeNamesCached(nodeNames sets.String) ([]*ec2.Instance, error) { - a.mutex.Lock() - defer a.mutex.Unlock() - if nodeNames.Equal(a.lastNodeNames) { - if len(a.lastInstancesByNodeNames) > 0 { +func (c *Cloud) getInstancesByNodeNamesCached(nodeNames sets.String) ([]*ec2.Instance, error) { + c.mutex.Lock() + defer c.mutex.Unlock() + if nodeNames.Equal(c.lastNodeNames) { + if len(c.lastInstancesByNodeNames) > 0 { // We assume that if the list of nodes is the same, the underlying // instances have not changed. Later we might guard this with TTLs. glog.V(2).Infof("Returning cached instances for %v", nodeNames) - return a.lastInstancesByNodeNames, nil + return c.lastInstancesByNodeNames, nil } } names := aws.StringSlice(nodeNames.List()) @@ -2836,12 +2851,12 @@ func (a *AWSCloud) getInstancesByNodeNamesCached(nodeNames sets.String) ([]*ec2. newEc2Filter("instance-state-name", "running"), } - filters = a.addFilters(filters) + filters = c.addFilters(filters) request := &ec2.DescribeInstancesInput{ Filters: filters, } - instances, err := a.ec2.DescribeInstances(request) + instances, err := c.ec2.DescribeInstances(request) if err != nil { glog.V(2).Infof("Failed to describe instances %v", nodeNames) return nil, err @@ -2853,24 +2868,24 @@ func (a *AWSCloud) getInstancesByNodeNamesCached(nodeNames sets.String) ([]*ec2. } glog.V(2).Infof("Caching instances for %v", nodeNames) - a.lastNodeNames = nodeNames - a.lastInstancesByNodeNames = instances + c.lastNodeNames = nodeNames + c.lastInstancesByNodeNames = instances return instances, nil } // Returns the instance with the specified node name // Returns nil if it does not exist -func (a *AWSCloud) findInstanceByNodeName(nodeName string) (*ec2.Instance, error) { +func (c *Cloud) findInstanceByNodeName(nodeName string) (*ec2.Instance, error) { filters := []*ec2.Filter{ newEc2Filter("private-dns-name", nodeName), newEc2Filter("instance-state-name", "running"), } - filters = a.addFilters(filters) + filters = c.addFilters(filters) request := &ec2.DescribeInstancesInput{ Filters: filters, } - instances, err := a.ec2.DescribeInstances(request) + instances, err := c.ec2.DescribeInstances(request) if err != nil { return nil, err } @@ -2885,8 +2900,8 @@ func (a *AWSCloud) findInstanceByNodeName(nodeName string) (*ec2.Instance, error // Returns the instance with the specified node name // Like findInstanceByNodeName, but returns error if node not found -func (a *AWSCloud) getInstanceByNodeName(nodeName string) (*ec2.Instance, error) { - instance, err := a.findInstanceByNodeName(nodeName) +func (c *Cloud) getInstanceByNodeName(nodeName string) (*ec2.Instance, error) { + instance, err := c.findInstanceByNodeName(nodeName) if err == nil && instance == nil { return nil, fmt.Errorf("no instances found for name: %s", nodeName) } @@ -2895,8 +2910,8 @@ func (a *AWSCloud) getInstanceByNodeName(nodeName string) (*ec2.Instance, error) // Add additional filters, to match on our tags // This lets us run multiple k8s clusters in a single EC2 AZ -func (s *AWSCloud) addFilters(filters []*ec2.Filter) []*ec2.Filter { - for k, v := range s.filterTags { +func (c *Cloud) addFilters(filters []*ec2.Filter) []*ec2.Filter { + for k, v := range c.filterTags { filters = append(filters, newEc2Filter("tag:"+k, v)) } if len(filters) == 0 { @@ -2909,6 +2924,6 @@ func (s *AWSCloud) addFilters(filters []*ec2.Filter) []*ec2.Filter { } // Returns the cluster name or an empty string -func (s *AWSCloud) getClusterName() string { - return s.filterTags[TagNameKubernetesCluster] +func (c *Cloud) getClusterName() string { + return c.filterTags[TagNameKubernetesCluster] } diff --git a/pkg/cloudprovider/providers/aws/aws_instancegroups.go b/pkg/cloudprovider/providers/aws/aws_instancegroups.go index 563c90de140..5edbb3da992 100644 --- a/pkg/cloudprovider/providers/aws/aws_instancegroups.go +++ b/pkg/cloudprovider/providers/aws/aws_instancegroups.go @@ -25,7 +25,7 @@ import ( ) // AWSCloud implements InstanceGroups -var _ InstanceGroups = &AWSCloud{} +var _ InstanceGroups = &Cloud{} // ResizeInstanceGroup sets the size of the specificed instancegroup Exported // so it can be used by the e2e tests, which don't want to instantiate a full @@ -44,8 +44,8 @@ func ResizeInstanceGroup(asg ASG, instanceGroupName string, size int) error { // Implement InstanceGroups.ResizeInstanceGroup // Set the size to the fixed size -func (a *AWSCloud) ResizeInstanceGroup(instanceGroupName string, size int) error { - return ResizeInstanceGroup(a.asg, instanceGroupName, size) +func (c *Cloud) ResizeInstanceGroup(instanceGroupName string, size int) error { + return ResizeInstanceGroup(c.asg, instanceGroupName, size) } // DescribeInstanceGroup gets info about the specified instancegroup @@ -72,8 +72,8 @@ func DescribeInstanceGroup(asg ASG, instanceGroupName string) (InstanceGroupInfo // Implement InstanceGroups.DescribeInstanceGroup // Queries the cloud provider for information about the specified instance group -func (a *AWSCloud) DescribeInstanceGroup(instanceGroupName string) (InstanceGroupInfo, error) { - return DescribeInstanceGroup(a.asg, instanceGroupName) +func (c *Cloud) DescribeInstanceGroup(instanceGroupName string) (InstanceGroupInfo, error) { + return DescribeInstanceGroup(c.asg, instanceGroupName) } // awsInstanceGroup implements InstanceGroupInfo diff --git a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go index 727675d8f01..85b2f2d50c5 100644 --- a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go +++ b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go @@ -30,8 +30,8 @@ import ( const ProxyProtocolPolicyName = "k8s-proxyprotocol-enabled" -func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadBalancerName string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string, internalELB, proxyProtocol bool) (*elb.LoadBalancerDescription, error) { - loadBalancer, err := s.describeLoadBalancer(loadBalancerName) +func (c *Cloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadBalancerName string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string, internalELB, proxyProtocol bool) (*elb.LoadBalancerDescription, error) { + loadBalancer, err := c.describeLoadBalancer(loadBalancerName) if err != nil { return nil, err } @@ -55,25 +55,25 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB createRequest.SecurityGroups = stringPointerArray(securityGroupIDs) createRequest.Tags = []*elb.Tag{ - {Key: aws.String(TagNameKubernetesCluster), Value: aws.String(s.getClusterName())}, + {Key: aws.String(TagNameKubernetesCluster), Value: aws.String(c.getClusterName())}, {Key: aws.String(TagNameKubernetesService), Value: aws.String(namespacedName.String())}, } glog.Infof("Creating load balancer for %v with name: ", namespacedName, loadBalancerName) - _, err := s.elb.CreateLoadBalancer(createRequest) + _, err := c.elb.CreateLoadBalancer(createRequest) if err != nil { return nil, err } if proxyProtocol { - err = s.createProxyProtocolPolicy(loadBalancerName) + err = c.createProxyProtocolPolicy(loadBalancerName) if err != nil { return nil, err } for _, listener := range listeners { glog.V(2).Infof("Adjusting AWS loadbalancer proxy protocol on node port %d. Setting to true", *listener.InstancePort) - err := s.setBackendPolicies(loadBalancerName, *listener.InstancePort, []*string{aws.String(ProxyProtocolPolicyName)}) + err := c.setBackendPolicies(loadBalancerName, *listener.InstancePort, []*string{aws.String(ProxyProtocolPolicyName)}) if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB request.LoadBalancerName = aws.String(loadBalancerName) request.Subnets = stringSetToPointers(removals) glog.V(2).Info("Detaching load balancer from removed subnets") - _, err := s.elb.DetachLoadBalancerFromSubnets(request) + _, err := c.elb.DetachLoadBalancerFromSubnets(request) if err != nil { return nil, fmt.Errorf("error detaching AWS loadbalancer from subnets: %v", err) } @@ -109,7 +109,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB request.LoadBalancerName = aws.String(loadBalancerName) request.Subnets = stringSetToPointers(additions) glog.V(2).Info("Attaching load balancer to added subnets") - _, err := s.elb.AttachLoadBalancerToSubnets(request) + _, err := c.elb.AttachLoadBalancerToSubnets(request) if err != nil { return nil, fmt.Errorf("error attaching AWS loadbalancer to subnets: %v", err) } @@ -128,7 +128,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB request.LoadBalancerName = aws.String(loadBalancerName) request.SecurityGroups = stringPointerArray(securityGroupIDs) glog.V(2).Info("Applying updated security groups to load balancer") - _, err := s.elb.ApplySecurityGroupsToLoadBalancer(request) + _, err := c.elb.ApplySecurityGroupsToLoadBalancer(request) if err != nil { return nil, fmt.Errorf("error applying AWS loadbalancer security groups: %v", err) } @@ -188,7 +188,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB request.LoadBalancerName = aws.String(loadBalancerName) request.LoadBalancerPorts = removals glog.V(2).Info("Deleting removed load balancer listeners") - _, err := s.elb.DeleteLoadBalancerListeners(request) + _, err := c.elb.DeleteLoadBalancerListeners(request) if err != nil { return nil, fmt.Errorf("error deleting AWS loadbalancer listeners: %v", err) } @@ -200,7 +200,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB request.LoadBalancerName = aws.String(loadBalancerName) request.Listeners = additions glog.V(2).Info("Creating added load balancer listeners") - _, err := s.elb.CreateLoadBalancerListeners(request) + _, err := c.elb.CreateLoadBalancerListeners(request) if err != nil { return nil, fmt.Errorf("error creating AWS loadbalancer listeners: %v", err) } @@ -219,7 +219,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB // back if a policy of the same name already exists. However, the aws-sdk does not // seem to return an error to us in these cases. Therefore this will issue an API // request every time. - err := s.createProxyProtocolPolicy(loadBalancerName) + err := c.createProxyProtocolPolicy(loadBalancerName) if err != nil { return nil, err } @@ -252,7 +252,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB if setPolicy { glog.V(2).Infof("Adjusting AWS loadbalancer proxy protocol on node port %d. Setting to %t", instancePort, proxyProtocol) - err := s.setBackendPolicies(loadBalancerName, instancePort, proxyPolicies) + err := c.setBackendPolicies(loadBalancerName, instancePort, proxyPolicies) if err != nil { return nil, err } @@ -266,7 +266,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB for instancePort, found := range foundBackends { if !found { glog.V(2).Infof("Adjusting AWS loadbalancer proxy protocol on node port %d. Setting to false", instancePort) - err := s.setBackendPolicies(loadBalancerName, instancePort, []*string{}) + err := c.setBackendPolicies(loadBalancerName, instancePort, []*string{}) if err != nil { return nil, err } @@ -277,7 +277,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB } if dirty { - loadBalancer, err = s.describeLoadBalancer(loadBalancerName) + loadBalancer, err = c.describeLoadBalancer(loadBalancerName) if err != nil { glog.Warning("Unable to retrieve load balancer after creation/update") return nil, err @@ -288,7 +288,7 @@ func (s *AWSCloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadB } // Makes sure that the health check for an ELB matches the configured listeners -func (s *AWSCloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerDescription, listeners []*elb.Listener) error { +func (c *Cloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerDescription, listeners []*elb.Listener) error { actual := loadBalancer.HealthCheck // Default AWS settings @@ -332,7 +332,7 @@ func (s *AWSCloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerD request.HealthCheck = healthCheck request.LoadBalancerName = loadBalancer.LoadBalancerName - _, err := s.elb.ConfigureHealthCheck(request) + _, err := c.elb.ConfigureHealthCheck(request) if err != nil { return fmt.Errorf("error configuring load-balancer health-check: %v", err) } @@ -341,7 +341,7 @@ func (s *AWSCloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerD } // Makes sure that exactly the specified hosts are registered as instances with the load balancer -func (s *AWSCloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstances []*elb.Instance, instances []*ec2.Instance) error { +func (c *Cloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstances []*elb.Instance, instances []*ec2.Instance) error { expected := sets.NewString() for _, instance := range instances { expected.Insert(orEmpty(instance.InstanceId)) @@ -373,7 +373,7 @@ func (s *AWSCloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstan registerRequest := &elb.RegisterInstancesWithLoadBalancerInput{} registerRequest.Instances = addInstances registerRequest.LoadBalancerName = aws.String(loadBalancerName) - _, err := s.elb.RegisterInstancesWithLoadBalancer(registerRequest) + _, err := c.elb.RegisterInstancesWithLoadBalancer(registerRequest) if err != nil { return err } @@ -384,7 +384,7 @@ func (s *AWSCloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstan deregisterRequest := &elb.DeregisterInstancesFromLoadBalancerInput{} deregisterRequest.Instances = removeInstances deregisterRequest.LoadBalancerName = aws.String(loadBalancerName) - _, err := s.elb.DeregisterInstancesFromLoadBalancer(deregisterRequest) + _, err := c.elb.DeregisterInstancesFromLoadBalancer(deregisterRequest) if err != nil { return err } @@ -394,7 +394,7 @@ func (s *AWSCloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstan return nil } -func (s *AWSCloud) createProxyProtocolPolicy(loadBalancerName string) error { +func (c *Cloud) createProxyProtocolPolicy(loadBalancerName string) error { request := &elb.CreateLoadBalancerPolicyInput{ LoadBalancerName: aws.String(loadBalancerName), PolicyName: aws.String(ProxyProtocolPolicyName), @@ -407,7 +407,7 @@ func (s *AWSCloud) createProxyProtocolPolicy(loadBalancerName string) error { }, } glog.V(2).Info("Creating proxy protocol policy on load balancer") - _, err := s.elb.CreateLoadBalancerPolicy(request) + _, err := c.elb.CreateLoadBalancerPolicy(request) if err != nil { return fmt.Errorf("error creating proxy protocol policy on load balancer: %v", err) } @@ -415,7 +415,7 @@ func (s *AWSCloud) createProxyProtocolPolicy(loadBalancerName string) error { return nil } -func (s *AWSCloud) setBackendPolicies(loadBalancerName string, instancePort int64, policies []*string) error { +func (c *Cloud) setBackendPolicies(loadBalancerName string, instancePort int64, policies []*string) error { request := &elb.SetLoadBalancerPoliciesForBackendServerInput{ InstancePort: aws.Int64(instancePort), LoadBalancerName: aws.String(loadBalancerName), @@ -426,7 +426,7 @@ func (s *AWSCloud) setBackendPolicies(loadBalancerName string, instancePort int6 } else { glog.V(2).Infof("Removing AWS loadbalancer backend policies on node port %d", instancePort) } - _, err := s.elb.SetLoadBalancerPoliciesForBackendServer(request) + _, err := c.elb.SetLoadBalancerPoliciesForBackendServer(request) if err != nil { return fmt.Errorf("error adjusting AWS loadbalancer backend policies: %v", err) } diff --git a/pkg/cloudprovider/providers/aws/aws_routes.go b/pkg/cloudprovider/providers/aws/aws_routes.go index a469e5f70b4..63a9e2e5ae2 100644 --- a/pkg/cloudprovider/providers/aws/aws_routes.go +++ b/pkg/cloudprovider/providers/aws/aws_routes.go @@ -25,14 +25,14 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider" ) -func (s *AWSCloud) findRouteTable(clusterName string) (*ec2.RouteTable, error) { +func (c *Cloud) findRouteTable(clusterName string) (*ec2.RouteTable, error) { // This should be unnecessary (we already filter on TagNameKubernetesCluster, // and something is broken if cluster name doesn't match, but anyway... // TODO: All clouds should be cluster-aware by default filters := []*ec2.Filter{newEc2Filter("tag:"+TagNameKubernetesCluster, clusterName)} - request := &ec2.DescribeRouteTablesInput{Filters: s.addFilters(filters)} + request := &ec2.DescribeRouteTablesInput{Filters: c.addFilters(filters)} - tables, err := s.ec2.DescribeRouteTables(request) + tables, err := c.ec2.DescribeRouteTables(request) if err != nil { return nil, err } @@ -49,8 +49,8 @@ func (s *AWSCloud) findRouteTable(clusterName string) (*ec2.RouteTable, error) { // ListRoutes implements Routes.ListRoutes // List all routes that match the filter -func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error) { - table, err := s.findRouteTable(clusterName) +func (c *Cloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error) { + table, err := c.findRouteTable(clusterName) if err != nil { return nil, err } @@ -68,7 +68,7 @@ func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error instanceIDs = append(instanceIDs, &instanceID) } - instances, err := s.getInstancesByIDs(instanceIDs) + instances, err := c.getInstancesByIDs(instanceIDs) if err != nil { return nil, err } @@ -95,12 +95,12 @@ func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error } // Sets the instance attribute "source-dest-check" to the specified value -func (s *AWSCloud) configureInstanceSourceDestCheck(instanceID string, sourceDestCheck bool) error { +func (c *Cloud) configureInstanceSourceDestCheck(instanceID string, sourceDestCheck bool) error { request := &ec2.ModifyInstanceAttributeInput{} request.InstanceId = aws.String(instanceID) request.SourceDestCheck = &ec2.AttributeBooleanValue{Value: aws.Bool(sourceDestCheck)} - _, err := s.ec2.ModifyInstanceAttribute(request) + _, err := c.ec2.ModifyInstanceAttribute(request) if err != nil { return fmt.Errorf("error configuring source-dest-check on instance %s: %v", instanceID, err) } @@ -109,20 +109,20 @@ func (s *AWSCloud) configureInstanceSourceDestCheck(instanceID string, sourceDes // CreateRoute implements Routes.CreateRoute // Create the described route -func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error { - instance, err := s.getInstanceByNodeName(route.TargetInstance) +func (c *Cloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error { + instance, err := c.getInstanceByNodeName(route.TargetInstance) if err != nil { return err } // In addition to configuring the route itself, we also need to configure the instance to accept that traffic // On AWS, this requires turning source-dest checks off - err = s.configureInstanceSourceDestCheck(orEmpty(instance.InstanceId), false) + err = c.configureInstanceSourceDestCheck(orEmpty(instance.InstanceId), false) if err != nil { return err } - table, err := s.findRouteTable(clusterName) + table, err := c.findRouteTable(clusterName) if err != nil { return err } @@ -147,7 +147,7 @@ func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloud request.DestinationCidrBlock = deleteRoute.DestinationCidrBlock request.RouteTableId = table.RouteTableId - _, err = s.ec2.DeleteRoute(request) + _, err = c.ec2.DeleteRoute(request) if err != nil { return fmt.Errorf("error deleting blackholed AWS route (%s): %v", aws.StringValue(deleteRoute.DestinationCidrBlock), err) } @@ -159,7 +159,7 @@ func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloud request.InstanceId = instance.InstanceId request.RouteTableId = table.RouteTableId - _, err = s.ec2.CreateRoute(request) + _, err = c.ec2.CreateRoute(request) if err != nil { return fmt.Errorf("error creating AWS route (%s): %v", route.DestinationCIDR, err) } @@ -169,8 +169,8 @@ func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloud // DeleteRoute implements Routes.DeleteRoute // Delete the specified route -func (s *AWSCloud) DeleteRoute(clusterName string, route *cloudprovider.Route) error { - table, err := s.findRouteTable(clusterName) +func (c *Cloud) DeleteRoute(clusterName string, route *cloudprovider.Route) error { + table, err := c.findRouteTable(clusterName) if err != nil { return err } @@ -179,7 +179,7 @@ func (s *AWSCloud) DeleteRoute(clusterName string, route *cloudprovider.Route) e request.DestinationCidrBlock = aws.String(route.DestinationCIDR) request.RouteTableId = table.RouteTableId - _, err = s.ec2.DeleteRoute(request) + _, err = c.ec2.DeleteRoute(request) if err != nil { return fmt.Errorf("error deleting AWS route (%s): %v", route.DestinationCIDR, err) } diff --git a/pkg/cloudprovider/providers/aws/aws_test.go b/pkg/cloudprovider/providers/aws/aws_test.go index fcd7935c5ca..5932b059edd 100644 --- a/pkg/cloudprovider/providers/aws/aws_test.go +++ b/pkg/cloudprovider/providers/aws/aws_test.go @@ -43,7 +43,7 @@ func TestReadAWSCloudConfig(t *testing.T) { name string reader io.Reader - aws AWSServices + aws Services expectError bool zone string @@ -198,7 +198,7 @@ func TestNewAWSCloud(t *testing.T) { name string reader io.Reader - awsServices AWSServices + awsServices Services expectError bool region string @@ -508,7 +508,7 @@ func (a *FakeASG) DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGrou panic("Not implemented") } -func mockInstancesResp(selfInstance *ec2.Instance, instances []*ec2.Instance) (*AWSCloud, *FakeAWSServices) { +func mockInstancesResp(selfInstance *ec2.Instance, instances []*ec2.Instance) (*Cloud, *FakeAWSServices) { awsServices := NewFakeAWSServices() awsServices.instances = instances awsServices.selfInstance = selfInstance @@ -519,7 +519,7 @@ func mockInstancesResp(selfInstance *ec2.Instance, instances []*ec2.Instance) (* return awsCloud, awsServices } -func mockAvailabilityZone(availabilityZone string) *AWSCloud { +func mockAvailabilityZone(availabilityZone string) *Cloud { awsServices := NewFakeAWSServices().withAz(availabilityZone) awsCloud, err := newAWSCloud(nil, awsServices) if err != nil { diff --git a/pkg/volume/aws_ebs/aws_util.go b/pkg/volume/aws_ebs/aws_util.go index c3097f31c0d..76ebe72adc5 100644 --- a/pkg/volume/aws_ebs/aws_util.go +++ b/pkg/volume/aws_ebs/aws_util.go @@ -166,8 +166,8 @@ func pathExists(path string) (bool, error) { } // Return cloud provider -func getCloudProvider(cloudProvider cloudprovider.Interface) (*aws.AWSCloud, error) { - awsCloudProvider, ok := cloudProvider.(*aws.AWSCloud) +func getCloudProvider(cloudProvider cloudprovider.Interface) (*aws.Cloud, error) { + awsCloudProvider, ok := cloudProvider.(*aws.Cloud) if !ok || awsCloudProvider == nil { return nil, fmt.Errorf("Failed to get AWS Cloud Provider. GetCloudProvider returned %v instead", cloudProvider) } diff --git a/plugin/pkg/admission/persistentvolume/label/admission.go b/plugin/pkg/admission/persistentvolume/label/admission.go index 67648058ed7..915ea63a5a4 100644 --- a/plugin/pkg/admission/persistentvolume/label/admission.go +++ b/plugin/pkg/admission/persistentvolume/label/admission.go @@ -136,7 +136,7 @@ func (l *persistentVolumeLabel) getEBSVolumes() (aws.Volumes, error) { if err != nil || cloudProvider == nil { return nil, err } - awsCloudProvider, ok := cloudProvider.(*aws.AWSCloud) + awsCloudProvider, ok := cloudProvider.(*aws.Cloud) if !ok { // GetCloudProvider has gone very wrong return nil, fmt.Errorf("error retrieving AWS cloud provider")