Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasell committed Feb 14, 2025
1 parent dcf6201 commit 0c843f9
Show file tree
Hide file tree
Showing 68 changed files with 332 additions and 7,372 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:
branches:
- main
- release/**
- f-NET-10260-vault
paths-ignore:
- 'README.md'
- 'CHANGELOG.md'
Expand Down
4 changes: 0 additions & 4 deletions api/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,6 @@ type Job struct {
Migrate *MigrateStrategy `hcl:"migrate,block"`
Meta map[string]string `hcl:"meta,block"`
ConsulToken *string `mapstructure:"consul_token" hcl:"consul_token,optional"`
VaultToken *string `mapstructure:"vault_token" hcl:"vault_token,optional"`
UI *JobUIConfig `hcl:"ui,block"`

/* Fields set by server, not sourced from job config file */
Expand Down Expand Up @@ -1179,9 +1178,6 @@ func (j *Job) Canonicalize() {
if j.ConsulNamespace == nil {
j.ConsulNamespace = pointerOf("")
}
if j.VaultToken == nil {
j.VaultToken = pointerOf("")
}
if j.VaultNamespace == nil {
j.VaultNamespace = pointerOf("")
}
Expand Down
8 changes: 0 additions & 8 deletions api/jobs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Status: pointerOf(""),
Expand Down Expand Up @@ -387,7 +386,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Status: pointerOf(""),
Expand Down Expand Up @@ -469,7 +467,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down Expand Up @@ -645,7 +642,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down Expand Up @@ -818,7 +814,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down Expand Up @@ -912,7 +907,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down Expand Up @@ -1096,7 +1090,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down Expand Up @@ -1275,7 +1268,6 @@ func TestJobs_Canonicalize(t *testing.T) {
AllAtOnce: pointerOf(false),
ConsulToken: pointerOf(""),
ConsulNamespace: pointerOf(""),
VaultToken: pointerOf(""),
VaultNamespace: pointerOf(""),
NomadTokenID: pointerOf(""),
Stop: pointerOf(false),
Expand Down
11 changes: 5 additions & 6 deletions client/allocrunner/taskrunner/task_runner_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,18 @@ func TestTaskRunner_DisableFileForVaultToken_UpgradePath(t *testing.T) {
"run_for": "0s",
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

// Setup a test Vault client.
token := "1234"
handler := func(*structs.Allocation, []string) (map[string]string, error) {
return map[string]string{task.Name: token}, nil
handler := func(ctx context.Context, req vaultclient.JWTLoginRequest) (string, bool, error) {
return token, true, nil
}
vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
must.NoError(t, err)
vaultClient := vc.(*vaultclient.MockVaultClient)
vaultClient.DeriveTokenFn = handler
vaultClient.SetDeriveTokenWithJWTFn(handler)

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, vaultClient)
defer cleanup()
Expand Down Expand Up @@ -75,7 +74,7 @@ func TestTaskRunner_DisableFileForVaultToken_UpgradePath(t *testing.T) {
must.Eq(t, structs.TaskStateDead, finalState.State)
must.False(t, finalState.Failed)

// Verfiry token is in secrets dir.
// Verify token is in secrets dir.
tokenPath = filepath.Join(conf.TaskDir.SecretsDir, vaultTokenFile)
data, err := os.ReadFile(tokenPath)
must.NoError(t, err)
Expand Down
119 changes: 91 additions & 28 deletions client/allocrunner/taskrunner/task_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1635,26 +1635,43 @@ func TestTaskRunner_BlockForVaultToken(t *testing.T) {
"run_for": "0s",
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

// Control when we get a Vault token
token := "1234"
waitCh := make(chan struct{})
handler := func(*structs.Allocation, []string) (map[string]string, error) {
handler := func(ctx context.Context, req vaultclient.JWTLoginRequest) (string, bool, error) {
<-waitCh
return map[string]string{task.Name: token}, nil
return token, true, nil
}

vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
must.NoError(t, err)
vaultClient := vc.(*vaultclient.MockVaultClient)
vaultClient.DeriveTokenFn = handler
vaultClient.SetDeriveTokenWithJWTFn(handler)

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, vaultClient)
defer cleanup()

// The test triggers the task runner Vault hook which performs a call to
// the WI manager. We therefore need to seed the WI manager with data and
// use the mock implementation for this. The data itself doesn't matter, we
// just care about the lookup success.
mockIDManager := widmgr.NewMockIdentityManager()
mockIDManager.(*widmgr.MockIdentityManager).SetIdentity(
structs.WIHandle{
IdentityName: task.Vault.IdentityName(),
WorkloadIdentifier: task.Name,
WorkloadType: structs.WorkloadTypeTask,
}, &structs.SignedWorkloadIdentity{
WorkloadIdentityRequest: structs.WorkloadIdentityRequest{},
JWT: "",
},
)

conf.WIDMgr = mockIDManager

tr, err := NewTaskRunner(conf)
require.NoError(t, err)
defer tr.Kill(context.Background(), structs.NewTaskEvent("cleanup"))
Expand Down Expand Up @@ -1728,23 +1745,40 @@ func TestTaskRunner_DisableFileForVaultToken(t *testing.T) {
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
DisableFile: true,
}

// Setup a test Vault client
token := "1234"
handler := func(*structs.Allocation, []string) (map[string]string, error) {
return map[string]string{task.Name: token}, nil
handler := func(ctx context.Context, req vaultclient.JWTLoginRequest) (string, bool, error) {
return token, true, nil
}
vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
must.NoError(t, err)
vaultClient := vc.(*vaultclient.MockVaultClient)
vaultClient.DeriveTokenFn = handler
vaultClient.SetDeriveTokenWithJWTFn(handler)

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, vaultClient)
defer cleanup()

// The test triggers the task runner Vault hook which performs a call to
// the WI manager. We therefore need to seed the WI manager with data and
// use the mock implementation for this. The data itself doesn't matter, we
// just care about the lookup success.
mockIDManager := widmgr.NewMockIdentityManager()
mockIDManager.(*widmgr.MockIdentityManager).SetIdentity(
structs.WIHandle{
IdentityName: task.Vault.IdentityName(),
WorkloadIdentifier: task.Name,
WorkloadType: structs.WorkloadTypeTask,
}, &structs.SignedWorkloadIdentity{
WorkloadIdentityRequest: structs.WorkloadIdentityRequest{},
JWT: "",
},
)

conf.WIDMgr = mockIDManager

// Start task runner and wait for it to complete.
tr, err := NewTaskRunner(conf)
must.NoError(t, err)
Expand Down Expand Up @@ -1778,29 +1812,46 @@ func TestTaskRunner_DeriveToken_Retry(t *testing.T) {
alloc := mock.BatchAlloc()
task := alloc.Job.TaskGroups[0].Tasks[0]
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

// Fail on the first attempt to derive a vault token
token := "1234"
count := 0
handler := func(*structs.Allocation, []string) (map[string]string, error) {
handler := func(ctx context.Context, req vaultclient.JWTLoginRequest) (string, bool, error) {
if count > 0 {
return map[string]string{task.Name: token}, nil
return token, true, nil
}

count++
return nil, structs.NewRecoverableError(fmt.Errorf("Want a retry"), true)
return "", false, structs.NewRecoverableError(fmt.Errorf("want a retry"), true)
}
vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
must.NoError(t, err)
vaultClient := vc.(*vaultclient.MockVaultClient)
vaultClient.DeriveTokenFn = handler
vaultClient.SetDeriveTokenWithJWTFn(handler)

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, vaultClient)
defer cleanup()

// The test triggers the task runner Vault hook which performs a call to
// the WI manager. We therefore need to seed the WI manager with data and
// use the mock implementation for this. The data itself doesn't matter, we
// just care about the lookup success.
mockIDManager := widmgr.NewMockIdentityManager()
mockIDManager.(*widmgr.MockIdentityManager).SetIdentity(
structs.WIHandle{
IdentityName: task.Vault.IdentityName(),
WorkloadIdentifier: task.Name,
WorkloadType: structs.WorkloadTypeTask,
}, &structs.SignedWorkloadIdentity{
WorkloadIdentityRequest: structs.WorkloadIdentityRequest{},
JWT: "",
},
)

conf.WIDMgr = mockIDManager

tr, err := NewTaskRunner(conf)
require.NoError(t, err)
defer tr.Kill(context.Background(), structs.NewTaskEvent("cleanup"))
Expand Down Expand Up @@ -1861,8 +1912,7 @@ func TestTaskRunner_DeriveToken_Unrecoverable(t *testing.T) {
"run_for": "0s",
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

// Error the token derivation
Expand Down Expand Up @@ -2178,25 +2228,42 @@ func TestTaskRunner_RestartSignalTask_NotRunning(t *testing.T) {

// Use vault to block the start
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

// Control when we get a Vault token
waitCh := make(chan struct{}, 1)
defer close(waitCh)
handler := func(*structs.Allocation, []string) (map[string]string, error) {
handler := func(ctx context.Context, req vaultclient.JWTLoginRequest) (string, bool, error) {
<-waitCh
return map[string]string{task.Name: "1234"}, nil
return "1234", true, nil
}
vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
must.NoError(t, err)
vaultClient := vc.(*vaultclient.MockVaultClient)
vaultClient.DeriveTokenFn = handler
vaultClient.SetDeriveTokenWithJWTFn(handler)

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, vaultClient)
defer cleanup()

// The test triggers the task runner Vault hook which performs a call to
// the WI manager. We therefore need to seed the WI manager with data and
// use the mock implementation for this. The data itself doesn't matter, we
// just care about the lookup success.
mockIDManager := widmgr.NewMockIdentityManager()
mockIDManager.(*widmgr.MockIdentityManager).SetIdentity(
structs.WIHandle{
IdentityName: task.Vault.IdentityName(),
WorkloadIdentifier: task.Name,
WorkloadType: structs.WorkloadTypeTask,
}, &structs.SignedWorkloadIdentity{
WorkloadIdentityRequest: structs.WorkloadIdentityRequest{},
JWT: "",
},
)

conf.WIDMgr = mockIDManager

tr, err := NewTaskRunner(conf)
require.NoError(t, err)
defer tr.Kill(context.Background(), structs.NewTaskEvent("cleanup"))
Expand Down Expand Up @@ -2343,8 +2410,7 @@ func TestTaskRunner_Template_BlockingPreStart(t *testing.T) {
}

task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

conf, cleanup := testTaskRunnerConfig(t, alloc, task.Name, nil)
Expand Down Expand Up @@ -2553,8 +2619,7 @@ func TestTaskRunner_Template_NewVaultToken(t *testing.T) {
},
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
Cluster: structs.VaultDefaultCluster,
}

vc, err := vaultclient.NewMockVaultClient(structs.VaultDefaultCluster)
Expand Down Expand Up @@ -2635,7 +2700,6 @@ func TestTaskRunner_VaultManager_Restart(t *testing.T) {
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
ChangeMode: structs.VaultChangeModeRestart,
}

Expand Down Expand Up @@ -2712,7 +2776,6 @@ func TestTaskRunner_VaultManager_Signal(t *testing.T) {
}
task.Vault = &structs.Vault{
Cluster: structs.VaultDefaultCluster,
Policies: []string{"default"},
ChangeMode: structs.VaultChangeModeSignal,
ChangeSignal: "SIGUSR1",
}
Expand Down
Loading

0 comments on commit 0c843f9

Please sign in to comment.