Merge pull request #251 from Vladimiroff/master

metadata: Populate CloudSigma's IPs properly
This commit is contained in:
Alex Crawford 2014-12-01 14:52:11 -08:00
commit d0d467813d
2 changed files with 89 additions and 21 deletions

View File

@ -17,8 +17,12 @@
package cloudsigma package cloudsigma
import ( import (
"bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors"
"io/ioutil"
"net"
"os" "os"
"strings" "strings"
@ -51,7 +55,8 @@ func (_ *serverContextService) IsAvailable() bool {
} }
productName := make([]byte, 10) productName := make([]byte, 10)
_, err = productNameFile.Read(productName) _, err = productNameFile.Read(productName)
return err == nil && string(productName) == "CloudSigma"
return err == nil && string(productName) == "CloudSigma" && hasDHCPLeases()
} }
func (_ *serverContextService) AvailabilityChanges() bool { func (_ *serverContextService) AvailabilityChanges() bool {
@ -73,12 +78,16 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) {
UUID string `json:"uuid"` UUID string `json:"uuid"`
Meta map[string]string `json:"meta"` Meta map[string]string `json:"meta"`
Nics []struct { Nics []struct {
Runtime struct { Mac string `json:"mac"`
IPv4Conf struct {
InterfaceType string `json:"interface_type"` InterfaceType string `json:"interface_type"`
IPv4 struct { IP struct {
IP string `json:"uuid"` UUID string `json:"uuid"`
} `json:"ip_v4"` } `json:"ip"`
} `json:"runtime"` } `json:"ip_v4_conf"`
VLAN struct {
UUID string `json:"uuid"`
} `json:"vlan"`
} `json:"nics"` } `json:"nics"`
} }
outputMetadata struct { outputMetadata struct {
@ -112,11 +121,12 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) {
} }
for _, nic := range inputMetadata.Nics { for _, nic := range inputMetadata.Nics {
if nic.Runtime.IPv4.IP != "" { if nic.IPv4Conf.IP.UUID != "" {
if nic.Runtime.InterfaceType == "public" { outputMetadata.PublicIPv4 = nic.IPv4Conf.IP.UUID
outputMetadata.PublicIPv4 = nic.Runtime.IPv4.IP }
} else { if nic.VLAN.UUID != "" {
outputMetadata.LocalIPv4 = nic.Runtime.IPv4.IP if localIP, err := scs.findLocalIP(nic.Mac); err == nil {
outputMetadata.LocalIPv4 = localIP
} }
} }
} }
@ -146,6 +156,36 @@ func (scs *serverContextService) FetchNetworkConfig(a string) ([]byte, error) {
return nil, nil return nil, nil
} }
func (scs *serverContextService) findLocalIP(mac string) (string, error) {
ifaces, err := net.Interfaces()
if err != nil {
return "", err
}
ifaceMac, err := net.ParseMAC(mac)
if err != nil {
return "", err
}
for _, iface := range ifaces {
if !bytes.Equal(iface.HardwareAddr, ifaceMac) {
continue
}
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
switch ip := addr.(type) {
case *net.IPNet:
if ip.IP.To4() != nil {
return ip.IP.To4().String(), nil
}
}
}
}
return "", errors.New("Local IP not found")
}
func isBase64Encoded(field string, userdata map[string]string) bool { func isBase64Encoded(field string, userdata map[string]string) bool {
base64Fields, ok := userdata["base64_fields"] base64Fields, ok := userdata["base64_fields"]
if !ok { if !ok {
@ -159,3 +199,8 @@ func isBase64Encoded(field string, userdata map[string]string) bool {
} }
return false return false
} }
func hasDHCPLeases() bool {
files, err := ioutil.ReadDir("/run/systemd/netif/leases/")
return err == nil && len(files) > 0
}

View File

@ -74,14 +74,41 @@ func TestServerContextFetchMetadata(t *testing.T) {
"name": "coreos", "name": "coreos",
"nics": [ "nics": [
{ {
"runtime": { "boot_order": null,
"interface_type": "public", "ip_v4_conf": {
"ip_v4": { "conf": "dhcp",
"ip": {
"gateway": "31.171.244.1",
"meta": {},
"nameservers": [
"178.22.66.167",
"178.22.71.56",
"8.8.8.8"
],
"netmask": 22,
"tags": [],
"uuid": "31.171.251.74" "uuid": "31.171.251.74"
}, }
"ip_v6": null
}, },
"ip_v6_conf": null,
"mac": "22:3d:09:6b:90:f3",
"model": "virtio",
"vlan": null "vlan": null
},
{
"boot_order": null,
"ip_v4_conf": null,
"ip_v6_conf": null,
"mac": "22:ae:4a:fb:8f:31",
"model": "virtio",
"vlan": {
"meta": {
"description": "",
"name": "CoreOS"
},
"tags": [],
"uuid": "5dec030e-25b8-4621-a5a4-a3302c9d9619"
}
} }
], ],
"smp": 2, "smp": 2,
@ -106,12 +133,8 @@ func TestServerContextFetchMetadata(t *testing.T) {
t.Error("Public SSH Keys are not being read properly") t.Error("Public SSH Keys are not being read properly")
} }
if metadata.LocalIPv4 != "" {
t.Errorf("Local IP is not empty but %s instead", metadata.LocalIPv4)
}
if metadata.PublicIPv4 != "31.171.251.74" { if metadata.PublicIPv4 != "31.171.251.74" {
t.Errorf("Local IP is not 31.171.251.74 but %s instead", metadata.PublicIPv4) t.Errorf("Public IP is not 31.171.251.74 but %s instead", metadata.PublicIPv4)
} }
} }