github.com/adityamillind98/nomad@v0.11.8/command/agent/consul/connect_test.go (about) 1 package consul 2 3 import ( 4 "testing" 5 6 "github.com/hashicorp/consul/api" 7 "github.com/hashicorp/nomad/nomad/structs" 8 "github.com/stretchr/testify/require" 9 ) 10 11 var ( 12 testConnectNetwork = structs.Networks{{ 13 Mode: "bridge", 14 Device: "eth0", 15 IP: "192.168.30.1", 16 DynamicPorts: []structs.Port{ 17 {Label: "healthPort", Value: 23100, To: 23100}, 18 {Label: "metricsPort", Value: 23200, To: 23200}, 19 {Label: "connect-proxy-redis", Value: 3000, To: 3000}, 20 }, 21 }} 22 ) 23 24 func TestConnect_newConnect(t *testing.T) { 25 t.Parallel() 26 27 t.Run("nil", func(t *testing.T) { 28 asr, err := newConnect("", nil, nil) 29 require.NoError(t, err) 30 require.Nil(t, asr) 31 }) 32 33 t.Run("native", func(t *testing.T) { 34 asr, err := newConnect("", &structs.ConsulConnect{ 35 Native: true, 36 }, nil) 37 require.NoError(t, err) 38 require.True(t, asr.Native) 39 require.Nil(t, asr.SidecarService) 40 }) 41 42 t.Run("with sidecar", func(t *testing.T) { 43 asr, err := newConnect("redis", &structs.ConsulConnect{ 44 Native: false, 45 SidecarService: &structs.ConsulSidecarService{ 46 Tags: []string{"foo", "bar"}, 47 Port: "sidecarPort", 48 }, 49 }, testConnectNetwork) 50 require.NoError(t, err) 51 require.Equal(t, &api.AgentServiceRegistration{ 52 Tags: []string{"foo", "bar"}, 53 Port: 3000, 54 Address: "192.168.30.1", 55 Proxy: &api.AgentServiceConnectProxyConfig{ 56 Config: map[string]interface{}{ 57 "bind_address": "0.0.0.0", 58 "bind_port": 3000, 59 }, 60 }, 61 }, asr.SidecarService) 62 }) 63 } 64 65 func TestConnect_connectSidecarRegistration(t *testing.T) { 66 t.Parallel() 67 68 t.Run("nil", func(t *testing.T) { 69 sidecarReg, err := connectSidecarRegistration("", nil, testConnectNetwork) 70 require.NoError(t, err) 71 require.Nil(t, sidecarReg) 72 }) 73 74 t.Run("no service port", func(t *testing.T) { 75 _, err := connectSidecarRegistration("unknown", &structs.ConsulSidecarService{ 76 // irrelevant 77 }, testConnectNetwork) 78 require.EqualError(t, err, `No Connect port defined for service "unknown"`) 79 }) 80 81 t.Run("bad proxy", func(t *testing.T) { 82 _, err := connectSidecarRegistration("redis", &structs.ConsulSidecarService{ 83 Proxy: &structs.ConsulProxy{ 84 Expose: &structs.ConsulExposeConfig{ 85 Paths: []structs.ConsulExposePath{{ 86 ListenerPort: "badPort", 87 }}, 88 }, 89 }, 90 }, testConnectNetwork) 91 require.EqualError(t, err, `No port of label "badPort" defined`) 92 }) 93 94 t.Run("normal", func(t *testing.T) { 95 proxy, err := connectSidecarRegistration("redis", &structs.ConsulSidecarService{ 96 Tags: []string{"foo", "bar"}, 97 Port: "sidecarPort", 98 }, testConnectNetwork) 99 require.NoError(t, err) 100 require.Equal(t, &api.AgentServiceRegistration{ 101 Tags: []string{"foo", "bar"}, 102 Port: 3000, 103 Address: "192.168.30.1", 104 Proxy: &api.AgentServiceConnectProxyConfig{ 105 Config: map[string]interface{}{ 106 "bind_address": "0.0.0.0", 107 "bind_port": 3000, 108 }, 109 }, 110 }, proxy) 111 }) 112 } 113 114 func TestConnect_connectProxy(t *testing.T) { 115 t.Parallel() 116 117 // If the input proxy is nil, we expect the output to be a proxy with its 118 // config set to default values. 119 t.Run("nil proxy", func(t *testing.T) { 120 proxy, err := connectProxy(nil, 2000, testConnectNetwork) 121 require.NoError(t, err) 122 require.Equal(t, &api.AgentServiceConnectProxyConfig{ 123 LocalServiceAddress: "", 124 LocalServicePort: 0, 125 Upstreams: nil, 126 Expose: api.ExposeConfig{}, 127 Config: map[string]interface{}{ 128 "bind_address": "0.0.0.0", 129 "bind_port": 2000, 130 }, 131 }, proxy) 132 }) 133 134 t.Run("bad proxy", func(t *testing.T) { 135 _, err := connectProxy(&structs.ConsulProxy{ 136 LocalServiceAddress: "0.0.0.0", 137 LocalServicePort: 2000, 138 Upstreams: nil, 139 Expose: &structs.ConsulExposeConfig{ 140 Paths: []structs.ConsulExposePath{{ 141 ListenerPort: "badPort", 142 }}, 143 }, 144 Config: nil, 145 }, 2000, testConnectNetwork) 146 require.EqualError(t, err, `No port of label "badPort" defined`) 147 }) 148 149 t.Run("normal", func(t *testing.T) { 150 proxy, err := connectProxy(&structs.ConsulProxy{ 151 LocalServiceAddress: "0.0.0.0", 152 LocalServicePort: 2000, 153 Upstreams: nil, 154 Expose: &structs.ConsulExposeConfig{ 155 Paths: []structs.ConsulExposePath{{ 156 Path: "/health", 157 Protocol: "http", 158 LocalPathPort: 8000, 159 ListenerPort: "healthPort", 160 }}, 161 }, 162 Config: nil, 163 }, 2000, testConnectNetwork) 164 require.NoError(t, err) 165 require.Equal(t, &api.AgentServiceConnectProxyConfig{ 166 LocalServiceAddress: "0.0.0.0", 167 LocalServicePort: 2000, 168 Upstreams: nil, 169 Expose: api.ExposeConfig{ 170 Paths: []api.ExposePath{{ 171 Path: "/health", 172 Protocol: "http", 173 LocalPathPort: 8000, 174 ListenerPort: 23100, 175 }}, 176 }, 177 Config: map[string]interface{}{ 178 "bind_address": "0.0.0.0", 179 "bind_port": 2000, 180 }, 181 }, proxy) 182 }) 183 } 184 185 func TestConnect_connectProxyExpose(t *testing.T) { 186 t.Parallel() 187 188 t.Run("nil", func(t *testing.T) { 189 exposeConfig, err := connectProxyExpose(nil, nil) 190 require.NoError(t, err) 191 require.Equal(t, api.ExposeConfig{}, exposeConfig) 192 }) 193 194 t.Run("bad port", func(t *testing.T) { 195 _, err := connectProxyExpose(&structs.ConsulExposeConfig{ 196 Paths: []structs.ConsulExposePath{{ 197 ListenerPort: "badPort", 198 }}, 199 }, testConnectNetwork) 200 require.EqualError(t, err, `No port of label "badPort" defined`) 201 }) 202 203 t.Run("normal", func(t *testing.T) { 204 expose, err := connectProxyExpose(&structs.ConsulExposeConfig{ 205 Paths: []structs.ConsulExposePath{{ 206 Path: "/health", 207 Protocol: "http", 208 LocalPathPort: 8000, 209 ListenerPort: "healthPort", 210 }}, 211 }, testConnectNetwork) 212 require.NoError(t, err) 213 require.Equal(t, api.ExposeConfig{ 214 Checks: false, 215 Paths: []api.ExposePath{{ 216 Path: "/health", 217 ListenerPort: 23100, 218 LocalPathPort: 8000, 219 Protocol: "http", 220 ParsedFromCheck: false, 221 }}, 222 }, expose) 223 }) 224 } 225 226 func TestConnect_connectProxyExposePaths(t *testing.T) { 227 t.Parallel() 228 229 t.Run("nil", func(t *testing.T) { 230 upstreams, err := connectProxyExposePaths(nil, nil) 231 require.NoError(t, err) 232 require.Empty(t, upstreams) 233 }) 234 235 t.Run("no network", func(t *testing.T) { 236 original := []structs.ConsulExposePath{{Path: "/path"}} 237 _, err := connectProxyExposePaths(original, nil) 238 require.EqualError(t, err, `Connect only supported with exactly 1 network (found 0)`) 239 }) 240 241 t.Run("normal", func(t *testing.T) { 242 original := []structs.ConsulExposePath{{ 243 Path: "/health", 244 Protocol: "http", 245 LocalPathPort: 8000, 246 ListenerPort: "healthPort", 247 }, { 248 Path: "/metrics", 249 Protocol: "grpc", 250 LocalPathPort: 9500, 251 ListenerPort: "metricsPort", 252 }} 253 exposePaths, err := connectProxyExposePaths(original, testConnectNetwork) 254 require.NoError(t, err) 255 require.Equal(t, []api.ExposePath{ 256 { 257 Path: "/health", 258 Protocol: "http", 259 LocalPathPort: 8000, 260 ListenerPort: 23100, 261 ParsedFromCheck: false, 262 }, 263 { 264 Path: "/metrics", 265 Protocol: "grpc", 266 LocalPathPort: 9500, 267 ListenerPort: 23200, 268 ParsedFromCheck: false, 269 }, 270 }, exposePaths) 271 }) 272 } 273 274 func TestConnect_connectUpstreams(t *testing.T) { 275 t.Parallel() 276 277 t.Run("nil", func(t *testing.T) { 278 require.Nil(t, connectUpstreams(nil)) 279 }) 280 281 t.Run("not empty", func(t *testing.T) { 282 require.Equal(t, 283 []api.Upstream{{ 284 DestinationName: "foo", 285 LocalBindPort: 8000, 286 }, { 287 DestinationName: "bar", 288 LocalBindPort: 9000, 289 }}, 290 connectUpstreams([]structs.ConsulUpstream{{ 291 DestinationName: "foo", 292 LocalBindPort: 8000, 293 }, { 294 DestinationName: "bar", 295 LocalBindPort: 9000, 296 }}), 297 ) 298 }) 299 } 300 301 func TestConnect_connectProxyConfig(t *testing.T) { 302 t.Parallel() 303 304 t.Run("nil map", func(t *testing.T) { 305 require.Equal(t, map[string]interface{}{ 306 "bind_address": "0.0.0.0", 307 "bind_port": 42, 308 }, connectProxyConfig(nil, 42)) 309 }) 310 311 t.Run("pre-existing map", func(t *testing.T) { 312 require.Equal(t, map[string]interface{}{ 313 "bind_address": "0.0.0.0", 314 "bind_port": 42, 315 "foo": "bar", 316 }, connectProxyConfig(map[string]interface{}{ 317 "foo": "bar", 318 }, 42)) 319 }) 320 } 321 322 func TestConnect_getConnectPort(t *testing.T) { 323 t.Parallel() 324 325 networks := structs.Networks{{ 326 IP: "192.168.30.1", 327 DynamicPorts: []structs.Port{{ 328 Label: "connect-proxy-foo", 329 Value: 23456, 330 To: 23456, 331 }}}} 332 333 t.Run("normal", func(t *testing.T) { 334 nr, port, err := connectPort("foo", networks) 335 require.NoError(t, err) 336 require.Equal(t, structs.Port{ 337 Label: "connect-proxy-foo", 338 Value: 23456, 339 To: 23456, 340 }, port) 341 require.Equal(t, "192.168.30.1", nr.IP) 342 }) 343 344 t.Run("no such service", func(t *testing.T) { 345 _, _, err := connectPort("other", networks) 346 require.EqualError(t, err, `No Connect port defined for service "other"`) 347 }) 348 349 t.Run("no network", func(t *testing.T) { 350 _, _, err := connectPort("foo", nil) 351 require.EqualError(t, err, "Connect only supported with exactly 1 network (found 0)") 352 }) 353 354 t.Run("multi network", func(t *testing.T) { 355 _, _, err := connectPort("foo", append(networks, &structs.NetworkResource{ 356 Device: "eth1", 357 IP: "10.0.10.0", 358 })) 359 require.EqualError(t, err, "Connect only supported with exactly 1 network (found 2)") 360 }) 361 } 362 363 func TestConnect_getExposePathPort(t *testing.T) { 364 t.Parallel() 365 366 networks := structs.Networks{{ 367 Device: "eth0", 368 IP: "192.168.30.1", 369 DynamicPorts: []structs.Port{{ 370 Label: "myPort", 371 Value: 23456, 372 To: 23456, 373 }}}} 374 375 t.Run("normal", func(t *testing.T) { 376 ip, port, err := connectExposePathPort("myPort", networks) 377 require.NoError(t, err) 378 require.Equal(t, ip, "192.168.30.1") 379 require.Equal(t, 23456, port) 380 }) 381 382 t.Run("no such port label", func(t *testing.T) { 383 _, _, err := connectExposePathPort("otherPort", networks) 384 require.EqualError(t, err, `No port of label "otherPort" defined`) 385 }) 386 387 t.Run("no network", func(t *testing.T) { 388 _, _, err := connectExposePathPort("myPort", nil) 389 require.EqualError(t, err, "Connect only supported with exactly 1 network (found 0)") 390 }) 391 392 t.Run("multi network", func(t *testing.T) { 393 _, _, err := connectExposePathPort("myPort", append(networks, &structs.NetworkResource{ 394 Device: "eth1", 395 IP: "10.0.10.0", 396 })) 397 require.EqualError(t, err, "Connect only supported with exactly 1 network (found 2)") 398 }) 399 }