diff --git a/internal/credential/vault/jobs_test.go b/internal/credential/vault/jobs_test.go index 9129705a8..10c6d3fe9 100644 --- a/internal/credential/vault/jobs_test.go +++ b/internal/credential/vault/jobs_test.go @@ -435,12 +435,12 @@ func TestTokenRenewalJob_RunExpired(t *testing.T) { rw := db.New(conn) wrapper := db.TestWrapper(t) kmsCache := kms.TestKms(t, conn, wrapper) - sche := scheduler.TestScheduler(t, conn, wrapper) + sche := scheduler.TestScheduler(t, conn, wrapper, scheduler.WithRunJobsInterval(time.Second)) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) v := NewTestVaultServer(t) - // Create 1s token so it expires in vault before we can renew it - _, ct := v.CreateToken(t, WithTokenPeriod(time.Second)) + // Create 2s token so it expires in vault before we can renew it + _, ct := v.CreateToken(t, WithTokenPeriod(time.Second*2)) in, err := NewCredentialStore(prj.GetPublicId(), v.Addr, []byte(ct)) assert.NoError(err) @@ -469,6 +469,27 @@ func TestTokenRenewalJob_RunExpired(t *testing.T) { token := allocToken() require.NoError(rw.LookupWhere(context.Background(), &token, "store_id = ?", []interface{}{cs.GetPublicId()})) assert.Equal(string(ExpiredToken), token.Status) + + // Updating the credential store with a token that will expire before the job scheduler can run should return an error + _, ct = v.CreateToken(t, WithTokenPeriod(time.Second)) + in, err = NewCredentialStore(prj.GetPublicId(), v.Addr, []byte(ct)) + assert.NoError(err) + require.NotNil(in) + + cs, _, err = repo.UpdateCredentialStore(context.Background(), in, cs.Version+1, []string{"Token"}) + assert.Error(err) + assert.Nil(cs) + + // Create 1s token so it expires in vault before the job scheduler can run + _, ct = v.CreateToken(t, WithTokenPeriod(time.Second)) + in, err = NewCredentialStore(prj.GetPublicId(), v.Addr, []byte(ct)) + assert.NoError(err) + require.NotNil(in) + + // Should return error because token ttl expires before the run job scheduler interval + cs, err = repo.CreateCredentialStore(context.Background(), in) + require.Error(err) + require.Nil(cs) } func TestTokenRenewalJob_NextRunIn(t *testing.T) { diff --git a/internal/credential/vault/repository_credential_store.go b/internal/credential/vault/repository_credential_store.go index 1c132b9d3..b4166eab5 100644 --- a/internal/credential/vault/repository_credential_store.go +++ b/internal/credential/vault/repository_credential_store.go @@ -116,6 +116,11 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt return nil, err } + runJobsInterval := r.scheduler.GetRunJobsInterval() + if token.expiration <= runJobsInterval { + return nil, errors.Wrap(ctx, fmt.Errorf("scheduler interval must be greater than token ttl. scheduler jobs interval value: %s", runJobsInterval.String()), op) + } + oplogWrapper, err := r.kms.GetWrapper(ctx, cs.ProjectId, kms.KeyPurposeOplog) if err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper")) @@ -505,6 +510,10 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt if token, err = newToken(cs.GetPublicId(), cs.inputToken, []byte(accessor), tokenExpires); err != nil { return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op) } + runJobsInterval := r.scheduler.GetRunJobsInterval() + if token.expiration <= runJobsInterval { + return nil, db.NoRowsAffected, errors.Wrap(ctx, fmt.Errorf("scheduler interval must be greater than token ttl. scheduler jobs interval value: %s", runJobsInterval.String()), op) + } // encrypt token if err := token.encrypt(ctx, databaseWrapper); err != nil { return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op) diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index c7d5167af..4b44202c9 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -333,3 +333,10 @@ func (s *Scheduler) updateRunningJobProgress(ctx context.Context, j *runningJob) return nil } + +// GetRunJobsInterval returns the value runJobsInterval, +// which represents an interval at which the scheduler +// will query the repository for jobs to run. +func (s *Scheduler) GetRunJobsInterval() time.Duration { + return s.runJobsInterval +}