Implicit vault constraint

This commit is contained in:
Alex Dadgar
2016-09-01 14:23:40 -07:00
parent cf5cc4f74a
commit a907994fcc
3 changed files with 53 additions and 3 deletions

View File

@@ -22,6 +22,16 @@ const (
RegisterEnforceIndexErrPrefix = "Enforcing job modify index"
)
var (
// vaultConstraint is the implicit constraint added to jobs requesting a
// Vault token
vaultConstraint = &structs.Constraint{
LTarget: "${attr.vault.version}",
RTarget: ">= 0.6.1",
Operand: structs.ConstraintVersion,
}
)
// Job endpoint is used for job interactions
type Job struct {
srv *Server
@@ -71,8 +81,8 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
}
// Ensure that the job has permissions for the requested Vault tokens
desiredPolicies := structs.VaultPoliciesSet(args.Job.VaultPolicies())
if len(desiredPolicies) != 0 {
policies := args.Job.VaultPolicies()
if len(policies) != 0 {
vconf := j.srv.config.VaultConfig
if !vconf.Enabled {
return fmt.Errorf("Vault not enabled and Vault policies requested")
@@ -97,13 +107,36 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
// If we are given a root token it can access all policies
if !lib.StrContains(allowedPolicies, "root") {
subset, offending := structs.SliceStringIsSubset(allowedPolicies, desiredPolicies)
flatPolicies := structs.VaultPoliciesSet(policies)
subset, offending := structs.SliceStringIsSubset(allowedPolicies, flatPolicies)
if !subset {
return fmt.Errorf("Passed Vault Token doesn't allow access to the following policies: %s",
strings.Join(offending, ", "))
}
}
}
// Add implicit constraints that the task groups are run on a Node with
// Vault
for _, tg := range args.Job.TaskGroups {
_, ok := policies[tg.Name]
if !ok {
// Not requesting Vault
continue
}
found := false
for _, c := range tg.Constraints {
if c.Equal(vaultConstraint) {
found = true
break
}
}
if !found {
tg.Constraints = append(tg.Constraints, vaultConstraint)
}
}
}
// Clear the Vault token

View File

@@ -547,6 +547,16 @@ func TestJobEndpoint_Register_Vault_Policies(t *testing.T) {
t.Fatalf("vault token not cleared")
}
// Check that an implicit constraint was created
constraints := out.TaskGroups[0].Constraints
if l := len(constraints); l != 1 {
t.Fatalf("Unexpected number of tests: %v", l)
}
if !constraints[0].Equal(vaultConstraint) {
t.Fatalf("bad constraint; got %#v; want %#v", constraints[0], vaultConstraint)
}
// Create the register request with another job asking for a vault policy but
// send the root Vault token
job2 := mock.Job()

View File

@@ -2534,6 +2534,13 @@ type Constraint struct {
str string // Memoized string
}
// Equal checks if two constraints are equal
func (c *Constraint) Equal(o *Constraint) bool {
return c.LTarget == o.LTarget &&
c.RTarget == o.RTarget &&
c.Operand == o.Operand
}
func (c *Constraint) Copy() *Constraint {
if c == nil {
return nil