mirror of
https://github.com/kemko/nomad.git
synced 2026-01-07 19:05:42 +03:00
Making the Job expand all service names during registration
This commit is contained in:
12
api/tasks.go
12
api/tasks.go
@@ -1,8 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/nomad/helper/args"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -44,16 +42,6 @@ type Service struct {
|
||||
Checks []ServiceCheck
|
||||
}
|
||||
|
||||
func (s *Service) ExpandName(job string, taskGroup string, task string) {
|
||||
s.Name = args.ReplaceEnv(s.Name, map[string]string{
|
||||
"JOB": job,
|
||||
"TASKGROUP": taskGroup,
|
||||
"TASK": task,
|
||||
"BASE": fmt.Sprintf("%s-%s-%s", job, taskGroup, task),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// TaskGroup is the unit of scheduling.
|
||||
type TaskGroup struct {
|
||||
Name string
|
||||
|
||||
@@ -218,37 +218,3 @@ func TestTask_Constrain(t *testing.T) {
|
||||
t.Fatalf("expect: %#v, got: %#v", expect, task.Constraints)
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_Expand_Name(t *testing.T) {
|
||||
job := "example"
|
||||
taskGroup := "cache"
|
||||
task := "redis"
|
||||
|
||||
s := Service{
|
||||
Name: "${TASK}-db",
|
||||
}
|
||||
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "${JOB}-${TASKGROUP}-${TASK}-db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "example-cache-redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "expample-cache-redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "${BASE}-db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "example-cache-redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "expample-cache-redis-db", s.Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||
if err := args.Job.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args.Job.ExpandAllServiceNames()
|
||||
|
||||
if args.Job.Type == structs.JobTypeCore {
|
||||
return fmt.Errorf("job type cannot be core")
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ func TestJobEndpoint_Register(t *testing.T) {
|
||||
if out.CreateIndex != resp.JobModifyIndex {
|
||||
t.Fatalf("index mis-match")
|
||||
}
|
||||
serviceName := out.TaskGroups[0].Tasks[0].Services[0].Name
|
||||
if serviceName != "web-frontend" {
|
||||
t.Fatalf("Expected Service Name: %s, Actual: %s", serviceName)
|
||||
}
|
||||
|
||||
// Lookup the evaluation
|
||||
eval, err := state.EvalByID(resp.EvalID)
|
||||
|
||||
@@ -90,6 +90,12 @@ func Job() *structs.Job {
|
||||
Env: map[string]string{
|
||||
"FOO": "bar",
|
||||
},
|
||||
Services: []*structs.Service{
|
||||
{
|
||||
Name: "${TASK}-frontend",
|
||||
PortLabel: "http",
|
||||
},
|
||||
},
|
||||
Resources: &structs.Resources{
|
||||
CPU: 500,
|
||||
MemoryMB: 256,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/hashicorp/go-msgpack/codec"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/hashicorp/nomad/helper/args"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -774,6 +775,14 @@ type Job struct {
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
// ExpandAllServiceNames traverses all Task Groups and makes them
|
||||
// interpolate Job, Task group and Task names in all Service names
|
||||
func (j *Job) ExpandAllServiceNames() {
|
||||
for _, tg := range j.TaskGroups {
|
||||
tg.ExpandAllServiceNames(j.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Validate is used to sanity check a job input
|
||||
func (j *Job) Validate() error {
|
||||
var mErr multierror.Error
|
||||
@@ -942,6 +951,14 @@ type TaskGroup struct {
|
||||
Meta map[string]string
|
||||
}
|
||||
|
||||
// ExpandAllServiceNames traverses over all Tasks and makes them to interpolate
|
||||
// values of Job, Task Group and Task names in all Service Names
|
||||
func (tg *TaskGroup) ExpandAllServiceNames(job string) {
|
||||
for _, task := range tg.Tasks {
|
||||
task.ExpandAllServiceNames(job, tg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Validate is used to sanity check a task group
|
||||
func (tg *TaskGroup) Validate() error {
|
||||
var mErr multierror.Error
|
||||
@@ -1025,6 +1042,16 @@ type ServiceCheck struct {
|
||||
Timeout time.Duration // Timeout of the response from the check before consul fails the check
|
||||
}
|
||||
|
||||
func (s *Service) ExpandName(job string, taskGroup string, task string) {
|
||||
s.Name = args.ReplaceEnv(s.Name, map[string]string{
|
||||
"JOB": job,
|
||||
"TASKGROUP": taskGroup,
|
||||
"TASK": task,
|
||||
"BASE": fmt.Sprintf("%s-%s-%s", job, taskGroup, task),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (sc *ServiceCheck) Validate() error {
|
||||
t := strings.ToLower(sc.Type)
|
||||
if t != ServiceCheckTCP && t != ServiceCheckHTTP {
|
||||
@@ -1109,6 +1136,14 @@ type Task struct {
|
||||
Meta map[string]string
|
||||
}
|
||||
|
||||
// ExpandAllServiceNames interpolates values of Job, Task Group
|
||||
// and Tasks in all the service Names of a Task
|
||||
func (t *Task) ExpandAllServiceNames(job string, taskGroup string) {
|
||||
for _, service := range t.Services {
|
||||
service.ExpandName(job, taskGroup, t.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Task) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *t)
|
||||
}
|
||||
|
||||
@@ -405,3 +405,82 @@ func TestDistinctCheckId(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestService_Expand_Name(t *testing.T) {
|
||||
job := "example"
|
||||
taskGroup := "cache"
|
||||
task := "redis"
|
||||
|
||||
s := Service{
|
||||
Name: "${TASK}-db",
|
||||
}
|
||||
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "${JOB}-${TASKGROUP}-${TASK}-db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "example-cache-redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "expample-cache-redis-db", s.Name)
|
||||
}
|
||||
|
||||
s.Name = "${BASE}-db"
|
||||
s.ExpandName(job, taskGroup, task)
|
||||
if s.Name != "example-cache-redis-db" {
|
||||
t.Fatalf("Expected name: %v, Actual: %v", "expample-cache-redis-db", s.Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJob_ExpandServiceNames(t *testing.T) {
|
||||
j := &Job{
|
||||
Name: "my-job",
|
||||
TaskGroups: []*TaskGroup{
|
||||
&TaskGroup{
|
||||
Name: "web",
|
||||
Tasks: []*Task{
|
||||
{
|
||||
Name: "frontend",
|
||||
Services: []*Service{
|
||||
{
|
||||
Name: "${BASE}-default",
|
||||
},
|
||||
{
|
||||
Name: "jmx",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&TaskGroup{
|
||||
Name: "admin",
|
||||
Tasks: []*Task{
|
||||
{
|
||||
Name: "admin-web",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
j.ExpandAllServiceNames()
|
||||
|
||||
service1Name := j.TaskGroups[0].Tasks[0].Services[0].Name
|
||||
if service1Name != "my-job-web-frontend-default" {
|
||||
t.Fatalf("Expected Service Name: %s, Actual: %s", "my-job-web-frontend-default", service1Name)
|
||||
}
|
||||
|
||||
service2Name := j.TaskGroups[0].Tasks[0].Services[1].Name
|
||||
if service2Name != "jmx" {
|
||||
t.Fatalf("Expected Service Name: %s, Actual: %s", "jmx", service2Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user