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  }