diff --git a/pkg/cloudprovider/providers/openstack/openstack_instances.go b/pkg/cloudprovider/providers/openstack/openstack_instances.go index fd94eacfbc..d75024c39e 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_instances.go +++ b/pkg/cloudprovider/providers/openstack/openstack_instances.go @@ -18,6 +18,8 @@ package openstack import ( "errors" + "fmt" + "net/url" "github.com/golang/glog" "github.com/gophercloud/gophercloud" @@ -107,7 +109,24 @@ func (i *Instances) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) // 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 (i *Instances) NodeAddressesByProviderID(providerID string) ([]v1.NodeAddress, error) { - return []v1.NodeAddress{}, errors.New("unimplemented") + instanceID, err := instanceIDFromProviderID(providerID) + + if err != nil { + return []v1.NodeAddress{}, err + } + + server, err := servers.Get(i.compute, instanceID).Extract() + + if err != nil { + return []v1.NodeAddress{}, err + } + + addresses, err := nodeAddresses(server) + if err != nil { + return []v1.NodeAddress{}, err + } + + return addresses, nil } // ExternalID returns the cloud provider ID of the specified instance (deprecated). @@ -142,10 +161,56 @@ func (i *Instances) InstanceID(name types.NodeName) (string, error) { // 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 (i *Instances) InstanceTypeByProviderID(providerID string) (string, error) { - return "", errors.New("unimplemented") + instanceID, err := instanceIDFromProviderID(providerID) + + if err != nil { + return "", err + } + + server, err := servers.Get(i.compute, instanceID).Extract() + + if err != nil { + return "", err + } + + return srvInstanceType(server) } // InstanceType returns the type of the specified instance. func (i *Instances) InstanceType(name types.NodeName) (string, error) { - return "", nil + srv, err := getServerByName(i.compute, name) + + if err != nil { + return "", err + } + + return srvInstanceType(srv) +} + +func srvInstanceType(srv *servers.Server) (string, error) { + val, ok := srv.Flavor["name"] + + if !ok { + return "", fmt.Errorf("flavor name not present in server info") + } + + flavor, ok := val.(string) + + if !ok { + return "", fmt.Errorf("flavor name is not a string") + } + + return flavor, nil +} + +func instanceIDFromProviderID(providerID string) (instanceID string, err error) { + parsedID, err := url.Parse(providerID) + if err != nil { + return "", err + } + if parsedID.Scheme != ProviderName { + return "", fmt.Errorf("unrecognized provider %q", parsedID.Scheme) + } + + return parsedID.Host, nil } diff --git a/pkg/cloudprovider/providers/openstack/openstack_test.go b/pkg/cloudprovider/providers/openstack/openstack_test.go index d69d53e919..1471cb262e 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_test.go +++ b/pkg/cloudprovider/providers/openstack/openstack_test.go @@ -18,9 +18,6 @@ package openstack import ( "fmt" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "os" "reflect" "sort" @@ -28,7 +25,11 @@ import ( "testing" "time" + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions" + "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/rand" "k8s.io/apimachinery/pkg/util/wait" @@ -543,3 +544,42 @@ func TestCinderAutoDetectApiVersion(t *testing.T) { } } } + +func TestInstanceIDFromProviderID(t *testing.T) { + testCases := []struct { + providerID string + instanceID string + fail bool + }{ + { + providerID: "openstack://7b9cf879-7146-417c-abfd-cb4272f0c935", + instanceID: "7b9cf879-7146-417c-abfd-cb4272f0c935", + fail: false, + }, + { + providerID: "7b9cf879-7146-417c-abfd-cb4272f0c935", + instanceID: "", + fail: true, + }, + { + providerID: "other-provider://7b9cf879-7146-417c-abfd-cb4272f0c935", + instanceID: "", + fail: true, + }, + } + + for _, test := range testCases { + instanceID, err := instanceIDFromProviderID(test.providerID) + if (err != nil) != test.fail { + t.Errorf("%s yielded `err != nil` as %t. expected %t", test.providerID, (err != nil), test.fail) + } + + if test.fail { + continue + } + + if instanceID != test.instanceID { + t.Errorf("%s yielded %s. expected %s", test.providerID, instanceID, test.instanceID) + } + } +}