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 }