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