d5aa72190f
Add structs and fields to support the Nomad Pools Governance Enterprise feature of controlling node pool access via namespaces. Nomad Enterprise allows users to specify a default node pool to be used by jobs that don't specify one. In order to accomplish this, it's necessary to distinguish between a job that explicitly uses the `default` node pool and one that did not specify any. If the `default` node pool is set during job canonicalization it's impossible to do this, so this commit allows a job to have an empty node pool value during registration but sets to `default` at the admission controller mutator. In order to guarantee state consistency the state store validates that the job node pool is set and exists before inserting it.
298 lines
6 KiB
Go
298 lines
6 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package mock
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
func HCL() string {
|
|
return `job "my-job" {
|
|
datacenters = ["dc1"]
|
|
type = "service"
|
|
constraint {
|
|
attribute = "${attr.kernel.name}"
|
|
value = "linux"
|
|
}
|
|
|
|
group "web" {
|
|
count = 10
|
|
restart {
|
|
attempts = 3
|
|
interval = "10m"
|
|
delay = "1m"
|
|
mode = "delay"
|
|
}
|
|
task "web" {
|
|
driver = "exec"
|
|
config {
|
|
command = "/bin/date"
|
|
}
|
|
resources {
|
|
cpu = 500
|
|
memory = 256
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`
|
|
}
|
|
|
|
// HCLVar returns a the HCL of job that requires a HCL variables S, N,
|
|
// and B to be set. Also returns the content of a vars-file to satisfy
|
|
// those variables.
|
|
func HCLVar() (string, string) {
|
|
return `
|
|
variable "S" {
|
|
type = string
|
|
}
|
|
|
|
variable "N" {
|
|
type = number
|
|
}
|
|
|
|
variable "B" {
|
|
type = bool
|
|
}
|
|
|
|
job "var-job" {
|
|
type = "batch"
|
|
constraint {
|
|
attribute = "${attr.kernel.name}"
|
|
value = "linux"
|
|
}
|
|
group "group" {
|
|
task "task" {
|
|
driver = "raw_exec"
|
|
config {
|
|
command = "echo"
|
|
args = ["S is ${var.S}, N is ${var.N}, B is ${var.B}"]
|
|
}
|
|
resources {
|
|
cpu = 10
|
|
memory = 32
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`, `
|
|
S = "stringy"
|
|
N = 42
|
|
B = true
|
|
`
|
|
}
|
|
|
|
func Eval() *structs.Evaluation {
|
|
now := time.Now().UTC().UnixNano()
|
|
eval := &structs.Evaluation{
|
|
ID: uuid.Generate(),
|
|
Namespace: structs.DefaultNamespace,
|
|
Priority: 50,
|
|
Type: structs.JobTypeService,
|
|
JobID: uuid.Generate(),
|
|
Status: structs.EvalStatusPending,
|
|
CreateTime: now,
|
|
ModifyTime: now,
|
|
}
|
|
return eval
|
|
}
|
|
|
|
func BlockedEval() *structs.Evaluation {
|
|
e := Eval()
|
|
e.Status = structs.EvalStatusBlocked
|
|
e.FailedTGAllocs = map[string]*structs.AllocMetric{
|
|
"cache": {
|
|
DimensionExhausted: map[string]int{
|
|
"memory": 1,
|
|
},
|
|
ResourcesExhausted: map[string]*structs.Resources{
|
|
"redis": {
|
|
CPU: 100,
|
|
MemoryMB: 1024,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return e
|
|
}
|
|
|
|
func JobSummary(jobID string) *structs.JobSummary {
|
|
return &structs.JobSummary{
|
|
JobID: jobID,
|
|
Namespace: structs.DefaultNamespace,
|
|
Summary: map[string]structs.TaskGroupSummary{
|
|
"web": {
|
|
Queued: 0,
|
|
Starting: 0,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func JobSysBatchSummary(jobID string) *structs.JobSummary {
|
|
return &structs.JobSummary{
|
|
JobID: jobID,
|
|
Namespace: structs.DefaultNamespace,
|
|
Summary: map[string]structs.TaskGroupSummary{
|
|
"pinger": {
|
|
Queued: 0,
|
|
Starting: 0,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func VaultAccessor() *structs.VaultAccessor {
|
|
return &structs.VaultAccessor{
|
|
Accessor: uuid.Generate(),
|
|
NodeID: uuid.Generate(),
|
|
AllocID: uuid.Generate(),
|
|
CreationTTL: 86400,
|
|
Task: "foo",
|
|
}
|
|
}
|
|
|
|
func SITokenAccessor() *structs.SITokenAccessor {
|
|
return &structs.SITokenAccessor{
|
|
NodeID: uuid.Generate(),
|
|
AllocID: uuid.Generate(),
|
|
AccessorID: uuid.Generate(),
|
|
TaskName: "foo",
|
|
}
|
|
}
|
|
|
|
func Deployment() *structs.Deployment {
|
|
return &structs.Deployment{
|
|
ID: uuid.Generate(),
|
|
JobID: uuid.Generate(),
|
|
Namespace: structs.DefaultNamespace,
|
|
JobVersion: 2,
|
|
JobModifyIndex: 20,
|
|
JobCreateIndex: 18,
|
|
TaskGroups: map[string]*structs.DeploymentState{
|
|
"web": {
|
|
DesiredTotal: 10,
|
|
},
|
|
},
|
|
Status: structs.DeploymentStatusRunning,
|
|
StatusDescription: structs.DeploymentStatusDescriptionRunning,
|
|
ModifyIndex: 23,
|
|
CreateIndex: 21,
|
|
}
|
|
}
|
|
|
|
func Plan() *structs.Plan {
|
|
return &structs.Plan{
|
|
Priority: 50,
|
|
}
|
|
}
|
|
|
|
func PlanResult() *structs.PlanResult {
|
|
return &structs.PlanResult{}
|
|
}
|
|
|
|
func ScalingPolicy() *structs.ScalingPolicy {
|
|
return &structs.ScalingPolicy{
|
|
ID: uuid.Generate(),
|
|
Min: 1,
|
|
Max: 100,
|
|
Type: structs.ScalingPolicyTypeHorizontal,
|
|
Target: map[string]string{
|
|
structs.ScalingTargetNamespace: structs.DefaultNamespace,
|
|
structs.ScalingTargetJob: uuid.Generate(),
|
|
structs.ScalingTargetGroup: uuid.Generate(),
|
|
structs.ScalingTargetTask: uuid.Generate(),
|
|
},
|
|
Policy: map[string]interface{}{
|
|
"a": "b",
|
|
},
|
|
Enabled: true,
|
|
}
|
|
}
|
|
|
|
func Events(index uint64) *structs.Events {
|
|
return &structs.Events{
|
|
Index: index,
|
|
Events: []structs.Event{
|
|
{
|
|
Index: index,
|
|
Topic: "Node",
|
|
Type: "update",
|
|
Key: uuid.Generate(),
|
|
Payload: Node(),
|
|
},
|
|
{
|
|
Index: index,
|
|
Topic: "Eval",
|
|
Type: "update",
|
|
Key: uuid.Generate(),
|
|
Payload: Eval(),
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func Namespace() *structs.Namespace {
|
|
id := uuid.Generate()
|
|
ns := &structs.Namespace{
|
|
Name: fmt.Sprintf("team-%s", id),
|
|
Meta: map[string]string{"team": id},
|
|
Description: "test namespace",
|
|
CreateIndex: 100,
|
|
ModifyIndex: 200,
|
|
}
|
|
ns.Canonicalize()
|
|
ns.SetHash()
|
|
return ns
|
|
}
|
|
|
|
func NodePool() *structs.NodePool {
|
|
pool := &structs.NodePool{
|
|
Name: fmt.Sprintf("pool-%s", uuid.Short()),
|
|
Description: "test node pool",
|
|
Meta: map[string]string{"team": "test"},
|
|
SchedulerConfiguration: &structs.NodePoolSchedulerConfiguration{
|
|
SchedulerAlgorithm: structs.SchedulerAlgorithmSpread,
|
|
},
|
|
}
|
|
pool.SetHash()
|
|
return pool
|
|
}
|
|
|
|
// ServiceRegistrations generates an array containing two unique service
|
|
// registrations.
|
|
func ServiceRegistrations() []*structs.ServiceRegistration {
|
|
return []*structs.ServiceRegistration{
|
|
{
|
|
ID: "_nomad-task-2873cf75-42e5-7c45-ca1c-415f3e18be3d-group-cache-example-cache-db",
|
|
ServiceName: "example-cache",
|
|
Namespace: "default",
|
|
NodeID: "17a6d1c0-811e-2ca9-ded0-3d5d6a54904c",
|
|
Datacenter: "dc1",
|
|
JobID: "example",
|
|
AllocID: "2873cf75-42e5-7c45-ca1c-415f3e18be3d",
|
|
Tags: []string{"foo"},
|
|
Address: "192.168.10.1",
|
|
Port: 23000,
|
|
},
|
|
{
|
|
ID: "_nomad-task-ca60e901-675a-0ab2-2e57-2f3b05fdc540-group-api-countdash-api-http",
|
|
ServiceName: "countdash-api",
|
|
Namespace: "platform",
|
|
NodeID: "ba991c17-7ce5-9c20-78b7-311e63578583",
|
|
Datacenter: "dc2",
|
|
JobID: "countdash-api",
|
|
AllocID: "ca60e901-675a-0ab2-2e57-2f3b05fdc540",
|
|
Tags: []string{"bar"},
|
|
Address: "192.168.200.200",
|
|
Port: 29000,
|
|
},
|
|
}
|
|
}
|