From c5fada6e69f606f257c37eb8b2e85b83b279e259 Mon Sep 17 00:00:00 2001 From: Kiril Vladimirov Date: Thu, 23 Oct 2014 13:21:49 +0300 Subject: [PATCH 1/3] fix(datasource/CloudSigma): Populate public IPv4 address properly --- .../metadata/cloudsigma/server_context.go | 20 +++++----- .../cloudsigma/server_context_test.go | 37 ++++++++++++++++--- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index 5d28900..b11bd96 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -73,12 +73,13 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { UUID string `json:"uuid"` Meta map[string]string `json:"meta"` Nics []struct { - Runtime struct { + Mac string `json:"mac"` + IPv4Conf struct { InterfaceType string `json:"interface_type"` - IPv4 struct { - IP string `json:"uuid"` - } `json:"ip_v4"` - } `json:"runtime"` + IP struct { + UUID string `json:"uuid"` + } `json:"ip"` + } `json:"ip_v4_conf"` } `json:"nics"` } outputMetadata struct { @@ -112,12 +113,9 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { } for _, nic := range inputMetadata.Nics { - if nic.Runtime.IPv4.IP != "" { - if nic.Runtime.InterfaceType == "public" { - outputMetadata.PublicIPv4 = nic.Runtime.IPv4.IP - } else { - outputMetadata.LocalIPv4 = nic.Runtime.IPv4.IP - } + if nic.IPv4Conf.IP.UUID != "" { + outputMetadata.PublicIPv4 = nic.IPv4Conf.IP.UUID + break } } diff --git a/datasource/metadata/cloudsigma/server_context_test.go b/datasource/metadata/cloudsigma/server_context_test.go index ef4073d..9c6f6d8 100644 --- a/datasource/metadata/cloudsigma/server_context_test.go +++ b/datasource/metadata/cloudsigma/server_context_test.go @@ -74,14 +74,41 @@ func TestServerContextFetchMetadata(t *testing.T) { "name": "coreos", "nics": [ { - "runtime": { - "interface_type": "public", - "ip_v4": { + "boot_order": null, + "ip_v4_conf": { + "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" - }, - "ip_v6": null + } }, + "ip_v6_conf": null, + "mac": "22:3d:09:6b:90:f3", + "model": "virtio", "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, From b6062f064431394a745441d0d9ef0c2f43eb6037 Mon Sep 17 00:00:00 2001 From: Kiril Vladimirov Date: Thu, 23 Oct 2014 14:12:09 +0300 Subject: [PATCH 2/3] fix(datasource/CloudSigma): Populate local IPv4 address properly --- .../metadata/cloudsigma/server_context.go | 42 ++++++++++++++++++- .../cloudsigma/server_context_test.go | 6 +-- 2 files changed, 42 insertions(+), 6 deletions(-) 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) } } From ea95920f313fc4e02800672d6b22ec9089188c4b Mon Sep 17 00:00:00 2001 From: Kiril Vladimirov Date: Mon, 17 Nov 2014 15:27:26 +0200 Subject: [PATCH 3/3] fix(datasource/CloudSigma): Make sure DHCP has run --- datasource/metadata/cloudsigma/server_context.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index 95623f0..b6fc4d2 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -21,6 +21,7 @@ import ( "encoding/base64" "encoding/json" "errors" + "io/ioutil" "net" "os" "strings" @@ -54,7 +55,8 @@ func (_ *serverContextService) IsAvailable() bool { } productName := make([]byte, 10) _, err = productNameFile.Read(productName) - return err == nil && string(productName) == "CloudSigma" + + return err == nil && string(productName) == "CloudSigma" && hasDHCPLeases() } func (_ *serverContextService) AvailabilityChanges() bool { @@ -85,7 +87,7 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { } `json:"ip_v4_conf"` VLAN struct { UUID string `json:"uuid"` - } `json: "vlan"` + } `json:"vlan"` } `json:"nics"` } outputMetadata struct { @@ -197,3 +199,8 @@ func isBase64Encoded(field string, userdata map[string]string) bool { } return false } + +func hasDHCPLeases() bool { + files, err := ioutil.ReadDir("/run/systemd/netif/leases/") + return err == nil && len(files) > 0 +}