github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/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  		"unique.platform.gce.id",
    90  		"unique.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  		"unique.platform.gce.tag.foo",
    97  		"platform.gce.attr.ghi",
    98  		"platform.gce.attr.jkl",
    99  		"unique.platform.gce.attr.bar",
   100  	}
   101  
   102  	for _, k := range keys {
   103  		assertNodeAttributeContains(t, node, k)
   104  	}
   105  
   106  	if len(node.Links) == 0 {
   107  		t.Fatalf("Empty links for Node in GCE Fingerprint test")
   108  	}
   109  
   110  	// Make sure Links contains the GCE ID.
   111  	for _, k := range []string{"gce"} {
   112  		assertNodeLinksContains(t, node, k)
   113  	}
   114  
   115  	assertNodeAttributeEquals(t, node, "unique.platform.gce.id", "12345")
   116  	assertNodeAttributeEquals(t, node, "unique.platform.gce.hostname", "instance-1.c.project.internal")
   117  	assertNodeAttributeEquals(t, node, "platform.gce.zone", "us-central1-f")
   118  	assertNodeAttributeEquals(t, node, "platform.gce.machine-type", "n1-standard-1")
   119  	assertNodeAttributeEquals(t, node, "platform.gce.network.default", "true")
   120  	assertNodeAttributeEquals(t, node, "unique.platform.gce.network.default.ip", "10.240.0.5")
   121  	if withExternalIp {
   122  		assertNodeAttributeEquals(t, node, "unique.platform.gce.network.default.external-ip.0", "104.44.55.66")
   123  		assertNodeAttributeEquals(t, node, "unique.platform.gce.network.default.external-ip.1", "104.44.55.67")
   124  	} else if _, ok := node.Attributes["unique.platform.gce.network.default.external-ip.0"]; ok {
   125  		t.Fatal("unique.platform.gce.network.default.external-ip is set without an external IP")
   126  	}
   127  
   128  	assertNodeAttributeEquals(t, node, "platform.gce.scheduling.automatic-restart", "TRUE")
   129  	assertNodeAttributeEquals(t, node, "platform.gce.scheduling.on-host-maintenance", "MIGRATE")
   130  	assertNodeAttributeEquals(t, node, "platform.gce.cpu-platform", "Intel Ivy Bridge")
   131  	assertNodeAttributeEquals(t, node, "platform.gce.tag.abc", "true")
   132  	assertNodeAttributeEquals(t, node, "platform.gce.tag.def", "true")
   133  	assertNodeAttributeEquals(t, node, "unique.platform.gce.tag.foo", "true")
   134  	assertNodeAttributeEquals(t, node, "platform.gce.attr.ghi", "111")
   135  	assertNodeAttributeEquals(t, node, "platform.gce.attr.jkl", "222")
   136  	assertNodeAttributeEquals(t, node, "unique.platform.gce.attr.bar", "333")
   137  }
   138  
   139  const GCE_routes = `
   140  {
   141    "endpoints": [
   142      {
   143        "uri": "/computeMetadata/v1/instance/id",
   144        "content-type": "text/plain",
   145        "body": "12345"
   146      },
   147      {
   148        "uri": "/computeMetadata/v1/instance/hostname",
   149        "content-type": "text/plain",
   150        "body": "instance-1.c.project.internal"
   151      },
   152      {
   153        "uri": "/computeMetadata/v1/instance/zone",
   154        "content-type": "text/plain",
   155        "body": "projects/555555/zones/us-central1-f"
   156      },
   157      {
   158        "uri": "/computeMetadata/v1/instance/machine-type",
   159        "content-type": "text/plain",
   160        "body": "projects/555555/machineTypes/n1-standard-1"
   161      },
   162      {
   163        "uri": "/computeMetadata/v1/instance/tags",
   164        "content-type": "application/json",
   165        "body": "[\"abc\", \"def\", \"unique.foo\"]"
   166      },
   167      {
   168        "uri": "/computeMetadata/v1/instance/attributes/?recursive=true",
   169        "content-type": "application/json",
   170        "body": "{\"ghi\":\"111\",\"jkl\":\"222\",\"unique.bar\":\"333\"}"
   171      },
   172      {
   173        "uri": "/computeMetadata/v1/instance/scheduling/automatic-restart",
   174        "content-type": "text/plain",
   175        "body": "TRUE"
   176      },
   177      {
   178        "uri": "/computeMetadata/v1/instance/scheduling/on-host-maintenance",
   179        "content-type": "text/plain",
   180        "body": "MIGRATE"
   181      },
   182      {
   183        "uri": "/computeMetadata/v1/instance/cpu-platform",
   184        "content-type": "text/plain",
   185        "body": "Intel Ivy Bridge"
   186      }
   187    ]
   188  }
   189  `
   190  
   191  func TestFingerprint_GCEWithExternalIp(t *testing.T) {
   192  	testFingerprint_GCE(t, true)
   193  }
   194  
   195  func TestFingerprint_GCEWithoutExternalIp(t *testing.T) {
   196  	testFingerprint_GCE(t, false)
   197  }