github.com/manicqin/nomad@v0.9.5/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 "testing" 9 10 "github.com/hashicorp/nomad/client/config" 11 "github.com/hashicorp/nomad/helper/testlog" 12 "github.com/hashicorp/nomad/nomad/structs" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestEnvAWSFingerprint_nonAws(t *testing.T) { 17 f := NewEnvAWSFingerprint(testlog.HCLogger(t)) 18 f.(*EnvAWSFingerprint).endpoint = "http://127.0.0.1/latest" 19 20 node := &structs.Node{ 21 Attributes: make(map[string]string), 22 } 23 24 request := &FingerprintRequest{Config: &config.Config{}, Node: node} 25 var response FingerprintResponse 26 err := f.Fingerprint(request, &response) 27 require.NoError(t, err) 28 require.Empty(t, response.Attributes) 29 } 30 31 func TestEnvAWSFingerprint_aws(t *testing.T) { 32 endpoint, cleanup := startFakeEC2Metadata(t) 33 defer cleanup() 34 35 f := NewEnvAWSFingerprint(testlog.HCLogger(t)) 36 f.(*EnvAWSFingerprint).endpoint = endpoint 37 38 node := &structs.Node{ 39 Attributes: make(map[string]string), 40 } 41 42 request := &FingerprintRequest{Config: &config.Config{}, Node: node} 43 var response FingerprintResponse 44 err := f.Fingerprint(request, &response) 45 require.NoError(t, err) 46 47 keys := []string{ 48 "platform.aws.ami-id", 49 "unique.platform.aws.hostname", 50 "unique.platform.aws.instance-id", 51 "platform.aws.instance-type", 52 "unique.platform.aws.local-hostname", 53 "unique.platform.aws.local-ipv4", 54 "unique.platform.aws.public-hostname", 55 "unique.platform.aws.public-ipv4", 56 "platform.aws.placement.availability-zone", 57 "unique.network.ip-address", 58 } 59 60 for _, k := range keys { 61 assertNodeAttributeContains(t, response.Attributes, k) 62 } 63 64 require.NotEmpty(t, response.Links) 65 66 // confirm we have at least instance-id and ami-id 67 for _, k := range []string{"aws.ec2"} { 68 assertNodeLinksContains(t, response.Links, k) 69 } 70 } 71 72 func TestNetworkFingerprint_AWS(t *testing.T) { 73 endpoint, cleanup := startFakeEC2Metadata(t) 74 defer cleanup() 75 76 f := NewEnvAWSFingerprint(testlog.HCLogger(t)) 77 f.(*EnvAWSFingerprint).endpoint = endpoint 78 79 node := &structs.Node{ 80 Attributes: make(map[string]string), 81 } 82 83 request := &FingerprintRequest{Config: &config.Config{}, Node: node} 84 var response FingerprintResponse 85 err := f.Fingerprint(request, &response) 86 require.NoError(t, err) 87 88 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 89 90 require.NotNil(t, response.NodeResources) 91 require.Len(t, response.NodeResources.Networks, 1) 92 93 // Test at least the first Network Resource 94 net := response.NodeResources.Networks[0] 95 require.NotEmpty(t, net.IP, "Expected Network Resource to have an IP") 96 require.NotEmpty(t, net.CIDR, "Expected Network Resource to have a CIDR") 97 require.NotEmpty(t, net.Device, "Expected Network Resource to have a Device Name") 98 } 99 100 func TestNetworkFingerprint_AWS_network(t *testing.T) { 101 endpoint, cleanup := startFakeEC2Metadata(t) 102 defer cleanup() 103 104 f := NewEnvAWSFingerprint(testlog.HCLogger(t)) 105 f.(*EnvAWSFingerprint).endpoint = endpoint 106 107 { 108 node := &structs.Node{ 109 Attributes: make(map[string]string), 110 } 111 112 request := &FingerprintRequest{Config: &config.Config{}, Node: node} 113 var response FingerprintResponse 114 err := f.Fingerprint(request, &response) 115 require.NoError(t, err) 116 117 require.True(t, response.Detected, "expected response to be applicable") 118 119 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 120 121 require.NotNil(t, response.NodeResources) 122 require.Len(t, response.NodeResources.Networks, 1) 123 124 // Test at least the first Network Resource 125 net := response.NodeResources.Networks[0] 126 require.NotEmpty(t, net.IP, "Expected Network Resource to have an IP") 127 require.NotEmpty(t, net.CIDR, "Expected Network Resource to have a CIDR") 128 require.NotEmpty(t, net.Device, "Expected Network Resource to have a Device Name") 129 require.Equal(t, 1000, net.MBits) 130 } 131 132 // Try again this time setting a network speed in the config 133 { 134 node := &structs.Node{ 135 Attributes: make(map[string]string), 136 } 137 138 cfg := &config.Config{ 139 NetworkSpeed: 10, 140 } 141 142 request := &FingerprintRequest{Config: cfg, Node: node} 143 var response FingerprintResponse 144 err := f.Fingerprint(request, &response) 145 require.NoError(t, err) 146 147 assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") 148 149 require.NotNil(t, response.NodeResources) 150 require.Len(t, response.NodeResources.Networks, 1) 151 152 // Test at least the first Network Resource 153 net := response.NodeResources.Networks[0] 154 require.NotEmpty(t, net.IP, "Expected Network Resource to have an IP") 155 require.NotEmpty(t, net.CIDR, "Expected Network Resource to have a CIDR") 156 require.NotEmpty(t, net.Device, "Expected Network Resource to have a Device Name") 157 require.Equal(t, 10, net.MBits) 158 } 159 } 160 161 /// Utility functions for tests 162 163 func startFakeEC2Metadata(t *testing.T) (endpoint string, cleanup func()) { 164 routes := routes{} 165 if err := json.Unmarshal([]byte(aws_routes), &routes); err != nil { 166 t.Fatalf("Failed to unmarshal JSON in AWS ENV test: %s", err) 167 } 168 169 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 170 for _, e := range routes.Endpoints { 171 if r.RequestURI == e.Uri { 172 w.Header().Set("Content-Type", e.ContentType) 173 fmt.Fprintln(w, e.Body) 174 } 175 } 176 })) 177 178 return ts.URL + "/latest", ts.Close 179 } 180 181 type routes struct { 182 Endpoints []*endpoint `json:"endpoints"` 183 } 184 type endpoint struct { 185 Uri string `json:"uri"` 186 ContentType string `json:"content-type"` 187 Body string `json:"body"` 188 } 189 190 const aws_routes = ` 191 { 192 "endpoints": [ 193 { 194 "uri": "/latest/meta-data/ami-id", 195 "content-type": "text/plain", 196 "body": "ami-1234" 197 }, 198 { 199 "uri": "/latest/meta-data/hostname", 200 "content-type": "text/plain", 201 "body": "ip-10-0-0-207.us-west-2.compute.internal" 202 }, 203 { 204 "uri": "/latest/meta-data/placement/availability-zone", 205 "content-type": "text/plain", 206 "body": "us-west-2a" 207 }, 208 { 209 "uri": "/latest/meta-data/instance-id", 210 "content-type": "text/plain", 211 "body": "i-b3ba3875" 212 }, 213 { 214 "uri": "/latest/meta-data/instance-type", 215 "content-type": "text/plain", 216 "body": "m3.2xlarge" 217 }, 218 { 219 "uri": "/latest/meta-data/local-hostname", 220 "content-type": "text/plain", 221 "body": "ip-10-0-0-207.us-west-2.compute.internal" 222 }, 223 { 224 "uri": "/latest/meta-data/local-ipv4", 225 "content-type": "text/plain", 226 "body": "10.0.0.207" 227 }, 228 { 229 "uri": "/latest/meta-data/public-hostname", 230 "content-type": "text/plain", 231 "body": "ec2-54-191-117-175.us-west-2.compute.amazonaws.com" 232 }, 233 { 234 "uri": "/latest/meta-data/public-ipv4", 235 "content-type": "text/plain", 236 "body": "54.191.117.175" 237 } 238 ] 239 } 240 `