diff --git a/pkg/cloudprovider/ovirt/ovirt.go b/pkg/cloudprovider/ovirt/ovirt.go index 187da1eddfe..1b3e959f2f7 100644 --- a/pkg/cloudprovider/ovirt/ovirt.go +++ b/pkg/cloudprovider/ovirt/ovirt.go @@ -25,6 +25,7 @@ import ( "net/http" "net/url" "path" + "sort" "strings" "code.google.com/p/gcfg" @@ -32,6 +33,13 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" ) +type OVirtInstance struct { + Name string + IPAddress string +} + +type OVirtInstanceMap map[string]OVirtInstance + type OVirtCloud struct { VmsRequest *url.URL HostsRequest *url.URL @@ -48,9 +56,15 @@ type OVirtApiConfig struct { } } +type XmlVmAddress struct { + Address string `xml:"address,attr"` +} + type XmlVmInfo struct { - Hostname string `xml:"guest_info>fqdn"` - State string `xml:"status>state"` + Name string `xml:"name"` + Hostname string `xml:"guest_info>fqdn"` + Addresses []XmlVmAddress `xml:"guest_info>ips>ip"` + State string `xml:"status>state"` } type XmlVmsList struct { @@ -115,16 +129,31 @@ func (v *OVirtCloud) Zones() (cloudprovider.Zones, bool) { } // IPAddress returns the address of a particular machine instance -func (v *OVirtCloud) IPAddress(instance string) (net.IP, error) { - // since the instance now is the IP in the ovirt env, this is trivial no-op - ip, err := net.LookupIP(instance) - if err != nil || len(ip) < 1 { - return nil, fmt.Errorf("cannot find ip address for: %s", instance) +func (v *OVirtCloud) IPAddress(name string) (net.IP, error) { + instance, err := v.fetchInstance(name) + if err != nil { + return nil, err } - return ip[0], nil + + var address net.IP + + if instance.IPAddress != "" { + address = net.ParseIP(instance.IPAddress) + if address == nil { + return nil, fmt.Errorf("couldn't parse address: %s", instance.IPAddress) + } + } else { + resolved, err := net.LookupIP(name) + if err != nil || len(resolved) < 1 { + return nil, fmt.Errorf("couldn't lookup address: %s", name) + } + address = resolved[0] + } + + return address, nil } -func getInstancesFromXml(body io.Reader) ([]string, error) { +func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) { if body == nil { return nil, fmt.Errorf("ovirt rest-api response body is missing") } @@ -140,20 +169,27 @@ func getInstancesFromXml(body io.Reader) ([]string, error) { return nil, err } - var instances []string + instances := make(OVirtInstanceMap) for _, vm := range vmlist.Vm { // Always return only vms that are up and running if vm.Hostname != "" && strings.ToLower(vm.State) == "up" { - instances = append(instances, vm.Hostname) + address := "" + if len(vm.Addresses) > 0 { + address = vm.Addresses[0].Address + } + + instances[vm.Hostname] = OVirtInstance{ + Name: vm.Name, + IPAddress: address, + } } } return instances, nil } -// List enumerates the set of minions instances known by the cloud provider -func (v *OVirtCloud) List(filter string) ([]string, error) { +func (v *OVirtCloud) fetchAllInstances() (OVirtInstanceMap, error) { response, err := http.Get(v.VmsRequest.String()) if err != nil { return nil, err @@ -164,6 +200,41 @@ func (v *OVirtCloud) List(filter string) ([]string, error) { return getInstancesFromXml(response.Body) } +func (v *OVirtCloud) fetchInstance(name string) (*OVirtInstance, error) { + allInstances, err := v.fetchAllInstances() + if err != nil { + return nil, err + } + + instance, found := allInstances[name] + if !found { + return nil, fmt.Errorf("cannot find instance: %s", name) + } + + return &instance, nil +} + +func (m *OVirtInstanceMap) ListSortedNames() []string { + var names []string + + for k := range *m { + names = append(names, k) + } + + sort.Strings(names) + + return names +} + +// List enumerates the set of minions instances known by the cloud provider +func (v *OVirtCloud) List(filter string) ([]string, error) { + instances, err := v.fetchAllInstances() + if err != nil { + return nil, err + } + return instances.ListSortedNames(), nil +} + func (v *OVirtCloud) GetNodeResources(name string) (*api.NodeResources, error) { return nil, nil } diff --git a/pkg/cloudprovider/ovirt/ovirt_test.go b/pkg/cloudprovider/ovirt/ovirt_test.go index 6f79cf01703..afeb45c4a9a 100644 --- a/pkg/cloudprovider/ovirt/ovirt_test.go +++ b/pkg/cloudprovider/ovirt/ovirt_test.go @@ -118,7 +118,9 @@ func TestOVirtCloudXmlParsing(t *testing.T) { if len(instances4) != 2 { t.Fatalf("Unexpected number of instance(s): %d", len(instances4)) } - if instances4[0] != "host1" || instances4[1] != "host3" { + + names := instances4.ListSortedNames() + if names[0] != "host1" || names[1] != "host3" { t.Fatalf("Unexpected instance(s): %s", instances4) } }