github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/client/taskenv/services_test.go (about) 1 package taskenv 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/hashicorp/nomad/helper" 8 "github.com/hashicorp/nomad/nomad/structs" 9 "github.com/stretchr/testify/require" 10 ) 11 12 // TestInterpolateServices asserts that all service 13 // and check fields are properly interpolated. 14 func TestInterpolateServices(t *testing.T) { 15 t.Parallel() 16 17 services := []*structs.Service{ 18 { 19 Name: "${name}", 20 PortLabel: "${portlabel}", 21 Tags: []string{"${tags}"}, 22 Meta: map[string]string{ 23 "meta-key": "${meta}", 24 }, 25 CanaryMeta: map[string]string{ 26 "canarymeta-key": "${canarymeta}", 27 }, 28 Checks: []*structs.ServiceCheck{ 29 { 30 Name: "${checkname}", 31 Type: "${checktype}", 32 Command: "${checkcmd}", 33 Args: []string{"${checkarg}"}, 34 Path: "${checkstr}", 35 Protocol: "${checkproto}", 36 PortLabel: "${checklabel}", 37 InitialStatus: "${checkstatus}", 38 Method: "${checkmethod}", 39 Header: map[string][]string{ 40 "${checkheaderk}": {"${checkheaderv}"}, 41 }, 42 }, 43 }, 44 }, 45 } 46 47 env := &TaskEnv{ 48 EnvMap: map[string]string{ 49 "name": "name", 50 "portlabel": "portlabel", 51 "tags": "tags", 52 "meta": "meta-value", 53 "canarymeta": "canarymeta-value", 54 "checkname": "checkname", 55 "checktype": "checktype", 56 "checkcmd": "checkcmd", 57 "checkarg": "checkarg", 58 "checkstr": "checkstr", 59 "checkpath": "checkpath", 60 "checkproto": "checkproto", 61 "checklabel": "checklabel", 62 "checkstatus": "checkstatus", 63 "checkmethod": "checkmethod", 64 "checkheaderk": "checkheaderk", 65 "checkheaderv": "checkheaderv", 66 }, 67 } 68 69 interpolated := InterpolateServices(env, services) 70 71 exp := []*structs.Service{ 72 { 73 Name: "name", 74 PortLabel: "portlabel", 75 Tags: []string{"tags"}, 76 Meta: map[string]string{ 77 "meta-key": "meta-value", 78 }, 79 CanaryMeta: map[string]string{ 80 "canarymeta-key": "canarymeta-value", 81 }, 82 Checks: []*structs.ServiceCheck{ 83 { 84 Name: "checkname", 85 Type: "checktype", 86 Command: "checkcmd", 87 Args: []string{"checkarg"}, 88 Path: "checkstr", 89 Protocol: "checkproto", 90 PortLabel: "checklabel", 91 InitialStatus: "checkstatus", 92 Method: "checkmethod", 93 Header: map[string][]string{ 94 "checkheaderk": {"checkheaderv"}, 95 }, 96 }, 97 }, 98 }, 99 } 100 101 require.Equal(t, exp, interpolated) 102 } 103 104 var testEnv = NewTaskEnv( 105 map[string]string{"foo": "bar", "baz": "blah"}, 106 map[string]string{"foo": "bar", "baz": "blah"}, 107 nil, nil, "", "") 108 109 func TestInterpolate_interpolateMapStringSliceString(t *testing.T) { 110 t.Parallel() 111 112 t.Run("nil", func(t *testing.T) { 113 require.Nil(t, interpolateMapStringSliceString(testEnv, nil)) 114 }) 115 116 t.Run("not nil", func(t *testing.T) { 117 require.Equal(t, map[string][]string{ 118 "a": {"b"}, 119 "bar": {"blah", "c"}, 120 }, interpolateMapStringSliceString(testEnv, map[string][]string{ 121 "a": {"b"}, 122 "${foo}": {"${baz}", "c"}, 123 })) 124 }) 125 } 126 127 func TestInterpolate_interpolateMapStringString(t *testing.T) { 128 t.Parallel() 129 130 t.Run("nil", func(t *testing.T) { 131 require.Nil(t, interpolateMapStringString(testEnv, nil)) 132 }) 133 134 t.Run("not nil", func(t *testing.T) { 135 require.Equal(t, map[string]string{ 136 "a": "b", 137 "bar": "blah", 138 }, interpolateMapStringString(testEnv, map[string]string{ 139 "a": "b", 140 "${foo}": "${baz}", 141 })) 142 }) 143 } 144 145 func TestInterpolate_interpolateMapStringInterface(t *testing.T) { 146 t.Parallel() 147 148 t.Run("nil", func(t *testing.T) { 149 require.Nil(t, interpolateMapStringInterface(testEnv, nil)) 150 }) 151 152 t.Run("not nil", func(t *testing.T) { 153 require.Equal(t, map[string]interface{}{ 154 "a": 1, 155 "bar": 2, 156 }, interpolateMapStringInterface(testEnv, map[string]interface{}{ 157 "a": 1, 158 "${foo}": 2, 159 })) 160 }) 161 } 162 163 func TestInterpolate_interpolateConnect(t *testing.T) { 164 t.Parallel() 165 166 e := map[string]string{ 167 "tag1": "_tag1", 168 "port1": "12345", 169 "address1": "1.2.3.4", 170 "destination1": "_dest1", 171 "datacenter1": "_datacenter1", 172 "localbindaddress1": "127.0.0.2", 173 "path1": "_path1", 174 "protocol1": "_protocol1", 175 "port2": "_port2", 176 "config1": "_config1", 177 "driver1": "_driver1", 178 "user1": "_user1", 179 "config2": "_config2", 180 "env1": "_env1", 181 "env2": "_env2", 182 "mode1": "_mode1", 183 "device1": "_device1", 184 "cidr1": "10.0.0.0/64", 185 "ip1": "1.1.1.1", 186 "server1": "10.0.0.1", 187 "search1": "10.0.0.2", 188 "option1": "10.0.0.3", 189 "port3": "_port3", 190 "network1": "_network1", 191 "port4": "_port4", 192 "network2": "_network2", 193 "resource1": "_resource1", 194 "meta1": "_meta1", 195 "meta2": "_meta2", 196 "signal1": "_signal1", 197 "bind1": "_bind1", 198 "address2": "10.0.0.4", 199 "config3": "_config3", 200 "protocol2": "_protocol2", 201 "service1": "_service1", 202 "host1": "_host1", 203 } 204 env := NewTaskEnv(e, e, nil, nil, "", "") 205 206 connect := &structs.ConsulConnect{ 207 Native: false, 208 SidecarService: &structs.ConsulSidecarService{ 209 Tags: []string{"${tag1}", "tag2"}, 210 Port: "${port1}", 211 Proxy: &structs.ConsulProxy{ 212 LocalServiceAddress: "${address1}", 213 LocalServicePort: 10000, 214 Upstreams: []structs.ConsulUpstream{{ 215 DestinationName: "${destination1}", 216 Datacenter: "${datacenter1}", 217 LocalBindPort: 10001, 218 LocalBindAddress: "${localbindaddress1}", 219 }}, 220 Expose: &structs.ConsulExposeConfig{ 221 Paths: []structs.ConsulExposePath{{ 222 Path: "${path1}", 223 Protocol: "${protocol1}", 224 ListenerPort: "${port2}", 225 LocalPathPort: 10002, 226 }}, 227 }, 228 Config: map[string]interface{}{ 229 "${config1}": 1, 230 }, 231 }, 232 }, 233 SidecarTask: &structs.SidecarTask{ 234 Name: "name", // not interpolated by taskenv 235 Driver: "${driver1}", 236 User: "${user1}", 237 Config: map[string]interface{}{"${config2}": 2}, 238 Env: map[string]string{"${env1}": "${env2}"}, 239 Resources: &structs.Resources{ 240 CPU: 1, 241 MemoryMB: 2, 242 DiskMB: 3, 243 IOPS: 4, 244 Networks: structs.Networks{{ 245 Mode: "${mode1}", 246 Device: "${device1}", 247 CIDR: "${cidr1}", 248 IP: "${ip1}", 249 MBits: 1, 250 DNS: &structs.DNSConfig{ 251 Servers: []string{"${server1}"}, 252 Searches: []string{"${search1}"}, 253 Options: []string{"${option1}"}, 254 }, 255 ReservedPorts: []structs.Port{{ 256 Label: "${port3}", 257 Value: 9000, 258 To: 9000, 259 HostNetwork: "${network1}", 260 }}, 261 DynamicPorts: []structs.Port{{ 262 Label: "${port4}", 263 Value: 9001, 264 To: 9001, 265 HostNetwork: "${network2}", 266 }}, 267 }}, 268 Devices: structs.ResourceDevices{{ 269 Name: "${resource1}", 270 }}, 271 }, 272 Meta: map[string]string{"${meta1}": "${meta2}"}, 273 KillTimeout: helper.TimeToPtr(1 * time.Second), 274 LogConfig: &structs.LogConfig{ 275 MaxFiles: 1, 276 MaxFileSizeMB: 2, 277 }, 278 ShutdownDelay: helper.TimeToPtr(2 * time.Second), 279 KillSignal: "${signal1}", 280 }, 281 Gateway: &structs.ConsulGateway{ 282 Proxy: &structs.ConsulGatewayProxy{ 283 ConnectTimeout: helper.TimeToPtr(3 * time.Second), 284 EnvoyGatewayBindTaggedAddresses: true, 285 EnvoyGatewayBindAddresses: map[string]*structs.ConsulGatewayBindAddress{ 286 "${bind1}": { 287 Address: "${address2}", 288 Port: 8000, 289 }, 290 }, 291 EnvoyGatewayNoDefaultBind: true, 292 Config: map[string]interface{}{ 293 "${config3}": 4, 294 }, 295 }, 296 Ingress: &structs.ConsulIngressConfigEntry{ 297 TLS: &structs.ConsulGatewayTLSConfig{ 298 Enabled: true, 299 }, 300 Listeners: []*structs.ConsulIngressListener{{ 301 Protocol: "${protocol2}", 302 Port: 8001, 303 Services: []*structs.ConsulIngressService{{ 304 Name: "${service1}", 305 Hosts: []string{"${host1}", "host2"}, 306 }}, 307 }}, 308 }, 309 }, 310 } 311 312 interpolateConnect(env, connect) 313 314 require.Equal(t, &structs.ConsulConnect{ 315 Native: false, 316 SidecarService: &structs.ConsulSidecarService{ 317 Tags: []string{"_tag1", "tag2"}, 318 Port: "12345", 319 Proxy: &structs.ConsulProxy{ 320 LocalServiceAddress: "1.2.3.4", 321 LocalServicePort: 10000, 322 Upstreams: []structs.ConsulUpstream{{ 323 DestinationName: "_dest1", 324 Datacenter: "_datacenter1", 325 LocalBindPort: 10001, 326 LocalBindAddress: "127.0.0.2", 327 }}, 328 Expose: &structs.ConsulExposeConfig{ 329 Paths: []structs.ConsulExposePath{{ 330 Path: "_path1", 331 Protocol: "_protocol1", 332 ListenerPort: "_port2", 333 LocalPathPort: 10002, 334 }}, 335 }, 336 Config: map[string]interface{}{ 337 "_config1": 1, 338 }, 339 }, 340 }, 341 SidecarTask: &structs.SidecarTask{ 342 Name: "name", // not interpolated by InterpolateServices 343 Driver: "_driver1", 344 User: "_user1", 345 Config: map[string]interface{}{"_config2": 2}, 346 Env: map[string]string{"_env1": "_env2"}, 347 Resources: &structs.Resources{ 348 CPU: 1, 349 MemoryMB: 2, 350 DiskMB: 3, 351 IOPS: 4, 352 Networks: structs.Networks{{ 353 Mode: "_mode1", 354 Device: "_device1", 355 CIDR: "10.0.0.0/64", 356 IP: "1.1.1.1", 357 MBits: 1, 358 DNS: &structs.DNSConfig{ 359 Servers: []string{"10.0.0.1"}, 360 Searches: []string{"10.0.0.2"}, 361 Options: []string{"10.0.0.3"}, 362 }, 363 ReservedPorts: []structs.Port{{ 364 Label: "_port3", 365 Value: 9000, 366 To: 9000, 367 HostNetwork: "_network1", 368 }}, 369 DynamicPorts: []structs.Port{{ 370 Label: "_port4", 371 Value: 9001, 372 To: 9001, 373 HostNetwork: "_network2", 374 }}, 375 }}, 376 Devices: structs.ResourceDevices{{ 377 Name: "_resource1", 378 }}, 379 }, 380 Meta: map[string]string{"_meta1": "_meta2"}, 381 KillTimeout: helper.TimeToPtr(1 * time.Second), 382 LogConfig: &structs.LogConfig{ 383 MaxFiles: 1, 384 MaxFileSizeMB: 2, 385 }, 386 ShutdownDelay: helper.TimeToPtr(2 * time.Second), 387 KillSignal: "_signal1", 388 }, 389 Gateway: &structs.ConsulGateway{ 390 Proxy: &structs.ConsulGatewayProxy{ 391 ConnectTimeout: helper.TimeToPtr(3 * time.Second), 392 EnvoyGatewayBindTaggedAddresses: true, 393 EnvoyGatewayBindAddresses: map[string]*structs.ConsulGatewayBindAddress{ 394 "_bind1": { 395 Address: "10.0.0.4", 396 Port: 8000, 397 }, 398 }, 399 EnvoyGatewayNoDefaultBind: true, 400 Config: map[string]interface{}{ 401 "_config3": 4, 402 }, 403 }, 404 Ingress: &structs.ConsulIngressConfigEntry{ 405 TLS: &structs.ConsulGatewayTLSConfig{ 406 Enabled: true, 407 }, 408 Listeners: []*structs.ConsulIngressListener{{ 409 Protocol: "_protocol2", 410 Port: 8001, 411 Services: []*structs.ConsulIngressService{{ 412 Name: "_service1", 413 Hosts: []string{"_host1", "host2"}, 414 }}, 415 }}, 416 }, 417 }, 418 }, connect) 419 }