mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
Merge pull request #7775 from simon3z/cloud-provider-id
api: add the ProviderID attribute to NodeSpec
This commit is contained in:
commit
32bb3ae8f1
@ -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
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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{}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user