github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/serviceregistration/address_test.go (about) 1 package serviceregistration 2 3 import ( 4 "testing" 5 6 "github.com/hashicorp/nomad/nomad/structs" 7 "github.com/hashicorp/nomad/plugins/drivers" 8 "github.com/stretchr/testify/require" 9 ) 10 11 func Test_GetAddress(t *testing.T) { 12 const HostIP = "127.0.0.1" 13 14 testCases := []struct { 15 name string 16 17 // Inputs 18 advertise string 19 mode string 20 portLabel string 21 host map[string]int // will be converted to structs.Networks 22 driver *drivers.DriverNetwork 23 ports structs.AllocatedPorts 24 status *structs.AllocNetworkStatus 25 26 // Expectations 27 expIP string 28 expPort int 29 expErr string 30 }{ 31 // Valid Configurations 32 { 33 name: "ExampleService", 34 mode: structs.AddressModeAuto, 35 portLabel: "db", 36 host: map[string]int{"db": 12435}, 37 driver: &drivers.DriverNetwork{ 38 PortMap: map[string]int{"db": 6379}, 39 IP: "10.1.2.3", 40 }, 41 expIP: HostIP, 42 expPort: 12435, 43 }, 44 { 45 name: "host", 46 mode: structs.AddressModeHost, 47 portLabel: "db", 48 host: map[string]int{"db": 12345}, 49 driver: &drivers.DriverNetwork{ 50 PortMap: map[string]int{"db": 6379}, 51 IP: "10.1.2.3", 52 }, 53 expIP: HostIP, 54 expPort: 12345, 55 }, 56 { 57 name: "driver", 58 mode: structs.AddressModeDriver, 59 portLabel: "db", 60 host: map[string]int{"db": 12345}, 61 driver: &drivers.DriverNetwork{ 62 PortMap: map[string]int{"db": 6379}, 63 IP: "10.1.2.3", 64 }, 65 expIP: "10.1.2.3", 66 expPort: 6379, 67 }, 68 { 69 name: "AutoDriver", 70 mode: structs.AddressModeAuto, 71 portLabel: "db", 72 host: map[string]int{"db": 12345}, 73 driver: &drivers.DriverNetwork{ 74 PortMap: map[string]int{"db": 6379}, 75 IP: "10.1.2.3", 76 AutoAdvertise: true, 77 }, 78 expIP: "10.1.2.3", 79 expPort: 6379, 80 }, 81 { 82 name: "DriverCustomPort", 83 mode: structs.AddressModeDriver, 84 portLabel: "7890", 85 host: map[string]int{"db": 12345}, 86 driver: &drivers.DriverNetwork{ 87 PortMap: map[string]int{"db": 6379}, 88 IP: "10.1.2.3", 89 }, 90 expIP: "10.1.2.3", 91 expPort: 7890, 92 }, 93 94 // Invalid Configurations 95 { 96 name: "DriverWithoutNetwork", 97 mode: structs.AddressModeDriver, 98 portLabel: "db", 99 host: map[string]int{"db": 12345}, 100 driver: nil, 101 expErr: "no driver network exists", 102 }, 103 { 104 name: "DriverBadPort", 105 mode: structs.AddressModeDriver, 106 portLabel: "bad-port-label", 107 host: map[string]int{"db": 12345}, 108 driver: &drivers.DriverNetwork{ 109 PortMap: map[string]int{"db": 6379}, 110 IP: "10.1.2.3", 111 }, 112 expErr: "invalid port", 113 }, 114 { 115 name: "DriverZeroPort", 116 mode: structs.AddressModeDriver, 117 portLabel: "0", 118 driver: &drivers.DriverNetwork{ 119 IP: "10.1.2.3", 120 }, 121 expErr: "invalid port", 122 }, 123 { 124 name: "HostBadPort", 125 mode: structs.AddressModeHost, 126 portLabel: "bad-port-label", 127 expErr: "invalid port", 128 }, 129 { 130 name: "InvalidMode", 131 mode: "invalid-mode", 132 portLabel: "80", 133 expErr: "invalid address mode", 134 }, 135 { 136 name: "NoPort_AutoMode", 137 mode: structs.AddressModeAuto, 138 expIP: HostIP, 139 }, 140 { 141 name: "NoPort_HostMode", 142 mode: structs.AddressModeHost, 143 expIP: HostIP, 144 }, 145 { 146 name: "NoPort_DriverMode", 147 mode: structs.AddressModeDriver, 148 driver: &drivers.DriverNetwork{ 149 IP: "10.1.2.3", 150 }, 151 expIP: "10.1.2.3", 152 }, 153 154 // Scenarios using port 0.12 networking fields (NetworkStatus, AllocatedPortMapping) 155 { 156 name: "ExampleServer_withAllocatedPorts", 157 mode: structs.AddressModeAuto, 158 portLabel: "db", 159 ports: []structs.AllocatedPortMapping{ 160 { 161 Label: "db", 162 Value: 12435, 163 To: 6379, 164 HostIP: HostIP, 165 }, 166 }, 167 status: &structs.AllocNetworkStatus{ 168 InterfaceName: "eth0", 169 Address: "172.26.0.1", 170 }, 171 expIP: HostIP, 172 expPort: 12435, 173 }, 174 { 175 name: "Host_withAllocatedPorts", 176 mode: structs.AddressModeHost, 177 portLabel: "db", 178 ports: []structs.AllocatedPortMapping{ 179 { 180 Label: "db", 181 Value: 12345, 182 To: 6379, 183 HostIP: HostIP, 184 }, 185 }, 186 status: &structs.AllocNetworkStatus{ 187 InterfaceName: "eth0", 188 Address: "172.26.0.1", 189 }, 190 expIP: HostIP, 191 expPort: 12345, 192 }, 193 { 194 name: "Driver_withAllocatedPorts", 195 mode: structs.AddressModeDriver, 196 portLabel: "db", 197 ports: []structs.AllocatedPortMapping{ 198 { 199 Label: "db", 200 Value: 12345, 201 To: 6379, 202 HostIP: HostIP, 203 }, 204 }, 205 driver: &drivers.DriverNetwork{ 206 IP: "10.1.2.3", 207 }, 208 status: &structs.AllocNetworkStatus{ 209 InterfaceName: "eth0", 210 Address: "172.26.0.1", 211 }, 212 expIP: "10.1.2.3", 213 expPort: 6379, 214 }, 215 { 216 name: "AutoDriver_withAllocatedPorts", 217 mode: structs.AddressModeAuto, 218 portLabel: "db", 219 ports: []structs.AllocatedPortMapping{ 220 { 221 Label: "db", 222 Value: 12345, 223 To: 6379, 224 HostIP: HostIP, 225 }, 226 }, 227 driver: &drivers.DriverNetwork{ 228 IP: "10.1.2.3", 229 AutoAdvertise: true, 230 }, 231 status: &structs.AllocNetworkStatus{ 232 InterfaceName: "eth0", 233 Address: "172.26.0.1", 234 }, 235 expIP: "10.1.2.3", 236 expPort: 6379, 237 }, 238 { 239 name: "DriverCustomPort_withAllocatedPorts", 240 mode: structs.AddressModeDriver, 241 portLabel: "7890", 242 ports: []structs.AllocatedPortMapping{ 243 { 244 Label: "db", 245 Value: 12345, 246 To: 6379, 247 HostIP: HostIP, 248 }, 249 }, 250 driver: &drivers.DriverNetwork{ 251 IP: "10.1.2.3", 252 }, 253 status: &structs.AllocNetworkStatus{ 254 InterfaceName: "eth0", 255 Address: "172.26.0.1", 256 }, 257 expIP: "10.1.2.3", 258 expPort: 7890, 259 }, 260 { 261 name: "Host_MultiHostInterface", 262 mode: structs.AddressModeAuto, 263 portLabel: "db", 264 ports: []structs.AllocatedPortMapping{ 265 { 266 Label: "db", 267 Value: 12345, 268 To: 6379, 269 HostIP: "127.0.0.100", 270 }, 271 }, 272 status: &structs.AllocNetworkStatus{ 273 InterfaceName: "eth0", 274 Address: "172.26.0.1", 275 }, 276 expIP: "127.0.0.100", 277 expPort: 12345, 278 }, 279 { 280 name: "Alloc", 281 mode: structs.AddressModeAlloc, 282 portLabel: "db", 283 ports: []structs.AllocatedPortMapping{ 284 { 285 Label: "db", 286 Value: 12345, 287 To: 6379, 288 HostIP: HostIP, 289 }, 290 }, 291 status: &structs.AllocNetworkStatus{ 292 InterfaceName: "eth0", 293 Address: "172.26.0.1", 294 }, 295 expIP: "172.26.0.1", 296 expPort: 6379, 297 }, 298 { 299 name: "Alloc no to value", 300 mode: structs.AddressModeAlloc, 301 portLabel: "db", 302 ports: []structs.AllocatedPortMapping{ 303 { 304 Label: "db", 305 Value: 12345, 306 HostIP: HostIP, 307 }, 308 }, 309 status: &structs.AllocNetworkStatus{ 310 InterfaceName: "eth0", 311 Address: "172.26.0.1", 312 }, 313 expIP: "172.26.0.1", 314 expPort: 12345, 315 }, 316 { 317 name: "AllocCustomPort", 318 mode: structs.AddressModeAlloc, 319 portLabel: "6379", 320 status: &structs.AllocNetworkStatus{ 321 InterfaceName: "eth0", 322 Address: "172.26.0.1", 323 }, 324 expIP: "172.26.0.1", 325 expPort: 6379, 326 }, 327 // Cases for setting the address field 328 { 329 name: "Address", 330 mode: structs.AddressModeAuto, 331 advertise: "example.com", 332 expIP: "example.com", 333 expPort: 0, 334 }, 335 { 336 name: "Address with numeric port", 337 mode: structs.AddressModeAuto, 338 advertise: "example.com", 339 portLabel: "8080", 340 expIP: "example.com", 341 expPort: 8080, 342 }, 343 { 344 name: "Address with mapped port", 345 mode: structs.AddressModeAuto, 346 portLabel: "web", 347 advertise: "example.com", 348 ports: []structs.AllocatedPortMapping{ 349 { 350 Label: "web", 351 Value: 12345, 352 HostIP: HostIP, 353 }, 354 }, 355 expIP: "example.com", 356 expPort: 12345, 357 }, 358 { 359 name: "Address with invalid mapped port", 360 mode: structs.AddressModeAuto, 361 advertise: "example.com", 362 portLabel: "foobar", 363 expErr: `invalid port: "foobar": not a valid port mapping or numeric port`, 364 }, 365 { 366 name: "Address with host mode", 367 mode: structs.AddressModeHost, 368 advertise: "example.com", 369 expErr: `cannot use custom advertise address with "host" address mode`, 370 }, 371 { 372 name: "Address with driver mode", 373 mode: structs.AddressModeDriver, 374 advertise: "example.com", 375 expErr: `cannot use custom advertise address with "driver" address mode`, 376 }, 377 { 378 name: "Address with alloc mode", 379 mode: structs.AddressModeAlloc, 380 advertise: "example.com", 381 expErr: `cannot use custom advertise address with "alloc" address mode`, 382 }, 383 } 384 385 for _, tc := range testCases { 386 t.Run(tc.name, func(t *testing.T) { 387 388 // Convert host port map into a structs.Networks. 389 networks := []*structs.NetworkResource{ 390 { 391 IP: HostIP, 392 ReservedPorts: make([]structs.Port, len(tc.host)), 393 }, 394 } 395 396 i := 0 397 for label, port := range tc.host { 398 networks[0].ReservedPorts[i].Label = label 399 networks[0].ReservedPorts[i].Value = port 400 i++ 401 } 402 403 // Run the GetAddress function. 404 actualIP, actualPort, actualErr := GetAddress( 405 tc.advertise, 406 tc.mode, 407 tc.portLabel, 408 networks, 409 tc.driver, 410 tc.ports, 411 tc.status, 412 ) 413 414 // Assert the results 415 require.Equal(t, tc.expIP, actualIP, "IP mismatch") 416 require.Equal(t, tc.expPort, actualPort, "Port mismatch") 417 if tc.expErr == "" { 418 require.Nil(t, actualErr) 419 } else { 420 require.Error(t, actualErr) 421 require.Contains(t, actualErr.Error(), tc.expErr) 422 } 423 }) 424 } 425 }