mirror of https://github.com/k3s-io/k3s
commit
ac582b0d93
|
@ -37,16 +37,22 @@ import (
|
||||||
type EC2 interface {
|
type EC2 interface {
|
||||||
// Query EC2 for instances matching the filter
|
// Query EC2 for instances matching the filter
|
||||||
Instances(instIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error)
|
Instances(instIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error)
|
||||||
|
|
||||||
|
// Query the EC2 metadata service (used to discover instance-id etc)
|
||||||
|
GetMetaData(key string) ([]byte, 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 {
|
||||||
ec2 EC2
|
ec2 EC2
|
||||||
cfg *AWSCloudConfig
|
cfg *AWSCloudConfig
|
||||||
|
availabilityZone string
|
||||||
|
region aws.Region
|
||||||
}
|
}
|
||||||
|
|
||||||
type AWSCloudConfig struct {
|
type AWSCloudConfig struct {
|
||||||
Global struct {
|
Global struct {
|
||||||
|
// TODO: Is there any use for this? We can get it from the instance metadata service
|
||||||
Region string
|
Region string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +88,14 @@ func (self *GoamzEC2) Instances(instanceIds []string, filter *ec2InstanceFilter)
|
||||||
return self.ec2.Instances(instanceIds, goamzFilter)
|
return self.ec2.Instances(instanceIds, goamzFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *GoamzEC2) GetMetaData(key string) ([]byte, error) {
|
||||||
|
v, err := aws.GetMetaData(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error querying AWS metadata for key %s: %v", key, err)
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
type AuthFunc func() (auth aws.Auth, err error)
|
type AuthFunc func() (auth aws.Auth, err error)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -125,18 +139,36 @@ func newAWSCloud(config io.Reader, authFunc AuthFunc) (*AWSCloud, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: We can get the region very easily from the instance-metadata service
|
||||||
region, ok := aws.Regions[cfg.Global.Region]
|
region, ok := aws.Regions[cfg.Global.Region]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("not a valid AWS region: %s", cfg.Global.Region)
|
return nil, fmt.Errorf("not a valid AWS region: %s", cfg.Global.Region)
|
||||||
}
|
}
|
||||||
|
|
||||||
ec2 := ec2.New(auth, region)
|
|
||||||
return &AWSCloud{
|
return &AWSCloud{
|
||||||
ec2: &GoamzEC2{ec2: ec2},
|
ec2: &GoamzEC2{ec2: ec2.New(auth, region)},
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
region: region,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *AWSCloud) getAvailabilityZone() (string, error) {
|
||||||
|
// TODO: Do we need sync.Mutex here?
|
||||||
|
availabilityZone := self.availabilityZone
|
||||||
|
if self.availabilityZone == "" {
|
||||||
|
availabilityZoneBytes, err := self.ec2.GetMetaData("placement/availability-zone")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if availabilityZoneBytes == nil || len(availabilityZoneBytes) == 0 {
|
||||||
|
return "", fmt.Errorf("Unable to determine availability-zone from instance metadata")
|
||||||
|
}
|
||||||
|
availabilityZone = string(availabilityZoneBytes)
|
||||||
|
self.availabilityZone = availabilityZone
|
||||||
|
}
|
||||||
|
return availabilityZone, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (aws *AWSCloud) Clusters() (cloudprovider.Clusters, bool) {
|
func (aws *AWSCloud) Clusters() (cloudprovider.Clusters, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -153,7 +185,7 @@ func (aws *AWSCloud) Instances() (cloudprovider.Instances, bool) {
|
||||||
|
|
||||||
// Zones returns an implementation of Zones for Amazon Web Services.
|
// Zones returns an implementation of Zones for Amazon Web Services.
|
||||||
func (aws *AWSCloud) Zones() (cloudprovider.Zones, bool) {
|
func (aws *AWSCloud) Zones() (cloudprovider.Zones, bool) {
|
||||||
return nil, false
|
return aws, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPAddress is an implementation of Instances.IPAddress.
|
// IPAddress is an implementation of Instances.IPAddress.
|
||||||
|
@ -246,3 +278,15 @@ func (aws *AWSCloud) List(filter string) ([]string, error) {
|
||||||
func (v *AWSCloud) GetNodeResources(name string) (*api.NodeResources, error) {
|
func (v *AWSCloud) GetNodeResources(name string) (*api.NodeResources, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetZone implements Zones.GetZone
|
||||||
|
func (self *AWSCloud) GetZone() (cloudprovider.Zone, error) {
|
||||||
|
availabilityZone, err := self.getAvailabilityZone()
|
||||||
|
if err != nil {
|
||||||
|
return cloudprovider.Zone{}, err
|
||||||
|
}
|
||||||
|
return cloudprovider.Zone{
|
||||||
|
FailureDomain: availabilityZone,
|
||||||
|
Region: self.region.Name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -76,19 +76,13 @@ func TestNewAWSCloud(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FakeEC2 struct {
|
type FakeEC2 struct {
|
||||||
instances func(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error)
|
instances []ec2.Instance
|
||||||
|
availabilityZone string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec2 *FakeEC2) Instances(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error) {
|
func (self *FakeEC2) Instances(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error) {
|
||||||
return ec2.instances(instanceIds, filter)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockInstancesResp(instances []ec2.Instance) (aws *AWSCloud) {
|
|
||||||
return &AWSCloud{
|
|
||||||
&FakeEC2{
|
|
||||||
func(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error) {
|
|
||||||
matches := []ec2.Instance{}
|
matches := []ec2.Instance{}
|
||||||
for _, instance := range instances {
|
for _, instance := range self.instances {
|
||||||
if filter == nil || filter.Matches(instance) {
|
if filter == nil || filter.Matches(instance) {
|
||||||
matches = append(matches, instance)
|
matches = append(matches, instance)
|
||||||
}
|
}
|
||||||
|
@ -96,8 +90,33 @@ func mockInstancesResp(instances []ec2.Instance) (aws *AWSCloud) {
|
||||||
return &ec2.InstancesResp{"",
|
return &ec2.InstancesResp{"",
|
||||||
[]ec2.Reservation{
|
[]ec2.Reservation{
|
||||||
{"", "", "", nil, matches}}}, nil
|
{"", "", "", nil, matches}}}, nil
|
||||||
}},
|
}
|
||||||
nil}
|
|
||||||
|
func (self *FakeEC2) GetMetaData(key string) ([]byte, error) {
|
||||||
|
if key == "placement/availability-zone" {
|
||||||
|
return []byte(self.availabilityZone), nil
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockInstancesResp(instances []ec2.Instance) (aws *AWSCloud) {
|
||||||
|
availabilityZone := "us-west-2d"
|
||||||
|
return &AWSCloud{
|
||||||
|
ec2: &FakeEC2{
|
||||||
|
instances: instances,
|
||||||
|
availabilityZone: availabilityZone,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockAvailabilityZone(region string, availabilityZone string) *AWSCloud {
|
||||||
|
return &AWSCloud{
|
||||||
|
ec2: &FakeEC2{
|
||||||
|
availabilityZone: availabilityZone,
|
||||||
|
},
|
||||||
|
region: aws.Regions[region],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
|
@ -163,3 +182,21 @@ func TestIPAddress(t *testing.T) {
|
||||||
t.Errorf("Expected %v, got %v", e, a)
|
t.Errorf("Expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetRegion(t *testing.T) {
|
||||||
|
aws := mockAvailabilityZone("us-west-2", "us-west-2e")
|
||||||
|
zones, ok := aws.Zones()
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Unexpected missing zones impl")
|
||||||
|
}
|
||||||
|
zone, err := zones.GetZone()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %v", err)
|
||||||
|
}
|
||||||
|
if zone.Region != "us-west-2" {
|
||||||
|
t.Errorf("Unexpected region: %s", zone.Region)
|
||||||
|
}
|
||||||
|
if zone.FailureDomain != "us-west-2e" {
|
||||||
|
t.Errorf("Unexpected FailureDomain: %s", zone.FailureDomain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue