Merge pull request #7775 from simon3z/cloud-provider-id

api: add the ProviderID attribute to NodeSpec
This commit is contained in:
Tim Hockin 2015-05-28 15:54:00 -07:00
commit 32bb3ae8f1
26 changed files with 200 additions and 23 deletions

View File

@ -921,6 +921,7 @@ func deepCopy_api_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) err
func deepCopy_api_NodeSpec(in NodeSpec, out *NodeSpec, c *conversion.Cloner) error {
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}

View File

@ -1241,6 +1241,10 @@ type NodeSpec struct {
// External ID of the node assigned by some machine database (e.g. a cloud provider)
ExternalID string `json:"externalID,omitempty"`
// ID of the node assigned by the cloud provider
// Note: format is "<ProviderName>://<ProviderSpecificNodeID>"
ProviderID string `json:"providerID,omitempty"`
// Unschedulable controls node schedulability of new pods. By default node is schedulable.
Unschedulable bool `json:"unschedulable,omitempty"`
}

View File

@ -995,6 +995,7 @@ func convert_api_NodeSpec_To_v1_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conv
}
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}
@ -3269,6 +3270,7 @@ func convert_v1_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conv
}
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}

View File

@ -852,6 +852,7 @@ func deepCopy_v1_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) erro
func deepCopy_v1_NodeSpec(in NodeSpec, out *NodeSpec, c *conversion.Cloner) error {
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}

View File

@ -397,6 +397,9 @@ func TestSetDefaultNodeExternalID(t *testing.T) {
if n2.Spec.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID)
}
if n2.Spec.ProviderID != "" {
t.Errorf("Expected empty default Cloud Provider ID, got: %s", n2.Spec.ProviderID)
}
}
func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {

View File

@ -1229,7 +1229,9 @@ type NodeSpec struct {
// PodCIDR represents the pod IP range assigned to the node
PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"`
// External ID of the node assigned by some machine database (e.g. a cloud provider)
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
ExternalID string `json:"externalID,omitempty" description:"deprecated. External ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
// ID of the node assigned by the cloud provider
ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>"`
// Unschedulable controls node schedulability of new pods. By default node is schedulable.
Unschedulable bool `json:"unschedulable,omitempty" description:"disable pod scheduling on the node"`
}

View File

@ -888,6 +888,7 @@ func addConversionFuncs() {
}
out.PodCIDR = in.Spec.PodCIDR
out.ExternalID = in.Spec.ExternalID
out.ProviderID = in.Spec.ProviderID
out.Unschedulable = in.Spec.Unschedulable
return s.Convert(&in.Status.Capacity, &out.NodeResources.Capacity, 0)
},
@ -920,6 +921,7 @@ func addConversionFuncs() {
}
out.Spec.PodCIDR = in.PodCIDR
out.Spec.ExternalID = in.ExternalID
out.Spec.ProviderID = in.ProviderID
out.Spec.Unschedulable = in.Unschedulable
return s.Convert(&in.NodeResources.Capacity, &out.Status.Capacity, 0)
},

View File

@ -326,6 +326,9 @@ func TestSetDefaultMinionExternalID(t *testing.T) {
if m2.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, m2.ExternalID)
}
if m2.ProviderID != "" {
t.Errorf("Expected empty default Cloud Provider ID, got: %s", m2.ProviderID)
}
}
func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {

View File

@ -1210,7 +1210,9 @@ type Minion struct {
// Labels for the node
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize minions; labels of a minion assigned by the scheduler must match the scheduled pod's nodeSelector"`
// External ID of the node
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
ExternalID string `json:"externalID,omitempty" description:"deprecated. External id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
// ID of the node assigned by the cloud provider
ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>"`
}
// MinionList is a list of minions.

View File

@ -810,6 +810,7 @@ func addConversionFuncs() {
}
out.PodCIDR = in.Spec.PodCIDR
out.ExternalID = in.Spec.ExternalID
out.ProviderID = in.Spec.ProviderID
out.Unschedulable = in.Spec.Unschedulable
return s.Convert(&in.Status.Capacity, &out.NodeResources.Capacity, 0)
},
@ -842,6 +843,7 @@ func addConversionFuncs() {
}
out.Spec.PodCIDR = in.PodCIDR
out.Spec.ExternalID = in.ExternalID
out.Spec.ProviderID = in.ProviderID
out.Spec.Unschedulable = in.Unschedulable
return s.Convert(&in.NodeResources.Capacity, &out.Status.Capacity, 0)
},

View File

@ -325,6 +325,9 @@ func TestSetDefaultMinionExternalID(t *testing.T) {
if m2.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, m2.ExternalID)
}
if m2.ProviderID != "" {
t.Errorf("Expected empty default Cloud Provider ID, got: %s", m2.ProviderID)
}
}
func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {

View File

@ -1226,7 +1226,9 @@ type Minion struct {
// Labels for the node
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize minions; labels of a minion assigned by the scheduler must match the scheduled pod's nodeSelector"`
// External ID of the node
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
ExternalID string `json:"externalID,omitempty" description:"deprecated. External id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
// ID of the node assigned by the cloud provider
ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>"`
}
// MinionList is a list of minions.

View File

@ -902,6 +902,7 @@ func convert_api_NodeSpec_To_v1beta3_NodeSpec(in *api.NodeSpec, out *NodeSpec, s
}
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}
@ -3047,6 +3048,7 @@ func convert_v1beta3_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s
}
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}

View File

@ -856,6 +856,7 @@ func deepCopy_v1beta3_NodeList(in NodeList, out *NodeList, c *conversion.Cloner)
func deepCopy_v1beta3_NodeSpec(in NodeSpec, out *NodeSpec, c *conversion.Cloner) error {
out.PodCIDR = in.PodCIDR
out.ExternalID = in.ExternalID
out.ProviderID = in.ProviderID
out.Unschedulable = in.Unschedulable
return nil
}

View File

