github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/structs/config/consul_test.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"testing"
     9  	"time"
    10  
    11  	consulapi "github.com/hashicorp/consul/api"
    12  	sockaddr "github.com/hashicorp/go-sockaddr"
    13  	"github.com/hashicorp/nomad/ci"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestMain(m *testing.M) {
    19  	if os.Getenv("NOMAD_ENV_TEST") != "1" {
    20  		os.Exit(m.Run())
    21  	}
    22  
    23  	// Encode the default config as json to stdout for testing env var
    24  	// handling.
    25  	if err := json.NewEncoder(os.Stdout).Encode(DefaultConsulConfig()); err != nil {
    26  		fmt.Fprintf(os.Stderr, "error encoding config: %v", err)
    27  		os.Exit(2)
    28  	}
    29  
    30  	os.Exit(0)
    31  }
    32  
    33  func TestConsulConfig_Merge(t *testing.T) {
    34  	ci.Parallel(t)
    35  
    36  	yes, no := true, false
    37  
    38  	c1 := &ConsulConfig{
    39  		ServerServiceName:    "1",
    40  		ServerHTTPCheckName:  "1",
    41  		ServerSerfCheckName:  "1",
    42  		ServerRPCCheckName:   "1",
    43  		ClientServiceName:    "1",
    44  		ClientHTTPCheckName:  "1",
    45  		Tags:                 []string{"a", "1"},
    46  		AutoAdvertise:        &no,
    47  		ChecksUseAdvertise:   &no,
    48  		Addr:                 "1",
    49  		GRPCAddr:             "1",
    50  		Timeout:              time.Duration(1),
    51  		TimeoutHCL:           "1",
    52  		Token:                "1",
    53  		AllowUnauthenticated: &no,
    54  		Auth:                 "1",
    55  		EnableSSL:            &no,
    56  		VerifySSL:            &no,
    57  		CAFile:               "1",
    58  		CertFile:             "1",
    59  		KeyFile:              "1",
    60  		ServerAutoJoin:       &no,
    61  		ClientAutoJoin:       &no,
    62  		ExtraKeysHCL:         []string{"a", "1"},
    63  	}
    64  
    65  	c2 := &ConsulConfig{
    66  		ServerServiceName:    "2",
    67  		ServerHTTPCheckName:  "2",
    68  		ServerSerfCheckName:  "2",
    69  		ServerRPCCheckName:   "2",
    70  		ClientServiceName:    "2",
    71  		ClientHTTPCheckName:  "2",
    72  		Tags:                 []string{"b", "2"},
    73  		AutoAdvertise:        &yes,
    74  		ChecksUseAdvertise:   &yes,
    75  		Addr:                 "2",
    76  		GRPCAddr:             "2",
    77  		Timeout:              time.Duration(2),
    78  		TimeoutHCL:           "2",
    79  		Token:                "2",
    80  		AllowUnauthenticated: &yes,
    81  		Auth:                 "2",
    82  		EnableSSL:            &yes,
    83  		VerifySSL:            &yes,
    84  		CAFile:               "2",
    85  		CertFile:             "2",
    86  		KeyFile:              "2",
    87  		ServerAutoJoin:       &yes,
    88  		ClientAutoJoin:       &yes,
    89  		ExtraKeysHCL:         []string{"b", "2"},
    90  	}
    91  
    92  	exp := &ConsulConfig{
    93  		ServerServiceName:    "2",
    94  		ServerHTTPCheckName:  "2",
    95  		ServerSerfCheckName:  "2",
    96  		ServerRPCCheckName:   "2",
    97  		ClientServiceName:    "2",
    98  		ClientHTTPCheckName:  "2",
    99  		Tags:                 []string{"a", "1", "b", "2"},
   100  		AutoAdvertise:        &yes,
   101  		ChecksUseAdvertise:   &yes,
   102  		Addr:                 "2",
   103  		GRPCAddr:             "2",
   104  		Timeout:              time.Duration(2),
   105  		TimeoutHCL:           "2",
   106  		Token:                "2",
   107  		AllowUnauthenticated: &yes,
   108  		Auth:                 "2",
   109  		EnableSSL:            &yes,
   110  		VerifySSL:            &yes,
   111  		CAFile:               "2",
   112  		CertFile:             "2",
   113  		KeyFile:              "2",
   114  		ServerAutoJoin:       &yes,
   115  		ClientAutoJoin:       &yes,
   116  		ExtraKeysHCL:         []string{"a", "1"}, // not merged
   117  	}
   118  
   119  	result := c1.Merge(c2)
   120  	require.Equal(t, exp, result)
   121  }
   122  
   123  // TestConsulConfig_Defaults asserts Consul defaults are copied from their
   124  // upstream API package defaults.
   125  func TestConsulConfig_Defaults(t *testing.T) {
   126  	ci.Parallel(t)
   127  
   128  	nomadDef := DefaultConsulConfig()
   129  	consulDef := consulapi.DefaultConfig()
   130  
   131  	require.Equal(t, consulDef.Address, nomadDef.Addr)
   132  	require.NotZero(t, nomadDef.Addr)
   133  	require.Equal(t, consulDef.Scheme == "https", *nomadDef.EnableSSL)
   134  	require.Equal(t, !consulDef.TLSConfig.InsecureSkipVerify, *nomadDef.VerifySSL)
   135  	require.Equal(t, consulDef.TLSConfig.CAFile, nomadDef.CAFile)
   136  }
   137  
   138  // TestConsulConfig_Exec asserts Consul defaults use env vars when they are
   139  // set by forking a subprocess.
   140  func TestConsulConfig_Exec(t *testing.T) {
   141  	ci.Parallel(t)
   142  
   143  	self, err := os.Executable()
   144  	if err != nil {
   145  		t.Fatalf("error finding test binary: %v", err)
   146  	}
   147  
   148  	cmd := exec.Command(self)
   149  	cmd.Env = []string{
   150  		"NOMAD_ENV_TEST=1",
   151  		"CONSUL_CACERT=cacert",
   152  		"CONSUL_HTTP_ADDR=addr",
   153  		"CONSUL_HTTP_SSL=1",
   154  		"CONSUL_HTTP_SSL_VERIFY=1",
   155  	}
   156  
   157  	out, err := cmd.Output()
   158  	if err != nil {
   159  		if eerr, ok := err.(*exec.ExitError); ok {
   160  			t.Fatalf("exit error code %d; output:\n%s", eerr.ExitCode(), string(eerr.Stderr))
   161  		}
   162  		t.Fatalf("error running command %q: %v", self, err)
   163  	}
   164  
   165  	conf := ConsulConfig{}
   166  	require.NoError(t, json.Unmarshal(out, &conf))
   167  	assert.Equal(t, "cacert", conf.CAFile)
   168  	assert.Equal(t, "addr", conf.Addr)
   169  	require.NotNil(t, conf.EnableSSL)
   170  	assert.True(t, *conf.EnableSSL)
   171  	require.NotNil(t, conf.VerifySSL)
   172  	assert.True(t, *conf.VerifySSL)
   173  }
   174  
   175  func TestConsulConfig_IpTemplateParse(t *testing.T) {
   176  	ci.Parallel(t)
   177  
   178  	privateIp, err := sockaddr.GetPrivateIP()
   179  	require.NoError(t, err)
   180  
   181  	testCases := []struct {
   182  		name        string
   183  		tmpl        string
   184  		expectedOut string
   185  		expectErr   bool
   186  	}{
   187  		{name: "string address keeps working", tmpl: "10.0.1.0:8500", expectedOut: "10.0.1.0:8500", expectErr: false},
   188  		{name: "single ip sock-addr template", tmpl: "{{ GetPrivateIP }}:8500", expectedOut: privateIp + ":8500", expectErr: false},
   189  		{name: "multi ip sock-addr template", tmpl: "10.0.1.0 10.0.1.1:8500", expectedOut: "", expectErr: true},
   190  	}
   191  
   192  	for _, tc := range testCases {
   193  		tc := tc
   194  		t.Run(tc.name, func(t *testing.T) {
   195  			ci.Parallel(t)
   196  			conf := ConsulConfig{
   197  				Addr: tc.tmpl,
   198  			}
   199  			out, err := conf.ApiConfig()
   200  
   201  			if tc.expectErr {
   202  				require.Error(t, err)
   203  				return
   204  			}
   205  			require.NoError(t, err)
   206  			require.Equal(t, tc.expectedOut, out.Address)
   207  		})
   208  	}
   209  }