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