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  }