github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/fingerprint/env_digitalocean_test.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"strings"
     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  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func TestDigitalOceanFingerprint_nonDigitalOcean(t *testing.T) {
    18  
    19  	t.Setenv("DO_ENV_URL", "http://127.0.0.1/metadata/v1/")
    20  	f := NewEnvDigitalOceanFingerprint(testlog.HCLogger(t))
    21  	node := &structs.Node{
    22  		Attributes: make(map[string]string),
    23  	}
    24  
    25  	request := &FingerprintRequest{Config: &config.Config{}, Node: node}
    26  	var response FingerprintResponse
    27  	err := f.Fingerprint(request, &response)
    28  	if err != nil {
    29  		t.Fatalf("err: %v", err)
    30  	}
    31  
    32  	if response.Detected {
    33  		t.Fatalf("expected response to not be applicable")
    34  	}
    35  
    36  	if len(response.Attributes) > 0 {
    37  		t.Fatalf("Should have zero attributes without test server")
    38  	}
    39  }
    40  
    41  func TestFingerprint_DigitalOcean(t *testing.T) {
    42  
    43  	node := &structs.Node{
    44  		Attributes: make(map[string]string),
    45  	}
    46  
    47  	// configure mock server with fixture routes, data
    48  	routes := routes{}
    49  	if err := json.Unmarshal([]byte(DO_routes), &routes); err != nil {
    50  		t.Fatalf("Failed to unmarshal JSON in DO ENV test: %s", err)
    51  	}
    52  
    53  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    54  		uavalue, ok := r.Header["User-Agent"]
    55  		if !ok {
    56  			t.Fatal("User-Agent not present in HTTP request header")
    57  		}
    58  		if !strings.Contains(uavalue[0], "Nomad/") {
    59  			t.Fatalf("Expected User-Agent to contain Nomad/, got %s", uavalue[0])
    60  		}
    61  
    62  		uri := r.RequestURI
    63  		if r.URL.RawQuery != "" {
    64  			uri = strings.Replace(uri, "?"+r.URL.RawQuery, "", 1)
    65  		}
    66  
    67  		found := false
    68  		for _, e := range routes.Endpoints {
    69  			if uri == e.Uri {
    70  				w.Header().Set("Content-Type", e.ContentType)
    71  				fmt.Fprintln(w, e.Body)
    72  				found = true
    73  			}
    74  		}
    75  
    76  		if !found {
    77  			w.WriteHeader(404)
    78  		}
    79  	}))
    80  	defer ts.Close()
    81  	t.Setenv("DO_ENV_URL", ts.URL+"/metadata/v1/")
    82  	f := NewEnvDigitalOceanFingerprint(testlog.HCLogger(t))
    83  
    84  	request := &FingerprintRequest{Config: &config.Config{}, Node: node}
    85  	var response FingerprintResponse
    86  	err := f.Fingerprint(request, &response)
    87  	assert.NoError(t, err)
    88  	assert.True(t, response.Detected, "expected response to be applicable")
    89  
    90  	keys := []string{
    91  		"unique.platform.digitalocean.id",
    92  		"unique.platform.digitalocean.hostname",
    93  		"platform.digitalocean.region",
    94  		"unique.platform.digitalocean.private-ipv4",
    95  		"unique.platform.digitalocean.public-ipv4",
    96  		"unique.platform.digitalocean.public-ipv6",
    97  		"unique.platform.digitalocean.mac",
    98  	}
    99  
   100  	for _, k := range keys {
   101  		assertNodeAttributeContains(t, response.Attributes, k)
   102  	}
   103  
   104  	assert.NotEmpty(t, response.Links, "Empty links for Node in DO Fingerprint test")
   105  
   106  	// Make sure Links contains the DO ID.
   107  	for _, k := range []string{"digitalocean"} {
   108  		assertNodeLinksContains(t, response.Links, k)
   109  	}
   110  
   111  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.id", "13f56399-bd52-4150-9748-7190aae1ff21")
   112  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.hostname", "demo01.internal")
   113  	assertNodeAttributeEquals(t, response.Attributes, "platform.digitalocean.region", "sfo3")
   114  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.private-ipv4", "10.1.0.4")
   115  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.mac", "000D3AF806EC")
   116  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.public-ipv4", "100.100.100.100")
   117  	assertNodeAttributeEquals(t, response.Attributes, "unique.platform.digitalocean.public-ipv6", "c99c:8ac5:3112:204b:48b0:41aa:e085:d11a")
   118  }
   119  
   120  const DO_routes = `
   121  {
   122    "endpoints": [
   123  	{
   124  	  "uri": "/metadata/v1/region",
   125  	  "content-type": "text/plain",
   126        "body": "sfo3"
   127  	},
   128  	{
   129  		"uri": "/metadata/v1/hostname",
   130  		"content-type": "text/plain",
   131  		"body": "demo01.internal"
   132  	},
   133  	{
   134  		"uri": "/metadata/v1/id",
   135  		"content-type": "text/plain",
   136  		"body": "13f56399-bd52-4150-9748-7190aae1ff21"
   137  	},
   138  	{
   139  		"uri": "/metadata/v1/interfaces/private/0/ipv4/address",
   140  		"content-type": "text/plain",
   141  		"body": "10.1.0.4"
   142  	},
   143  	{
   144  		"uri": "/metadata/v1/interfaces/public/0/mac",
   145  		"content-type": "text/plain",
   146  		"body": "000D3AF806EC"
   147  	},
   148    {
   149  		"uri": "/metadata/v1/interfaces/public/0/ipv4/address",
   150  		"content-type": "text/plain",
   151  		"body": "100.100.100.100"
   152  	},
   153    {
   154  		"uri": "/metadata/v1/interfaces/public/0/ipv6/address",
   155  		"content-type": "text/plain",
   156  		"body": "c99c:8ac5:3112:204b:48b0:41aa:e085:d11a"
   157  	}
   158    ]
   159  }
   160  `