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 }