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  }