github.com/hernad/nomad@v1.6.112/nomad/structs/config/consul_test.go (about)

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