github.com/hernad/nomad@v1.6.112/nomad/mock/connect.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package mock 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/hernad/nomad/helper/envoy" 11 "github.com/hernad/nomad/helper/pointer" 12 "github.com/hernad/nomad/helper/uuid" 13 "github.com/hernad/nomad/nomad/structs" 14 ) 15 16 // ConnectJob adds a Connect proxy sidecar group service to mock.Job. 17 // 18 // Note this does *not* include the Job.Register mutation that inserts the 19 // associated Sidecar Task (nor the hook that configures envoy as the default). 20 func ConnectJob() *structs.Job { 21 job := Job() 22 tg := job.TaskGroups[0] 23 tg.Services = []*structs.Service{{ 24 Name: "testconnect", 25 PortLabel: "9999", 26 Connect: &structs.ConsulConnect{ 27 SidecarService: new(structs.ConsulSidecarService), 28 }, 29 }} 30 tg.Networks = structs.Networks{{ 31 Mode: "bridge", // always bridge ... for now? 32 }} 33 return job 34 } 35 36 func ConnectNativeJob(mode string) *structs.Job { 37 job := Job() 38 tg := job.TaskGroups[0] 39 tg.Networks = []*structs.NetworkResource{{ 40 Mode: mode, 41 }} 42 tg.Services = []*structs.Service{{ 43 Name: "test_connect_native", 44 PortLabel: "9999", 45 Connect: &structs.ConsulConnect{ 46 Native: true, 47 }, 48 }} 49 tg.Tasks = []*structs.Task{{ 50 Name: "native_task", 51 }} 52 return job 53 } 54 55 // ConnectIngressGatewayJob creates a structs.Job that contains the definition 56 // of a Consul Ingress Gateway service. The mode is the name of the network 57 // mode assumed by the task group. If inject is true, a corresponding Task is 58 // set on the group's Tasks (i.e. what the job would look like after job mutation). 59 func ConnectIngressGatewayJob(mode string, inject bool) *structs.Job { 60 job := Job() 61 tg := job.TaskGroups[0] 62 tg.Networks = []*structs.NetworkResource{{ 63 Mode: mode, 64 }} 65 tg.Services = []*structs.Service{{ 66 Name: "my-ingress-service", 67 PortLabel: "9999", 68 Connect: &structs.ConsulConnect{ 69 Gateway: &structs.ConsulGateway{ 70 Proxy: &structs.ConsulGatewayProxy{ 71 ConnectTimeout: pointer.Of(3 * time.Second), 72 EnvoyGatewayBindAddresses: make(map[string]*structs.ConsulGatewayBindAddress), 73 }, 74 Ingress: &structs.ConsulIngressConfigEntry{ 75 Listeners: []*structs.ConsulIngressListener{{ 76 Port: 2000, 77 Protocol: "tcp", 78 Services: []*structs.ConsulIngressService{{ 79 Name: "service1", 80 }}, 81 }}, 82 }, 83 }, 84 }, 85 }} 86 87 tg.Tasks = nil 88 89 // some tests need to assume the gateway proxy task has already been injected 90 if inject { 91 tg.Tasks = []*structs.Task{{ 92 Name: fmt.Sprintf("%s-%s", structs.ConnectIngressPrefix, "my-ingress-service"), 93 Kind: structs.NewTaskKind(structs.ConnectIngressPrefix, "my-ingress-service"), 94 Driver: "docker", 95 Config: make(map[string]interface{}), 96 ShutdownDelay: 5 * time.Second, 97 LogConfig: &structs.LogConfig{ 98 MaxFiles: 2, 99 MaxFileSizeMB: 2, 100 }, 101 }} 102 } 103 return job 104 } 105 106 // ConnectTerminatingGatewayJob creates a structs.Job that contains the definition 107 // of a Consul Terminating Gateway service. The mode is the name of the network mode 108 // assumed by the task group. If inject is true, a corresponding task is set on the 109 // group's Tasks (i.e. what the job would look like after mutation). 110 func ConnectTerminatingGatewayJob(mode string, inject bool) *structs.Job { 111 job := Job() 112 tg := job.TaskGroups[0] 113 tg.Networks = []*structs.NetworkResource{{ 114 Mode: mode, 115 }} 116 tg.Services = []*structs.Service{{ 117 Name: "my-terminating-service", 118 PortLabel: "9999", 119 Connect: &structs.ConsulConnect{ 120 Gateway: &structs.ConsulGateway{ 121 Proxy: &structs.ConsulGatewayProxy{ 122 ConnectTimeout: pointer.Of(3 * time.Second), 123 EnvoyGatewayBindAddresses: make(map[string]*structs.ConsulGatewayBindAddress), 124 }, 125 Terminating: &structs.ConsulTerminatingConfigEntry{ 126 Services: []*structs.ConsulLinkedService{{ 127 Name: "service1", 128 CAFile: "/ssl/ca_file", 129 CertFile: "/ssl/cert_file", 130 KeyFile: "/ssl/key_file", 131 SNI: "sni-name", 132 }}, 133 }, 134 }, 135 }, 136 }} 137 138 tg.Tasks = nil 139 140 // some tests need to assume the gateway proxy task has already been injected 141 if inject { 142 tg.Tasks = []*structs.Task{{ 143 Name: fmt.Sprintf("%s-%s", structs.ConnectTerminatingPrefix, "my-terminating-service"), 144 Kind: structs.NewTaskKind(structs.ConnectTerminatingPrefix, "my-terminating-service"), 145 Driver: "docker", 146 Config: make(map[string]interface{}), 147 ShutdownDelay: 5 * time.Second, 148 LogConfig: &structs.LogConfig{ 149 MaxFiles: 2, 150 MaxFileSizeMB: 2, 151 }, 152 }} 153 } 154 return job 155 } 156 157 // ConnectMeshGatewayJob creates a structs.Job that contains the definition of a 158 // Consul Mesh Gateway service. The mode is the name of the network mode assumed 159 // by the task group. If inject is true, a corresponding task is set on the group's 160 // Tasks (i.e. what the job would look like after job mutation). 161 func ConnectMeshGatewayJob(mode string, inject bool) *structs.Job { 162 job := Job() 163 tg := job.TaskGroups[0] 164 tg.Networks = []*structs.NetworkResource{{ 165 Mode: mode, 166 }} 167 tg.Services = []*structs.Service{{ 168 Name: "my-mesh-service", 169 PortLabel: "public_port", 170 Connect: &structs.ConsulConnect{ 171 Gateway: &structs.ConsulGateway{ 172 Proxy: &structs.ConsulGatewayProxy{ 173 ConnectTimeout: pointer.Of(3 * time.Second), 174 EnvoyGatewayBindAddresses: make(map[string]*structs.ConsulGatewayBindAddress), 175 }, 176 Mesh: &structs.ConsulMeshConfigEntry{ 177 // nothing to configure 178 }, 179 }, 180 }, 181 }} 182 183 tg.Tasks = nil 184 185 // some tests need to assume the gateway task has already been injected 186 if inject { 187 tg.Tasks = []*structs.Task{{ 188 Name: fmt.Sprintf("%s-%s", structs.ConnectMeshPrefix, "my-mesh-service"), 189 Kind: structs.NewTaskKind(structs.ConnectMeshPrefix, "my-mesh-service"), 190 Driver: "docker", 191 Config: make(map[string]interface{}), 192 ShutdownDelay: 5 * time.Second, 193 LogConfig: &structs.LogConfig{ 194 MaxFiles: 2, 195 MaxFileSizeMB: 2, 196 }, 197 }} 198 } 199 return job 200 } 201 202 func BatchConnectJob() *structs.Job { 203 job := &structs.Job{ 204 Region: "global", 205 ID: fmt.Sprintf("mock-connect-batch-job%s", uuid.Generate()), 206 Name: "mock-connect-batch-job", 207 Namespace: structs.DefaultNamespace, 208 Type: structs.JobTypeBatch, 209 Priority: 50, 210 AllAtOnce: false, 211 Datacenters: []string{"dc1"}, 212 TaskGroups: []*structs.TaskGroup{{ 213 Name: "mock-connect-batch-job", 214 Count: 1, 215 EphemeralDisk: &structs.EphemeralDisk{SizeMB: 150}, 216 Networks: []*structs.NetworkResource{{ 217 Mode: "bridge", 218 }}, 219 Tasks: []*structs.Task{{ 220 Name: "connect-proxy-testconnect", 221 Kind: "connect-proxy:testconnect", 222 Driver: "mock_driver", 223 Config: map[string]interface{}{ 224 "run_for": "500ms", 225 }, 226 LogConfig: structs.DefaultLogConfig(), 227 Resources: &structs.Resources{ 228 CPU: 500, 229 MemoryMB: 256, 230 Networks: []*structs.NetworkResource{{ 231 MBits: 50, 232 DynamicPorts: []structs.Port{{Label: "port1"}}, 233 }}, 234 }, 235 }}, 236 Services: []*structs.Service{{ 237 Name: "testconnect", 238 }}, 239 }}, 240 Meta: map[string]string{"owner": "shoenig"}, 241 Status: structs.JobStatusPending, 242 Version: 0, 243 CreateIndex: 42, 244 ModifyIndex: 99, 245 JobModifyIndex: 99, 246 } 247 job.Canonicalize() 248 return job 249 } 250 251 func ConnectSidecarTask() *structs.Task { 252 return &structs.Task{ 253 Name: "mysidecar-sidecar-task", 254 Driver: "docker", 255 User: "nobody", 256 Config: map[string]interface{}{ 257 "image": envoy.SidecarConfigVar, 258 }, 259 Env: nil, 260 Resources: &structs.Resources{ 261 CPU: 150, 262 MemoryMB: 350, 263 }, 264 Kind: structs.NewTaskKind(structs.ConnectProxyPrefix, "mysidecar"), 265 } 266 } 267 268 // ConnectAlloc adds a Connect proxy sidecar group service to mock.Alloc. 269 func ConnectAlloc() *structs.Allocation { 270 alloc := Alloc() 271 alloc.Job = ConnectJob() 272 alloc.AllocatedResources.Shared.Networks = []*structs.NetworkResource{ 273 { 274 Mode: "bridge", 275 IP: "10.0.0.1", 276 DynamicPorts: []structs.Port{ 277 { 278 Label: "connect-proxy-testconnect", 279 Value: 9999, 280 To: 9999, 281 }, 282 }, 283 }, 284 } 285 return alloc 286 } 287 288 // ConnectNativeAlloc creates an alloc with a connect native task. 289 func ConnectNativeAlloc(mode string) *structs.Allocation { 290 alloc := Alloc() 291 alloc.Job = ConnectNativeJob(mode) 292 alloc.AllocatedResources.Shared.Networks = []*structs.NetworkResource{{ 293 Mode: mode, 294 IP: "10.0.0.1", 295 }} 296 return alloc 297 } 298 299 func ConnectIngressGatewayAlloc(mode string) *structs.Allocation { 300 alloc := Alloc() 301 alloc.Job = ConnectIngressGatewayJob(mode, true) 302 alloc.AllocatedResources.Shared.Networks = []*structs.NetworkResource{{ 303 Mode: mode, 304 IP: "10.0.0.1", 305 }} 306 return alloc 307 } 308 309 // BatchConnectAlloc is useful for testing task runner things. 310 func BatchConnectAlloc() *structs.Allocation { 311 alloc := &structs.Allocation{ 312 ID: uuid.Generate(), 313 EvalID: uuid.Generate(), 314 NodeID: "12345678-abcd-efab-cdef-123456789abc", 315 Namespace: structs.DefaultNamespace, 316 TaskGroup: "mock-connect-batch-job", 317 TaskResources: map[string]*structs.Resources{ 318 "connect-proxy-testconnect": { 319 CPU: 500, 320 MemoryMB: 256, 321 }, 322 }, 323 324 AllocatedResources: &structs.AllocatedResources{ 325 Tasks: map[string]*structs.AllocatedTaskResources{ 326 "connect-proxy-testconnect": { 327 Cpu: structs.AllocatedCpuResources{CpuShares: 500}, 328 Memory: structs.AllocatedMemoryResources{MemoryMB: 256}, 329 }, 330 }, 331 Shared: structs.AllocatedSharedResources{ 332 Networks: []*structs.NetworkResource{{ 333 Mode: "bridge", 334 IP: "10.0.0.1", 335 DynamicPorts: []structs.Port{{ 336 Label: "connect-proxy-testconnect", 337 Value: 9999, 338 To: 9999, 339 }}, 340 }}, 341 DiskMB: 0, 342 }, 343 }, 344 Job: BatchConnectJob(), 345 DesiredStatus: structs.AllocDesiredStatusRun, 346 ClientStatus: structs.AllocClientStatusPending, 347 } 348 alloc.JobID = alloc.Job.ID 349 return alloc 350 } 351 352 func BatchAlloc() *structs.Allocation { 353 alloc := &structs.Allocation{ 354 ID: uuid.Generate(), 355 EvalID: uuid.Generate(), 356 NodeID: "12345678-abcd-efab-cdef-123456789abc", 357 Namespace: structs.DefaultNamespace, 358 TaskGroup: "web", 359 360 // TODO Remove once clientv2 gets merged 361 Resources: &structs.Resources{ 362 CPU: 500, 363 MemoryMB: 256, 364 DiskMB: 150, 365 Networks: []*structs.NetworkResource{ 366 { 367 Device: "eth0", 368 IP: "192.168.0.100", 369 ReservedPorts: []structs.Port{{Label: "admin", Value: 5000}}, 370 MBits: 50, 371 DynamicPorts: []structs.Port{{Label: "http"}}, 372 }, 373 }, 374 }, 375 TaskResources: map[string]*structs.Resources{ 376 "web": { 377 CPU: 500, 378 MemoryMB: 256, 379 Networks: []*structs.NetworkResource{ 380 { 381 Device: "eth0", 382 IP: "192.168.0.100", 383 ReservedPorts: []structs.Port{{Label: "admin", Value: 5000}}, 384 MBits: 50, 385 DynamicPorts: []structs.Port{{Label: "http", Value: 9876}}, 386 }, 387 }, 388 }, 389 }, 390 SharedResources: &structs.Resources{ 391 DiskMB: 150, 392 }, 393 394 AllocatedResources: &structs.AllocatedResources{ 395 Tasks: map[string]*structs.AllocatedTaskResources{ 396 "web": { 397 Cpu: structs.AllocatedCpuResources{ 398 CpuShares: 500, 399 }, 400 Memory: structs.AllocatedMemoryResources{ 401 MemoryMB: 256, 402 }, 403 Networks: []*structs.NetworkResource{ 404 { 405 Device: "eth0", 406 IP: "192.168.0.100", 407 ReservedPorts: []structs.Port{{Label: "admin", Value: 5000}}, 408 MBits: 50, 409 DynamicPorts: []structs.Port{{Label: "http", Value: 9876}}, 410 }, 411 }, 412 }, 413 }, 414 Shared: structs.AllocatedSharedResources{ 415 DiskMB: 150, 416 }, 417 }, 418 Job: BatchJob(), 419 DesiredStatus: structs.AllocDesiredStatusRun, 420 ClientStatus: structs.AllocClientStatusPending, 421 } 422 alloc.JobID = alloc.Job.ID 423 return alloc 424 }