github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/client/fingerprint/env_gce_test.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/nomad/client/config"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  )
    14  
    15  func TestGCEFingerprint_nonGCE(t *testing.T) {
    16  	os.Setenv("GCE_ENV_URL", "http://127.0.0.1/computeMetadata/v1/instance/")
    17  	f := NewEnvGCEFingerprint(testLogger())
    18  	node := &structs.Node{
    19  		Attributes: make(map[string]string),
    20  	}
    21  
    22  	ok, err := f.Fingerprint(&config.Config{}, node)
    23  	if err != nil {
    24  		t.Fatalf("err: %v", err)
    25  	}
    26  
    27  	if ok {
    28  		t.Fatalf("Should be false without test server")
    29  	}
    30  }
    31  
    32  func testFingerprint_GCE(t *testing.T, withExternalIp bool) {
    33  	node := &structs.Node{
    34  		Attributes: make(map[string]string),
    35  	}
    36  
    37  	// configure mock server with fixture routes, data
    38  	routes := routes{}
    39  	if err := json.Unmarshal([]byte(GCE_routes), &routes); err != nil {
    40  		t.Fatalf("Failed to unmarshal JSON in GCE ENV test: %s", err)
    41  	}
    42  	networkEndpoint := &endpoint{
    43  		Uri:         "/computeMetadata/v1/instance/network-interfaces/?recursive=true",
    44  		ContentType: "application/json",
    45  	}
    46  	if withExternalIp {
    47  		networkEndpoint.Body = `[{"accessConfigs":[{"externalIp":"104.44.55.66","type":"ONE_TO_ONE_NAT"},{"externalIp":"104.44.55.67","type":"ONE_TO_ONE_NAT"}],"forwardedIps":[],"ip":"10.240.0.5","network":"projects/555555/networks/default"}]`
    48  	} else {
    49  		networkEndpoint.Body = `[{"accessConfigs":[],"forwardedIps":[],"ip":"10.240.0.5","network":"projects/555555/networks/default"}]`
    50  	}
    51  	routes.Endpoints = append(routes.Endpoints, networkEndpoint)
    52  
    53  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    54  		value, ok := r.Header["Metadata-Flavor"]
    55  		if !ok {
    56  			t.Fatal("Metadata-Flavor not present in HTTP request header")
    57  		}
    58  		if value[0] != "Google" {
    59  			t.Fatalf("Expected Metadata-Flavor Google, saw %s", value[0])
    60  		}
    61  
    62  		found := false
    63  		for _, e := range routes.Endpoints {
    64  			if r.RequestURI == e.Uri {
    65  				w.Header().Set("Content-Type", e.ContentType)
    66  				fmt.Fprintln(w, e.Body)
    67  			}
    68  			found = true
    69  		}
    70  
    71  		if !found {
    72  			w.WriteHeader(404)
    73  		}
    74  	}))
    75  	defer ts.Close()
    76  	os.Setenv("GCE_ENV_URL", ts.URL+"/computeMetadata/v1/instance/")
    77  	f := NewEnvGCEFingerprint(testLogger())
    78  
    79  	ok, err := f.Fingerprint(&config.Config{}, node)
    80  	if err != nil {
    81  		t.Fatalf("err: %v", err)
    82  	}
    83  
    84  	if !ok {
    85  		t.Fatalf("should apply")
    86  	}
    87  
    88  	keys := []string{
    89  		"platform.gce.id",
    90  		"platform.gce.hostname",
    91  		"platform.gce.zone",
    92  		"platform.gce.machine-type",
    93  		"platform.gce.zone",
    94  		"platform.gce.tag.abc",
    95  		"platform.gce.tag.def",
    96  		"platform.gce.attr.ghi",
    97  		"platform.gce.attr.jkl",
    98  	}
    99  
   100  	for _, k := range keys {
   101  		assertNodeAttributeContains(t, node, k)
   102  	}
   103  
   104  	if len(node.Links) == 0 {
   105  		t.Fatalf("Empty links for Node in GCE Fingerprint test")
   106  	}
   107  
   108  	// Make sure Links contains the GCE ID.
   109  	for _, k := range []string{"gce"} {
   110  		assertNodeLinksContains(t, node, k)
   111  	}
   112  
   113  	assertNodeAttributeEquals(t, node, "platform.gce.id", "12345")
   114  	assertNodeAttributeEquals(t, node, "platform.gce.hostname", "instance-1.c.project.internal")
   115  	assertNodeAttributeEquals(t, node, "platform.gce.zone", "us-central1-f")
   116  	assertNodeAttributeEquals(t, node, "platform.gce.machine-type", "n1-standard-1")
   117  	assertNodeAttributeEquals(t, node, "platform.gce.network.default", "true")
   118  	assertNodeAttributeEquals(t, node, "platform.gce.network.default.ip", "10.240.0.5")
   119  	if withExternalIp {
   120  		assertNodeAttributeEquals(t, node, "platform.gce.network.default.external-ip.0", "104.44.55.66")
   121  		assertNodeAttributeEquals(t, node, "platform.gce.network.default.external-ip.1", "104.44.55.67")
   122  	} else if _, ok := node.Attributes["platform.gce.network.default.external-ip.0"]; ok {
   123  		t.Fatal("platform.gce.network.default.external-ip is set without an external IP")
   124  	}
   125  
   126  	assertNodeAttributeEquals(t, node, "platform.gce.scheduling.automatic-restart", "TRUE")
   127  	assertNodeAttributeEquals(t, node, "platform.gce.scheduling.on-host-maintenance", "MIGRATE")
   128  	assertNodeAttributeEquals(t, node, "platform.gce.cpu-platform", "Intel Ivy Bridge")
   129  	assertNodeAttributeEquals(t, node, "platform.gce.tag.abc", "true")
   130  	assertNodeAttributeEquals(t, node, "platform.gce.tag.def", "true")
   131  	assertNodeAttributeEquals(t, node, "platform.gce.attr.ghi", "111")
   132  	assertNodeAttributeEquals(t, node, "platform.gce.attr.jkl", "222")
   133  }
   134  
   135  const GCE_routes = `
   136  {
   137    "endpoints": [
   138      {
   139        "uri": "/computeMetadata/v1/instance/id",
   140        "content-type": "text/plain",
   141        "body": "12345"
   142      },
   143      {
   144        "uri": "/computeMetadata/v1/instance/hostname",
   145        "content-type": "text/plain",
   146        "body": "instance-1.c.project.internal"
   147      },
   148      {
   149        "uri": "/computeMetadata/v1/instance/zone",
   150        "content-type": "text/plain",
   151        "body": "projects/555555/zones/us-central1-f"
   152      },
   153      {
   154        "uri": "/computeMetadata/v1/instance/machine-type",
   155        "content-type": "text/plain",
   156        "body": "projects/555555/machineTypes/n1-standard-1"
   157      },
   158      {
   159        "uri": "/computeMetadata/v1/instance/tags",
   160        "content-type": "application/json",
   161        "body": "[\"abc\", \"def\"]"
   162      },
   163      {
   164        "uri": "/computeMetadata/v1/instance/attributes/?recursive=true",
   165        "content-type": "application/json",
   166        "body": "{\"ghi\":\"111\",\"jkl\":\"222\"}"
   167      },
   168      {
   169        "uri": "/computeMetadata/v1/instance/scheduling/automatic-restart",
   170        "content-type": "text/plain",
   171        "body": "TRUE"
   172      },
   173      {
   174        "uri": "/computeMetadata/v1/instance/scheduling/on-host-maintenance",
   175        "content-type": "text/plain",
   176        "body": "MIGRATE"
   177      },
   178      {
   179        "uri": "/computeMetadata/v1/instance/cpu-platform",
   180        "content-type": "text/plain",
   181        "body": "Intel Ivy Bridge"
   182      }
   183    ]
   184  }
   185  `
   186  
   187  func TestFingerprint_GCEWithExternalIp(t *testing.T) {
   188  	testFingerprint_GCE(t, true)
   189  }
   190  
   191  func TestFingerprint_GCEWithoutExternalIp(t *testing.T) {
   192  	testFingerprint_GCE(t, false)
   193  }