github.com/zhizhiboom/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/client/fingerprint/env_aws_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 cstructs "github.com/hashicorp/nomad/client/structs" 13 "github.com/hashicorp/nomad/helper/testlog" 14 "github.com/hashicorp/nomad/nomad/structs" 15 ) 16 17 func TestEnvAWSFingerprint_nonAws(t *testing.T) { 18 os.Setenv("AWS_ENV_URL", "http://127.0.0.1/latest/meta-data/") 19 f := NewEnvAWSFingerprint(testlog.Logger(t)) 20 node := &structs.Node{ 21 Attributes: make(map[string]string), 22 } 23 24 request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} 25 var response cstructs.FingerprintResponse 26 err := f.Fingerprint(request, &response) 27 if err != nil { 28 t.Fatalf("err: %v", err) 29 } 30 31 if len(response.Attributes) > 0 { 32 t.Fatalf("Should not apply") 33 } 34 } 35 36 func TestEnvAWSFingerprint_aws(t *testing.T) { 37 f := NewEnvAWSFingerprint(testlog.Logger(t)) 38 node := &structs.Node{ 39 Attributes: make(map[string]string), 40 } 41 42 // configure mock server with fixture routes, data 43 routes := routes{} 44 if err := json.Unmarshal([]byte(aws_routes), &routes); err != nil { 45 t.Fatalf("Failed to unmarshal JSON in AWS ENV test: %s", err) 46 } 47 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 48 for _, e := range routes.Endpoints { 49 if r.RequestURI == e.Uri { 50 w.Header().Set("Content-Type", e.ContentType) 51 fmt.Fprintln(w, e.Body) 52 } 53 } 54 })) 55 defer ts.Close() 56 os.Setenv("AWS_ENV_URL", ts.URL+"/latest/meta-data/") 57 58 request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} 59 var response cstructs.FingerprintResponse 60 err := f.Fingerprint(request, &response) 61 if err != nil { 62 t.Fatalf("err: %v", err) 63 } 64 65 keys := []string{ 66 "platform.aws.ami-id", 67 "unique.platform.aws.hostname", 68 "unique.platform.aws.instance-id", 69 "platform.aws.instance-type", 70 "unique.platform.aws.local-hostname", 71 "unique.platform.aws.local-ipv4", 72 "unique.platform.aws.public-hostname", 73 "unique.platform.aws.public-ipv4", 74 "platform.aws.placement.availability-zone", 75 "unique.network.ip-address", 76 } 77 78 for _, k := range keys { 79 assertNodeAttributeContains(t, response.Attributes, k) 80 } 81 82 if len(response.Links) == 0 { 83 t.Fatalf("Empty links for Node in AWS Fingerprint test") 84 } 85 86 // confirm we have at least instance-id and ami-id 87 for _, k := range []string{"aws.ec2"} { 88 assertNodeLinksContains(t, response.Links, k) 89 } 90 } 91 92 type routes struct { 93 Endpoints []*endpoint `json:"endpoints"` 94 } 95 type endpoint struct { 96 Uri string `json:"uri"` 97 ContentType string `json:"content-type"` 98 Body string `json:"body"` 99 } 100 101 const aws_routes = ` 102 { 103 "endpoints": [ 104 { 105 "uri": "/latest/meta-data/ami-id", 106 "content-type": "text/plain", 107 "body": "ami-1234" 108 }, 109 { 110 "uri": "/latest/meta-data/hostname", 111 "content-type": "text/plain", 112 "body": "ip-10-0-0-207.us-west-2.compute.internal" 113 }, 114 { 115 "uri": "/latest/meta-data/placement/availability-zone", 116 "content-type": "text/plain", 117 "body": "us-west-2a" 118 }, 119 { 120 "uri": "/latest/meta-data/instance-id", 121 "content-type": "text/plain", 122 "body": "i-b3ba3875" 123 }, 124 { 125 "uri": "/latest/meta-data/instance-type", 126 "content-type": "text/plain", 127 "body": "m3.2xlarge" 128 }, 129 { 130 "uri": "/latest/meta-data/local-hostname", 131 "content-type": "text/plain", 132 "body": "ip-10-0-0-207.us-west-2.compute.internal" 133 }, 134 { 135 "uri": "/latest/meta-data/local-ipv4", 136 "content-type": "text/plain", 137 "body": "10.0.0.207" 138 }, 139 { 140 "uri": "/latest/meta-data/public-hostname", 141 "content-type": "text/plain", 142 "body": "ec2-54-191-117-175.us-west-2.compute.amazonaws.com" 143 }, 144 { 145 "uri": "/latest/meta-data/public-ipv4", 146 "content-type": "text/plain", 147 "body": "54.191.117.175" 148 } 149 ] 150 } 151 ` 152 153 func TestNetworkFingerprint_AWS(t *testing.T) { 154 // configure mock server with fixture routes, data 155 routes := routes{} 156 if err := json.Unmarshal([]byte(aws_routes), &routes); err != nil { 157 t.Fatalf("Failed to unmarshal JSON in AWS ENV test: %s", err) 158 } 159 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 160 for _, e := range routes.Endpoints { 161 if r.RequestURI == e.Uri { 162 w.Header().Set("Content-Type", e.ContentType) 163 fmt.Fprintln(w, e.Body) 164 } 165 } 166 })) 167 168 defer ts.Close() 169 os.Setenv("AWS_ENV_URL", ts.URL+"/latest/meta-data/") 170 171 f := NewEnvAWSFingerprint(testlog.Logger(t)) 172 node := &structs.Node{ 173 Attributes: make(map[string]string), 174 } 175 176 request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} 177 var response cstructs.FingerprintResponse 178 err := f.Fingerprint(request, &response) 179 if err != nil { 180 t.Fatalf("err: %v", err) 181 } 182 183 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 184 185 if response.Resources == nil || len(response.Resources.Networks) == 0 { 186 t.Fatal("Expected to find Network Resources") 187 } 188 189 // Test at least the first Network Resource 190 net := response.Resources.Networks[0] 191 if net.IP == "" { 192 t.Fatal("Expected Network Resource to have an IP") 193 } 194 if net.CIDR == "" { 195 t.Fatal("Expected Network Resource to have a CIDR") 196 } 197 if net.Device == "" { 198 t.Fatal("Expected Network Resource to have a Device Name") 199 } 200 } 201 202 func TestNetworkFingerprint_AWS_network(t *testing.T) { 203 // configure mock server with fixture routes, data 204 routes := routes{} 205 if err := json.Unmarshal([]byte(aws_routes), &routes); err != nil { 206 t.Fatalf("Failed to unmarshal JSON in AWS ENV test: %s", err) 207 } 208 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 209 for _, e := range routes.Endpoints { 210 if r.RequestURI == e.Uri { 211 w.Header().Set("Content-Type", e.ContentType) 212 fmt.Fprintln(w, e.Body) 213 } 214 } 215 })) 216 217 defer ts.Close() 218 os.Setenv("AWS_ENV_URL", ts.URL+"/latest/meta-data/") 219 220 f := NewEnvAWSFingerprint(testlog.Logger(t)) 221 { 222 node := &structs.Node{ 223 Attributes: make(map[string]string), 224 } 225 226 request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} 227 var response cstructs.FingerprintResponse 228 err := f.Fingerprint(request, &response) 229 if err != nil { 230 t.Fatalf("err: %v", err) 231 } 232 233 if !response.Detected { 234 t.Fatalf("expected response to be applicable") 235 } 236 237 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 238 239 if response.Resources == nil || len(response.Resources.Networks) == 0 { 240 t.Fatal("Expected to find Network Resources") 241 } 242 243 // Test at least the first Network Resource 244 net := response.Resources.Networks[0] 245 if net.IP == "" { 246 t.Fatal("Expected Network Resource to have an IP") 247 } 248 if net.CIDR == "" { 249 t.Fatal("Expected Network Resource to have a CIDR") 250 } 251 if net.Device == "" { 252 t.Fatal("Expected Network Resource to have a Device Name") 253 } 254 if net.MBits != 1000 { 255 t.Fatalf("Expected Network Resource to have speed %d; got %d", 1000, net.MBits) 256 } 257 } 258 259 // Try again this time setting a network speed in the config 260 { 261 node := &structs.Node{ 262 Attributes: make(map[string]string), 263 } 264 265 cfg := &config.Config{ 266 NetworkSpeed: 10, 267 } 268 269 request := &cstructs.FingerprintRequest{Config: cfg, Node: node} 270 var response cstructs.FingerprintResponse 271 err := f.Fingerprint(request, &response) 272 if err != nil { 273 t.Fatalf("err: %v", err) 274 } 275 276 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 277 278 if response.Resources == nil || len(response.Resources.Networks) == 0 { 279 t.Fatal("Expected to find Network Resources") 280 } 281 282 // Test at least the first Network Resource 283 net := response.Resources.Networks[0] 284 if net.IP == "" { 285 t.Fatal("Expected Network Resource to have an IP") 286 } 287 if net.CIDR == "" { 288 t.Fatal("Expected Network Resource to have a CIDR") 289 } 290 if net.Device == "" { 291 t.Fatal("Expected Network Resource to have a Device Name") 292 } 293 if net.MBits != 10 { 294 t.Fatalf("Expected Network Resource to have speed %d; got %d", 10, net.MBits) 295 } 296 } 297 } 298 299 func TestNetworkFingerprint_notAWS(t *testing.T) { 300 os.Setenv("AWS_ENV_URL", "http://127.0.0.1/latest/meta-data/") 301 f := NewEnvAWSFingerprint(testlog.Logger(t)) 302 node := &structs.Node{ 303 Attributes: make(map[string]string), 304 } 305 306 request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} 307 var response cstructs.FingerprintResponse 308 err := f.Fingerprint(request, &response) 309 if err != nil { 310 t.Fatalf("err: %v", err) 311 } 312 313 if len(response.Attributes) > 0 { 314 t.Fatalf("Should not apply") 315 } 316 }