summaryrefslogtreecommitdiff
path: root/libvirt/qemu_agent.go
diff options
context:
space:
mode:
authorFlavio Castelli <fcastelli@suse.com>2016-07-04 19:03:45 +0200
committerFlavio Castelli <fcastelli@suse.com>2016-07-20 13:11:13 +0200
commitc5661d890f83f2e118f89867a0edf73dc1da282e (patch)
treefd1e488f769a2c01a318e75ff542216b9f43df3a /libvirt/qemu_agent.go
parent0cc42cc992323bcd42db36536227d8616dca3189 (diff)
downloadterraform-provider-libvirt-c5661d890f83f2e118f89867a0edf73dc1da282e.tar
terraform-provider-libvirt-c5661d890f83f2e118f89867a0edf73dc1da282e.tar.gz
Discover IP address of the network cards attached to a LAN
When a network card is attached to a LAN the `domain.ListAllInterfaceAddresses` API cannot be used to get the IP address associated with the interfaces. The only solution to this problem is to use the [Qemu guest agent](http://wiki.libvirt.org/page/Qemu_guest_agent) to fetch this information. This PR will take advantage of the qemu guest ageint (when installed inside of the domain) to workaround the limitations of the `domain.ListAllInterfaceAddresses`. In theory this PR could also allow to relax the required version of libvirt. Signed-off-by: Flavio Castelli <fcastelli@suse.com>
Diffstat (limited to 'libvirt/qemu_agent.go')
-rw-r--r--libvirt/qemu_agent.go90
1 files changed, 90 insertions, 0 deletions
diff --git a/libvirt/qemu_agent.go b/libvirt/qemu_agent.go
new file mode 100644
index 00000000..10bf45cc
--- /dev/null
+++ b/libvirt/qemu_agent.go
@@ -0,0 +1,90 @@
+package libvirt
+
+import (
+ "encoding/json"
+ "log"
+ "strings"
+
+ libvirt "github.com/dmacvicar/libvirt-go"
+)
+
+type QemuAgentInterfacesResponse struct {
+ Interfaces []QemuAgentInterface `json:"return"`
+}
+
+type QemuAgentInterface struct {
+ Name string `json:"name"`
+ Hwaddr string `json:"hardware-address"`
+ IpAddresses []struct {
+ Type string `json:"ip-address-type"`
+ Address string `json:"ip-address"`
+ Prefix uint `json:"prefix"`
+ } `json:"ip-addresses"`
+}
+
+// Retrieve all the interfaces attached to a domain and their addresses. Only
+// the interfaces with at least an IP address are returned.
+// When wait4ipv4 is turned on the code will not report interfaces that don't
+// have a ipv4 address set. This is useful when a domain gets the ipv6 address
+// before the ipv4 one.
+func getDomainInterfacesViaQemuAgent(domain *libvirt.VirDomain, wait4ipv4 bool) []libvirt.VirDomainInterface {
+ log.Print("[DEBUG] get network interfaces using qemu agent")
+
+ var interfaces []libvirt.VirDomainInterface
+
+ result := domain.QemuAgentCommand(
+ "{\"execute\":\"guest-network-get-interfaces\"}",
+ libvirt.VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT,
+ 0)
+
+ log.Printf("[DEBUG] qemu-agent response: %s", result)
+
+ response := QemuAgentInterfacesResponse{}
+ if err := json.Unmarshal([]byte(result), &response); err != nil {
+ log.Printf("[DEBUG] Error converting Qemu agent response about domain interfaces: %s", err)
+ log.Printf("[DEBUG] Original message: %s", response)
+ log.Print("[DEBUG] Returning an empty list of interfaces")
+ return interfaces
+ }
+ log.Printf("[DEBUG] Parsed response %+v", response)
+
+ for _, iface := range response.Interfaces {
+ if iface.Name == "lo" {
+ // ignore loopback interface
+ continue
+ }
+
+ libVirtIface := libvirt.VirDomainInterface{}
+ libVirtIface.Name = iface.Name
+ libVirtIface.Hwaddr = iface.Hwaddr
+
+ ipv4Assigned := false
+ for _, addr := range iface.IpAddresses {
+ if addr.Address == "" {
+ // ignore interfaces without an address (eg. waiting for dhcp lease)
+ continue
+ }
+
+ libVirtAddr := libvirt.VirDomainIPAddress{}
+ libVirtAddr.Addr = addr.Address
+ libVirtAddr.Prefix = addr.Prefix
+ switch strings.ToLower(addr.Type) {
+ case "ipv4":
+ libVirtAddr.Type = libvirt.VIR_IP_ADDR_TYPE_IPV4
+ ipv4Assigned = true
+ case "ipv6":
+ libVirtAddr.Type = libvirt.VIR_IP_ADDR_TYPE_IPV6
+ default:
+ log.Printf("[ERROR] Cannot handle unknown address type %s", addr.Type)
+ }
+ libVirtIface.Addrs = append(libVirtIface.Addrs, libVirtAddr)
+ }
+ if len(libVirtIface.Addrs) > 0 && (ipv4Assigned || !wait4ipv4) {
+ interfaces = append(interfaces, libVirtIface)
+ }
+ }
+
+ log.Printf("[DEBUG] Interfaces obtained via qemu Agent: %+v", interfaces)
+
+ return interfaces
+}