diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index b11bd96..95623f0 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -17,8 +17,11 @@ package cloudsigma import ( + "bytes" "encoding/base64" "encoding/json" + "errors" + "net" "os" "strings" @@ -80,6 +83,9 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { UUID string `json:"uuid"` } `json:"ip"` } `json:"ip_v4_conf"` + VLAN struct { + UUID string `json:"uuid"` + } `json: "vlan"` } `json:"nics"` } outputMetadata struct { @@ -115,7 +121,11 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { for _, nic := range inputMetadata.Nics { if nic.IPv4Conf.IP.UUID != "" { outputMetadata.PublicIPv4 = nic.IPv4Conf.IP.UUID - break + } + if nic.VLAN.UUID != "" { + if localIP, err := scs.findLocalIP(nic.Mac); err == nil { + outputMetadata.LocalIPv4 = localIP + } } } @@ -144,6 +154,36 @@ func (scs *serverContextService) FetchNetworkConfig(a string) ([]byte, error) { 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 { base64Fields, ok := userdata["base64_fields"] if !ok { diff --git a/datasource/metadata/cloudsigma/server_context_test.go b/datasource/metadata/cloudsigma/server_context_test.go index 9c6f6d8..815ba1a 100644 --- a/datasource/metadata/cloudsigma/server_context_test.go +++ b/datasource/metadata/cloudsigma/server_context_test.go @@ -133,12 +133,8 @@ func TestServerContextFetchMetadata(t *testing.T) { 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" { - 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) } }