mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
cloudprovider: add instance id to NodeSpec
Sometimes for external applications it is important to identify the cloud instance of the nodes. Until this patch there was no contract that the node name returned by List was also the unique identifier of the cloud instance. This new API ensures that an external application can reliably retrieve the relevant instance id of the nodes. Signed-off-by: Federico Simoncelli <fsimonce@redhat.com>
This commit is contained in:
parent
8844c06574
commit
a450da4fd0
@ -781,6 +781,8 @@ type NodeSpec struct {
|
|||||||
// PodCIDR represents the pod IP range assigned to the node
|
// PodCIDR represents the pod IP range assigned to the node
|
||||||
// Note: assigning IP ranges to nodes might need to be revisited when we support migratable IPs.
|
// Note: assigning IP ranges to nodes might need to be revisited when we support migratable IPs.
|
||||||
PodCIDR string `json:"cidr,omitempty"`
|
PodCIDR string `json:"cidr,omitempty"`
|
||||||
|
// External ID of the node assigned by some machine database (e.g. a cloud provider)
|
||||||
|
ExternalID string `json:"externalID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeStatus is information about the current status of a node.
|
// NodeStatus is information about the current status of a node.
|
||||||
|
@ -699,6 +699,7 @@ func init() {
|
|||||||
|
|
||||||
out.HostIP = in.Status.HostIP
|
out.HostIP = in.Status.HostIP
|
||||||
out.PodCIDR = in.Spec.PodCIDR
|
out.PodCIDR = in.Spec.PodCIDR
|
||||||
|
out.ExternalID = in.Spec.ExternalID
|
||||||
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
|
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
|
||||||
},
|
},
|
||||||
func(in *Minion, out *newer.Node, s conversion.Scope) error {
|
func(in *Minion, out *newer.Node, s conversion.Scope) error {
|
||||||
@ -720,6 +721,7 @@ func init() {
|
|||||||
|
|
||||||
out.Status.HostIP = in.HostIP
|
out.Status.HostIP = in.HostIP
|
||||||
out.Spec.PodCIDR = in.PodCIDR
|
out.Spec.PodCIDR = in.PodCIDR
|
||||||
|
out.Spec.ExternalID = in.ExternalID
|
||||||
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
|
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
|
||||||
},
|
},
|
||||||
func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
|
func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
|
||||||
|
@ -690,6 +690,8 @@ type Minion struct {
|
|||||||
Status NodeStatus `json:"status,omitempty" description:"current status of node"`
|
Status NodeStatus `json:"status,omitempty" description:"current status of node"`
|
||||||
// Labels for the node
|
// 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"`
|
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)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinionList is a list of minions.
|
// MinionList is a list of minions.
|
||||||
|
@ -619,6 +619,7 @@ func init() {
|
|||||||
|
|
||||||
out.HostIP = in.Status.HostIP
|
out.HostIP = in.Status.HostIP
|
||||||
out.PodCIDR = in.Spec.PodCIDR
|
out.PodCIDR = in.Spec.PodCIDR
|
||||||
|
out.ExternalID = in.Spec.ExternalID
|
||||||
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
|
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
|
||||||
},
|
},
|
||||||
func(in *Minion, out *newer.Node, s conversion.Scope) error {
|
func(in *Minion, out *newer.Node, s conversion.Scope) error {
|
||||||
@ -640,6 +641,7 @@ func init() {
|
|||||||
|
|
||||||
out.Status.HostIP = in.HostIP
|
out.Status.HostIP = in.HostIP
|
||||||
out.Spec.PodCIDR = in.PodCIDR
|
out.Spec.PodCIDR = in.PodCIDR
|
||||||
|
out.Spec.ExternalID = in.ExternalID
|
||||||
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
|
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
|
||||||
},
|
},
|
||||||
func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
|
func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
|
||||||
|
@ -654,6 +654,8 @@ type Minion struct {
|
|||||||
Status NodeStatus `json:"status,omitempty" description:"current status of node"`
|
Status NodeStatus `json:"status,omitempty" description:"current status of node"`
|
||||||
// Labels for the node
|
// 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"`
|
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)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinionList is a list of minions.
|
// MinionList is a list of minions.
|
||||||
|
@ -814,6 +814,8 @@ type NodeSpec struct {
|
|||||||
Capacity ResourceList `json:"capacity,omitempty"`
|
Capacity ResourceList `json:"capacity,omitempty"`
|
||||||
// PodCIDR represents the pod IP range assigned to the node
|
// PodCIDR represents the pod IP range assigned to the node
|
||||||
PodCIDR string `json:"cidr,omitempty"`
|
PodCIDR string `json:"cidr,omitempty"`
|
||||||
|
// External ID of the node assigned by some machine database (e.g. a cloud provider)
|
||||||
|
ExternalID string `json:"externalID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeStatus is information about the current status of a node.
|
// NodeStatus is information about the current status of a node.
|
||||||
|
@ -150,6 +150,11 @@ func (aws *AWSCloud) IPAddress(name string) (net.IP, error) {
|
|||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (aws *AWSCloud) ExternalID(name string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
// Return a list of instances matching regex string.
|
// Return a list of instances matching regex string.
|
||||||
func (aws *AWSCloud) getInstancesByRegex(regex string) ([]string, error) {
|
func (aws *AWSCloud) getInstancesByRegex(regex string) ([]string, error) {
|
||||||
resp, err := aws.ec2.Instances(nil, nil)
|
resp, err := aws.ec2.Instances(nil, nil)
|
||||||
|
@ -59,6 +59,8 @@ type TCPLoadBalancer interface {
|
|||||||
type Instances interface {
|
type Instances interface {
|
||||||
// IPAddress returns an IP address of the specified instance.
|
// IPAddress returns an IP address of the specified instance.
|
||||||
IPAddress(name string) (net.IP, error)
|
IPAddress(name string) (net.IP, error)
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
ExternalID(name string) (string, error)
|
||||||
// List lists instances that match 'filter' which is a regular expression which must match the entire instance name (fqdn)
|
// List lists instances that match 'filter' which is a regular expression which must match the entire instance name (fqdn)
|
||||||
List(filter string) ([]string, error)
|
List(filter string) ([]string, error)
|
||||||
// GetNodeResources gets the resources for a particular node
|
// GetNodeResources gets the resources for a particular node
|
||||||
|
@ -231,6 +231,12 @@ func (s *NodeController) PopulateIPs(nodes *api.NodeList) (*api.NodeList, error)
|
|||||||
} else {
|
} else {
|
||||||
node.Status.HostIP = hostIP.String()
|
node.Status.HostIP = hostIP.String()
|
||||||
}
|
}
|
||||||
|
instanceID, err := instances.ExternalID(node.Name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("error getting instance id for %s: %v", node.Name, err)
|
||||||
|
} else {
|
||||||
|
node.Spec.ExternalID = instanceID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for i := range nodes.Items {
|
for i := range nodes.Items {
|
||||||
|
@ -30,6 +30,7 @@ type FakeCloud struct {
|
|||||||
Err error
|
Err error
|
||||||
Calls []string
|
Calls []string
|
||||||
IP net.IP
|
IP net.IP
|
||||||
|
ExtID string
|
||||||
Machines []string
|
Machines []string
|
||||||
NodeResources *api.NodeResources
|
NodeResources *api.NodeResources
|
||||||
ClusterList []string
|
ClusterList []string
|
||||||
@ -110,6 +111,13 @@ func (f *FakeCloud) IPAddress(instance string) (net.IP, error) {
|
|||||||
return f.IP, f.Err
|
return f.IP, f.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID is a test-spy implementation of Instances.ExternalID.
|
||||||
|
// It adds an entry "external-id" into the internal method call record.
|
||||||
|
func (f *FakeCloud) ExternalID(instance string) (string, error) {
|
||||||
|
f.addCall("external-id")
|
||||||
|
return f.ExtID, f.Err
|
||||||
|
}
|
||||||
|
|
||||||
// List is a test-spy implementation of Instances.List.
|
// List is a test-spy implementation of Instances.List.
|
||||||
// It adds an entry "list" into the internal method call record.
|
// It adds an entry "list" into the internal method call record.
|
||||||
func (f *FakeCloud) List(filter string) ([]string, error) {
|
func (f *FakeCloud) List(filter string) ([]string, error) {
|
||||||
|
@ -294,6 +294,11 @@ func (gce *GCECloud) IPAddress(instance string) (net.IP, error) {
|
|||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (gce *GCECloud) ExternalID(instance string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
// fqdnSuffix is hacky function to compute the delta between hostame and hostname -f.
|
// fqdnSuffix is hacky function to compute the delta between hostame and hostname -f.
|
||||||
func fqdnSuffix() (string, error) {
|
func fqdnSuffix() (string, error) {
|
||||||
fullHostname, err := exec.Command("hostname", "-f").Output()
|
fullHostname, err := exec.Command("hostname", "-f").Output()
|
||||||
|
@ -312,6 +312,11 @@ func (i *Instances) IPAddress(name string) (net.IP, error) {
|
|||||||
return net.ParseIP(ip), err
|
return net.ParseIP(ip), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (i *Instances) ExternalID(name string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
|
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
|
||||||
glog.V(2).Infof("GetNodeResources(%v) called", name)
|
glog.V(2).Infof("GetNodeResources(%v) called", name)
|
||||||
|
|
||||||
|
@ -153,6 +153,11 @@ func (v *OVirtCloud) IPAddress(name string) (net.IP, error) {
|
|||||||
return address, nil
|
return address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (v *OVirtCloud) ExternalID(name string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) {
|
func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) {
|
||||||
if body == nil {
|
if body == nil {
|
||||||
return nil, fmt.Errorf("ovirt rest-api response body is missing")
|
return nil, fmt.Errorf("ovirt rest-api response body is missing")
|
||||||
|
@ -363,6 +363,11 @@ func (i *Instances) IPAddress(name string) (net.IP, error) {
|
|||||||
return net.ParseIP(ip), err
|
return net.ParseIP(ip), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (i *Instances) ExternalID(name string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
|
func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) {
|
||||||
glog.V(2).Infof("GetNodeResources(%v) called", name)
|
glog.V(2).Infof("GetNodeResources(%v) called", name)
|
||||||
|
|
||||||
|
@ -119,6 +119,11 @@ func (v *VagrantCloud) IPAddress(instance string) (net.IP, error) {
|
|||||||
return nil, fmt.Errorf("unable to find IP address for instance: %s", instance)
|
return nil, fmt.Errorf("unable to find IP address for instance: %s", instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExternalID returns the cloud provider ID of the specified instance.
|
||||||
|
func (v *VagrantCloud) ExternalID(instance string) (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
// saltMinionsByRole filters a list of minions that have a matching role.
|
// saltMinionsByRole filters a list of minions that have a matching role.
|
||||||
func (v *VagrantCloud) saltMinionsByRole(minions []SaltMinion, role string) []SaltMinion {
|
func (v *VagrantCloud) saltMinionsByRole(minions []SaltMinion, role string) []SaltMinion {
|
||||||
var filteredMinions []SaltMinion
|
var filteredMinions []SaltMinion
|
||||||
|
Loading…
Reference in New Issue
Block a user