Skip to content

Commit

Permalink
Implement InstanceExistsByProviderID() for cloud providers
Browse files Browse the repository at this point in the history
Fix kubernetes#51406
If cloud providers(like aws, gce etc...) implement ExternalID()
and support getting instance by ProviderID , they also implement
InstanceExistsByProviderID(). InstanceExistsByProviderID() just
check whether instance exists.
  • Loading branch information
FengyunPan committed Sep 5, 2017
1 parent 870406b commit 691d0fc
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 22 deletions.
21 changes: 19 additions & 2 deletions pkg/cloudprovider/providers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -1144,10 +1144,27 @@ func (c *Cloud) ExternalID(nodeName types.NodeName) (string, error) {
return aws.StringValue(instance.InstanceId), nil
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (c *Cloud) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
if err != nil {
return false, err
}

request := &ec2.DescribeInstancesInput{
InstanceIds: []*string{instanceID.awsString()},
}

instances, err := c.ec2.DescribeInstances(request)
if err != nil {
return false, err
}
if len(instances) == 0 {
return false, nil
}

return true, nil
}

// InstanceID returns the cloud provider ID of the node with the specified nodeName.
Expand Down
18 changes: 15 additions & 3 deletions pkg/cloudprovider/providers/azure/azure_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package azure

import (
"errors"
"fmt"

"k8s.io/api/core/v1"
Expand Down Expand Up @@ -87,10 +86,23 @@ func (az *Cloud) ExternalID(name types.NodeName) (string, error) {
return az.InstanceID(name)
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (az *Cloud) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
name, err := splitProviderID(providerID)
if err != nil {
return false, err
}

_, err = az.InstanceID(name)
if err != nil {
if err == cloudprovider.InstanceNotFound {
return false, nil
}
return false, err
}

return true, nil
}

func (az *Cloud) isCurrentInstance(name types.NodeName) (bool, error) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloudprovider/providers/fake/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (f *FakeCloud) InstanceTypeByProviderID(providerID string) (string, error)
return f.InstanceTypes[types.NodeName(providerID)], nil
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (f *FakeCloud) InstanceExistsByProviderID(providerID string) (bool, error) {
f.addCall("instance-exists-by-provider-id")
Expand Down
39 changes: 31 additions & 8 deletions pkg/cloudprovider/providers/gce/gce_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package gce

import (
"errors"
"fmt"
"net"
"net/http"
Expand Down Expand Up @@ -117,19 +116,35 @@ func (gce *GCECloud) NodeAddressesByProviderID(providerID string) ([]v1.NodeAddr
return nodeAddresses, nil
}

// instanceByProviderID returns the cloudprovider instance of the node
// with the specified unique providerID
func (gce *GCECloud) instanceByProviderID(providerID string) (*gceInstance, error) {
project, zone, name, err := splitProviderID(providerID)
if err != nil {
return nil, err
}

instance, err := gce.getInstanceFromProjectInZoneByName(project, zone, name)
if err != nil {
if isHTTPErrorCode(err, http.StatusNotFound) {
return nil, cloudprovider.InstanceNotFound
}
return nil, err
}

return instance, nil
}

// InstanceTypeByProviderID returns the cloudprovider instance type of the node
// with the specified unique providerID This method will not be called from the
// node that is requesting this ID. i.e. metadata service and other local
// methods cannot be used here
func (gce *GCECloud) InstanceTypeByProviderID(providerID string) (string, error) {
project, zone, name, err := splitProviderID(providerID)
if err != nil {
return "", err
}
instance, err := gce.getInstanceFromProjectInZoneByName(project, zone, name)
instance, err := gce.instanceByProviderID(providerID)
if err != nil {
return "", err
}

return instance.Type, nil
}

Expand All @@ -154,10 +169,18 @@ func (gce *GCECloud) ExternalID(nodeName types.NodeName) (string, error) {
return strconv.FormatUint(inst.ID, 10), nil
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (gce *GCECloud) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
_, err := gce.instanceByProviderID(providerID)
if err != nil {
if err == cloudprovider.InstanceNotFound {
return false, nil
}
return false, err
}

return true, nil
}

// InstanceID returns the cloud provider ID of the node with the specified NodeName.
Expand Down
17 changes: 15 additions & 2 deletions pkg/cloudprovider/providers/openstack/openstack_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,23 @@ func (i *Instances) ExternalID(name types.NodeName) (string, error) {
return srv.ID, nil
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (i *Instances) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
instanceID, err := instanceIDFromProviderID(providerID)
if err != nil {
return false, err
}

_, err = servers.Get(i.compute, instanceID).Extract()
if err != nil {
if isNotFound(err) {
return false, nil
}
return false, err
}

return true, nil
}

// InstanceID returns the kubelet's cloud provider ID.
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloudprovider/providers/ovirt/ovirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (v *OVirtCloud) ExternalID(nodeName types.NodeName) (string, error) {
return instance.UUID, nil
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (v *OVirtCloud) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloudprovider/providers/photon/photon.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ func (pc *PCCloud) ExternalID(nodeName k8stypes.NodeName) (string, error) {
}
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (pc *PCCloud) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
Expand Down
15 changes: 13 additions & 2 deletions pkg/cloudprovider/providers/rackspace/rackspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,21 @@ func (i *Instances) ExternalID(nodeName types.NodeName) (string, error) {
return probeInstanceID(i.compute, serverName)
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (i *Instances) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
instanceID, err := instanceIDFromProviderID(providerID)
if err != nil {
return false, err
}

_, err = servers.Get(i.compute, instanceID).Extract()
if err != nil {
// TODO: check whether instance is not found
return false, err
}

return true, nil
}

// InstanceID returns the cloud provider ID of the kubelet's instance.
Expand Down
22 changes: 20 additions & 2 deletions pkg/cloudprovider/providers/vsphere/vsphere.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,28 @@ func (vs *VSphere) ExternalID(nodeName k8stypes.NodeName) (string, error) {
return vs.InstanceID(nodeName)
}

// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
func (vs *VSphere) InstanceExistsByProviderID(providerID string) (bool, error) {
return false, errors.New("unimplemented")
vmName := path.Base(providerID)
nodeName := vmNameToNodeName(vmName)
// Create context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Ensure client is logged in and session is valid
err := vs.conn.Connect(ctx)
if err != nil {
return false, err
}
_, err = vs.getVMByName(ctx, nodeName)
if err != nil {
if vclib.IsNotFound(err) {
return false, nil
}
return false, err
}

return true, nil
}

// InstanceID returns the cloud provider ID of the node with the specified Name.
Expand Down

0 comments on commit 691d0fc

Please sign in to comment.