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 }