ovirt: fetch instance ip address from rest-api

This patch adds the support for returning the ip address of the instances
when reported by the guest-agent and from the rest-api.

Signed-off-by: Federico Simoncelli <fsimonce@redhat.com>
This commit is contained in:
Federico Simoncelli
2015-02-12 14:51:45 +00:00
parent 7d44201a0b
commit 8844c06574
2 changed files with 87 additions and 14 deletions

View File

@@ -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
}

View File

@@ -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)
}
}