@ -334,6 +334,9 @@ func TestSetDefaultNodeExternalID(t *testing.T) {
if n2.Spec.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID)
}
if n2.Spec.ProviderID != "" {
t.Errorf("Expected empty default Cloud Provider ID, got: %s", n2.Spec.ProviderID)
}
}
func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {

View File

@ -1236,7 +1236,9 @@ type NodeSpec struct {
// PodCIDR represents the pod IP range assigned to the node
PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"`
// External ID of the node assigned by some machine database (e.g. a cloud provider)
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
ExternalID string `json:"externalID,omitempty" description:"deprecated. External ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
// ID of the node assigned by the cloud provider
ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>"`
// Unschedulable controls node schedulability of new pods. By default node is schedulable.
Unschedulable bool `json:"unschedulable,omitempty" description:"disable pod scheduling on the node"`
}

View File

@ -41,6 +41,8 @@ import (
"github.com/golang/glog"
)
const ProviderName = "aws"
// Abstraction over EC2, to allow mocking/other implementations
type EC2 interface {
// Query EC2 for instances matching the filter
@ -244,7 +246,7 @@ func (s *awsSdkEC2) DeleteVolume(volumeID string) (resp *ec2.DeleteVolumeOutput,
}
func init() {
cloudprovider.RegisterCloudProvider("aws", func(config io.Reader) (cloudprovider.Interface, error) {
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
metadata := &awsSdkMetadata{}
return newAWSCloud(config, getAuth, metadata)
})
@ -360,6 +362,11 @@ func (aws *AWSCloud) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (aws *AWSCloud) ProviderName() string {
return ProviderName
}
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Amazon Web Services.
func (aws *AWSCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
return nil, false
@ -414,7 +421,7 @@ func (aws *AWSCloud) NodeAddresses(name string) ([]api.NodeAddress, error) {
return addresses, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (aws *AWSCloud) ExternalID(name string) (string, error) {
inst, err := aws.getInstancesByDnsName(name)
if err != nil {
@ -423,6 +430,17 @@ func (aws *AWSCloud) ExternalID(name string) (string, error) {
return *inst.InstanceID, nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (aws *AWSCloud) InstanceID(name string) (string, error) {
inst, err := aws.getInstancesByDnsName(name)
if err != nil {
return "", err
}
// In the future it is possible to also return an endpoint as:
// <endpoint>/<zone>/<instanceid>
return "/" + *inst.Placement.AvailabilityZone + "/" + *inst.InstanceID, nil
}
// Return the instances matching the relevant private dns name.
func (aws *AWSCloud) getInstancesByDnsName(name string) (*ec2.Instance, error) {
f := &ec2InstanceFilter{}

View File

@ -18,6 +18,7 @@ package cloudprovider
import (
"errors"
"fmt"
"net"
"strings"
@ -36,6 +37,8 @@ type Interface interface {
Clusters() (Clusters, bool)
// Routes returns a routes interface along with whether the interface is supported.
Routes() (Routes, bool)
// ProviderName returns the cloud provider ID.
ProviderName() string
}
// Clusters is an abstract, pluggable interface for clusters of containers.
@ -59,6 +62,18 @@ func GetLoadBalancerName(service *api.Service) string {
return ret
}
func GetInstanceProviderID(cloud Interface, nodeName string) (string, error) {
instances, ok := cloud.Instances()
if !ok {
return "", fmt.Errorf("failed to get instances from cloud provider")
}
instanceID, err := instances.InstanceID(nodeName)
if err != nil {
return "", fmt.Errorf("failed to get instance ID from cloud provider: %v", err)
}
return cloud.ProviderName() + "://" + instanceID, nil
}
// TCPLoadBalancer is an abstract, pluggable interface for TCP load balancers.
type TCPLoadBalancer interface {
// TODO: Break this up into different interfaces (LB, etc) when we have more than one type of service
@ -85,8 +100,10 @@ type Instances interface {
// returns the address of the calling instance. We should do a rename to
// make this clearer.
NodeAddresses(name string) ([]api.NodeAddress, error)
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
ExternalID(name string) (string, error)
// InstanceID returns the cloud provider ID of the specified instance.
InstanceID(name string) (string, error)
// List lists instances that match 'filter' which is a regular expression which must match the entire instance name (fqdn)
List(filter string) ([]string, error)
// GetNodeResources gets the resources for a particular node

View File

@ -26,6 +26,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
)
const ProviderName = "fake"
// FakeBalancer is a fake storage of balancer information
type FakeBalancer struct {
Name string
@ -81,6 +83,11 @@ func (f *FakeCloud) Clusters() (cloudprovider.Clusters, bool) {
return f, true
}
// ProviderName returns the cloud provider ID.
func (f *FakeCloud) ProviderName() string {
return ProviderName
}
// TCPLoadBalancer returns a fake implementation of TCPLoadBalancer.
// Actually it just returns f itself.
func (f *FakeCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
@ -152,6 +159,12 @@ func (f *FakeCloud) ExternalID(instance string) (string, error) {
return f.ExtID[instance], f.Err
}
// InstanceID returns the cloud provider ID of the specified instance.
func (f *FakeCloud) InstanceID(instance string) (string, error) {
f.addCall("instance-id")
return f.ExtID[instance], nil
}
// List is a test-spy implementation of Instances.List.
// It adds an entry "list" into the internal method call record.
func (f *FakeCloud) List(filter string) ([]string, error) {

View File

@ -42,6 +42,8 @@ import (
"google.golang.org/cloud/compute/metadata"
)
const ProviderName = "gce"
const EXTERNAL_IP_METADATA_URL = "http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip"
// GCECloud is an implementation of Interface, TCPLoadBalancer and Instances for Google Compute Engine.
@ -67,7 +69,7 @@ type Config struct {
}
func init() {
cloudprovider.RegisterCloudProvider("gce", func(config io.Reader) (cloudprovider.Interface, error) { return newGCECloud(config) })
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) { return newGCECloud(config) })
}
func getMetadata(url string) (string, error) {
@ -182,6 +184,11 @@ func (gce *GCECloud) Clusters() (cloudprovider.Clusters, bool) {
return gce, true
}
// ProviderName returns the cloud provider ID.
func (gce *GCECloud) ProviderName() string {
return ProviderName
}
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Google Compute Engine.
func (gce *GCECloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
return gce, true
@ -481,7 +488,7 @@ func (gce *GCECloud) NodeAddresses(_ string) ([]api.NodeAddress, error) {
}, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (gce *GCECloud) ExternalID(instance string) (string, error) {
inst, err := gce.getInstanceByName(instance)
if err != nil {
@ -490,6 +497,11 @@ func (gce *GCECloud) ExternalID(instance string) (string, error) {
return strconv.FormatUint(inst.Id, 10), nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (gce *GCECloud) InstanceID(instance string) (string, error) {
return gce.projectID + "/" + gce.zone + "/" + canonicalizeInstanceName(instance), nil
}
// List is an implementation of Instances.List.
func (gce *GCECloud) List(filter string) ([]string, error) {
listCall := gce.service.Instances.List(gce.projectID, gce.zone)

View File

@ -31,7 +31,7 @@ import (
)
var (
PluginName = "mesos"
ProviderName = "mesos"
CloudProvider *MesosCloud
noHostNameSpecified = errors.New("No hostname specified")
@ -39,7 +39,7 @@ var (
func init() {
cloudprovider.RegisterCloudProvider(
PluginName,
ProviderName,
func(configReader io.Reader) (cloudprovider.Interface, error) {
provider, err := newMesosCloud(configReader)
if err == nil {
@ -110,6 +110,11 @@ func (c *MesosCloud) Routes() (cloudprovider.Routes, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (c *MesosCloud) ProviderName() string {
return ProviderName
}
// ListClusters lists the names of the available Mesos clusters.
func (c *MesosCloud) ListClusters() ([]string, error) {
// Always returns a single cluster (this one!)
@ -161,7 +166,7 @@ func ipAddress(name string) (net.IP, error) {
return ipaddr, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (c *MesosCloud) ExternalID(instance string) (string, error) {
ip, err := ipAddress(instance)
if err != nil {
@ -170,6 +175,11 @@ func (c *MesosCloud) ExternalID(instance string) (string, error) {
return ip.String(), nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (c *MesosCloud) InstanceID(name string) (string, error) {
return "", nil
}
// List lists instances that match 'filter' which is a regular expression
// which must match the entire instance name (fqdn).
func (c *MesosCloud) List(filter string) ([]string, error) {

View File

@ -42,6 +42,8 @@ import (
"github.com/golang/glog"
)
const ProviderName = "openstack"
var ErrNotFound = errors.New("Failed to find object")
var ErrMultipleResults = errors.New("Multiple results where only one expected")
var ErrNoAddressFound = errors.New("No address found for host")
@ -99,7 +101,7 @@ type Config struct {
}
func init() {
cloudprovider.RegisterCloudProvider("openstack", func(config io.Reader) (cloudprovider.Interface, error) {
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
cfg, err := readConfig(config)
if err != nil {
return nil, err
@ -355,7 +357,7 @@ func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) {
return addrs, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (i *Instances) ExternalID(name string) (string, error) {
srv, err := getServerByName(i.compute, name)
if err != nil {
@ -364,6 +366,17 @@ func (i *Instances) ExternalID(name string) (string, error) {
return srv.ID, nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (i *Instances) InstanceID(name string) (string, error) {
srv, err := getServerByName(i.compute, name)
if err != nil {
return "", err
}
// In the future it is possible to also return an endpoint as:
// <endpoint>/<instanceid>
return "/" + srv.ID, nil
}
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
glog.V(4).Infof("GetNodeResources(%v) called", name)
@ -394,6 +407,11 @@ func (os *OpenStack) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (os *OpenStack) ProviderName() string {
return ProviderName
}
type LoadBalancer struct {
network *gophercloud.ServiceClient
compute *gophercloud.ServiceClient

View File

@ -33,6 +33,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
)
const ProviderName = "ovirt"
type OVirtInstance struct {
UUID string
Name string
@ -75,7 +77,7 @@ type XmlVmsList struct {
}
func init() {
cloudprovider.RegisterCloudProvider("ovirt",
cloudprovider.RegisterCloudProvider(ProviderName,
func(config io.Reader) (cloudprovider.Interface, error) {
return newOVirtCloud(config)
})
@ -115,6 +117,11 @@ func (aws *OVirtCloud) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (v *OVirtCloud) ProviderName() string {
return ProviderName
}
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for oVirt cloud
func (v *OVirtCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
return nil, false
@ -160,7 +167,7 @@ func (v *OVirtCloud) NodeAddresses(name string) ([]api.NodeAddress, error) {
return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: address.String()}}, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (v *OVirtCloud) ExternalID(name string) (string, error) {
instance, err := v.fetchInstance(name)
if err != nil {
@ -169,6 +176,17 @@ func (v *OVirtCloud) ExternalID(name string) (string, error) {
return instance.UUID, nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (v *OVirtCloud) InstanceID(name string) (string, error) {
instance, err := v.fetchInstance(name)
if err != nil {
return "", err
}
// TODO: define a way to identify the provider instance to complete
// the format <provider_instance_id>/<instance_id>.
return "/" + instance.UUID, err
}
func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) {
if body == nil {
return nil, fmt.Errorf("ovirt rest-api response body is missing")

View File

@ -38,6 +38,8 @@ import (
"github.com/golang/glog"
)
const ProviderName = "rackspace"
var ErrNotFound = errors.New("Failed to find object")
var ErrMultipleResults = errors.New("Multiple results where only one expected")
var ErrNoAddressFound = errors.New("No address found for host")
@ -89,7 +91,7 @@ type Config struct {
}
func init() {
cloudprovider.RegisterCloudProvider("rackspace", func(config io.Reader) (cloudprovider.Interface, error) {
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
cfg, err := readConfig(config)
if err != nil {
return nil, err
@ -364,11 +366,16 @@ func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) {
return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: net.ParseIP(ip).String()}}, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (i *Instances) ExternalID(name string) (string, error) {
return "", fmt.Errorf("unimplemented")
}
// InstanceID returns the cloud provider ID of the specified instance.
func (i *Instances) InstanceID(name string) (string, error) {
return "", nil
}
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
glog.V(2).Infof("GetNodeResources(%v) called", name)
@ -399,6 +406,11 @@ func (os *Rackspace) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (os *Rackspace) ProviderName() string {
return ProviderName
}
func (os *Rackspace) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
return nil, false
}

View File

@ -31,6 +31,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
)
const ProviderName = "vagrant"
// VagrantCloud is an implementation of Interface, TCPLoadBalancer and Instances for developer managed Vagrant cluster.
type VagrantCloud struct {
saltURL string
@ -40,7 +42,7 @@ type VagrantCloud struct {
}
func init() {
cloudprovider.RegisterCloudProvider("vagrant", func(config io.Reader) (cloudprovider.Interface, error) { return newVagrantCloud() })
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) { return newVagrantCloud() })
}
// SaltToken is an authorization token required by Salt REST API.
@ -84,6 +86,11 @@ func (v *VagrantCloud) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (v *VagrantCloud) ProviderName() string {
return ProviderName
}
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Vagrant cloud.
func (v *VagrantCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
return nil, false
@ -135,7 +142,7 @@ func (v *VagrantCloud) NodeAddresses(instance string) ([]api.NodeAddress, error)
return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: ip.String()}}, nil
}
// ExternalID returns the cloud provider ID of the specified instance.
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (v *VagrantCloud) ExternalID(instance string) (string, error) {
// Due to vagrant not running with a dedicated DNS setup, we return the IP address of a minion as its hostname at this time
minion, err := v.getInstanceByAddress(instance)
@ -145,6 +152,15 @@ func (v *VagrantCloud) ExternalID(instance string) (string, error) {
return minion.IP, nil
}
// InstanceID returns the cloud provider ID of the specified instance.
func (v *VagrantCloud) InstanceID(instance string) (string, error) {
minion, err := v.getInstanceByAddress(instance)
if err != nil {
return "", err
}
return minion.IP, nil
}
// saltMinionsByRole filters a list of minions that have a matching role.
func (v *VagrantCloud) saltMinionsByRole(minions []SaltMinion, role string) []SaltMinion {
var filteredMinions []SaltMinion

View File

@ -700,11 +700,19 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) {
}
// TODO(roberthbailey): Can we do this without having credentials to talk
// to the cloud provider?
instanceID, err := instances.ExternalID(kl.hostname)
// TODO: ExternalID is deprecated, we'll have to drop this code
externalID, err := instances.ExternalID(kl.hostname)
if err != nil {
return nil, fmt.Errorf("failed to get instance ID from cloud provider: %v", err)
return nil, fmt.Errorf("failed to get external ID from cloud provider: %v", err)
}
node.Spec.ExternalID = externalID
// TODO: We can't assume that the node has credentials to talk to the
// cloudprovider from arbitrary nodes. At most, we should talk to a
// local metadata server here.
node.Spec.ProviderID, err = cloudprovider.GetInstanceProviderID(kl.cloud, kl.hostname)
if err != nil {
return nil, err
}
node.Spec.ExternalID = instanceID
} else {
node.Spec.ExternalID = kl.hostname
}