Merge pull request #1729 from hashicorp/f-vault-anywhere

Vault block improvements
This commit is contained in:
Alex Dadgar
2016-09-21 12:56:16 -07:00
committed by GitHub
7 changed files with 132 additions and 2 deletions

View File

@@ -166,8 +166,9 @@ func GetTaskEnv(allocDir *allocdir.AllocDir, node *structs.Node,
env.SetAlloc(alloc)
}
// TODO: make this conditional on the task's vault block allowing it
env.SetVaultToken(vaultToken, true)
if task.Vault != nil {
env.SetVaultToken(vaultToken, task.Vault.Env)
}
return env.Build(), nil
}

View File

@@ -101,6 +101,7 @@ func parseJob(result *structs.Job, list *ast.ObjectList) error {
delete(m, "meta")
delete(m, "update")
delete(m, "periodic")
delete(m, "vault")
// Set the ID and name to the object key
result.ID = obj.Keys[0].Token.Value().(string)
@@ -139,6 +140,7 @@ func parseJob(result *structs.Job, list *ast.ObjectList) error {
"meta",
"task",
"group",
"vault",
"vault_token",
}
if err := checkHCLKeys(listVal, valid); err != nil {
@@ -205,6 +207,23 @@ func parseJob(result *structs.Job, list *ast.ObjectList) error {
}
}
// If we have a vault block, then parse that
if o := listVal.Filter("vault"); len(o.Items) > 0 {
var jobVault structs.Vault
if err := parseVault(&jobVault, o); err != nil {
return multierror.Prefix(err, "vault ->")
}
// Go through the task groups/tasks and if they don't have a Vault block, set it
for _, tg := range result.TaskGroups {
for _, task := range tg.Tasks {
if task.Vault == nil {
task.Vault = &jobVault
}
}
}
}
return nil
}
@@ -242,6 +261,7 @@ func parseGroups(result *structs.Job, list *ast.ObjectList) error {
"meta",
"task",
"ephemeral_disk",
"vault",
}
if err := checkHCLKeys(listVal, valid); err != nil {
return multierror.Prefix(err, fmt.Sprintf("'%s' ->", n))
@@ -256,6 +276,7 @@ func parseGroups(result *structs.Job, list *ast.ObjectList) error {
delete(m, "task")
delete(m, "restart")
delete(m, "ephemeral_disk")
delete(m, "vault")
// Default count to 1 if not specified
if _, ok := m["count"]; !ok {
@@ -312,6 +333,21 @@ func parseGroups(result *structs.Job, list *ast.ObjectList) error {
}
}
// If we have a vault block, then parse that
if o := listVal.Filter("vault"); len(o.Items) > 0 {
var tgVault structs.Vault
if err := parseVault(&tgVault, o); err != nil {
return multierror.Prefix(err, fmt.Sprintf("'%s', vault ->", n))
}
// Go through the tasks and if they don't have a Vault block, set it
for _, task := range g.Tasks {
if task.Vault == nil {
task.Vault = &tgVault
}
}
}
collection = append(collection, &g)
}
@@ -1090,6 +1126,7 @@ func parseVault(result *structs.Vault, list *ast.ObjectList) error {
// Check for invalid keys
valid := []string{
"policies",
"env",
}
if err := checkHCLKeys(listVal, valid); err != nil {
return multierror.Prefix(err, "vault ->")
@@ -1100,6 +1137,11 @@ func parseVault(result *structs.Vault, list *ast.ObjectList) error {
return err
}
// Default the env bool
if _, ok := m["env"]; !ok {
m["env"] = true
}
if err := mapstructure.WeakDecode(m, result); err != nil {
return err
}

View File

@@ -160,6 +160,7 @@ func TestParse(t *testing.T) {
},
Vault: &structs.Vault{
Policies: []string{"foo", "bar"},
Env: true,
},
},
&structs.Task{
@@ -440,6 +441,57 @@ func TestParse(t *testing.T) {
},
false,
},
{
"vault_inheritance.hcl",
&structs.Job{
ID: "example",
Name: "example",
Type: "service",
Priority: 50,
Region: "global",
TaskGroups: []*structs.TaskGroup{
&structs.TaskGroup{
Name: "cache",
Count: 1,
LocalDisk: structs.DefaultLocalDisk(),
Tasks: []*structs.Task{
&structs.Task{
Name: "redis",
LogConfig: structs.DefaultLogConfig(),
Vault: &structs.Vault{
Policies: []string{"group"},
Env: true,
},
},
&structs.Task{
Name: "redis2",
LogConfig: structs.DefaultLogConfig(),
Vault: &structs.Vault{
Policies: []string{"task"},
Env: false,
},
},
},
},
&structs.TaskGroup{
Name: "cache2",
Count: 1,
LocalDisk: structs.DefaultLocalDisk(),
Tasks: []*structs.Task{
&structs.Task{
Name: "redis",
LogConfig: structs.DefaultLogConfig(),
Vault: &structs.Vault{
Policies: []string{"job"},
Env: true,
},
},
},
},
},
},
false,
},
}
for _, tc := range cases {

View File

@@ -0,0 +1,22 @@
job "example" {
vault {
policies = ["job"]
}
group "cache" {
vault {
policies = ["group"]
}
task "redis" { }
task "redis2" {
vault {
policies = ["task"]
env = false
}
}
}
group "cache2" {
task "redis" { }
}
}

View File

@@ -2630,6 +2630,10 @@ func (d *EphemeralDisk) Copy() *EphemeralDisk {
type Vault struct {
// Policies is the set of policies that the task needs access to
Policies []string
// Env marks whether the Vault Token should be exposed as an environment
// variable
Env bool
}
// Copy returns a copy of this Vault block.

View File

@@ -359,6 +359,9 @@ func tasksUpdated(a, b *structs.TaskGroup) bool {
if !reflect.DeepEqual(at.Artifacts, bt.Artifacts) {
return true
}
if !reflect.DeepEqual(at.Vault, bt.Vault) {
return true
}
// Inspect the network to see if the dynamic ports are different
if len(at.Resources.Networks) != len(bt.Resources.Networks) {

View File

@@ -540,6 +540,12 @@ func TestTasksUpdated(t *testing.T) {
if !tasksUpdated(j1.TaskGroups[0], j14.TaskGroups[0]) {
t.Fatalf("bad")
}
j15 := mock.Job()
j15.TaskGroups[0].Tasks[0].Vault = &structs.Vault{Policies: []string{"foo"}}
if !tasksUpdated(j1.TaskGroups[0], j15.TaskGroups[0]) {
t.Fatalf("bad")
}
}
func TestEvictAndPlace_LimitLessThanAllocs(t *testing.T) {