Create delete_session_recording job and associated infra
This commit is contained in:
1 parent
2dda19aafe
commit
e903947bef
5 files changed
+156
-2
No files matched your search
+7
-2
@@ -49,6 +49,11 @@ type Session struct {
|
||||
Summary SessionSummary
|
||||
}
|
||||
|
||||
// GetBsrFileName formats a session recording id into the BSR filename format
|
||||
func GetBsrFileName(sessionRecordingId string) string {
|
||||
return fmt.Sprintf(bsrFileNameTemplate, sessionRecordingId)
|
||||
}
|
||||
|
||||
// NewSession creates a Session container for a given session id.
|
||||
func NewSession(ctx context.Context, meta *SessionRecordingMeta, sessionMeta *SessionMeta, f storage.FS, keys *kms.Keys, options ...Option) (*Session, error) {
|
||||
const op = "bsr.NewSession"
|
||||
@@ -82,7 +87,7 @@ func NewSession(ctx context.Context, meta *SessionRecordingMeta, sessionMeta *Se
|
||||
|
||||
opts := getOpts(options...)
|
||||
|
||||
c, err := f.New(ctx, fmt.Sprintf(bsrFileNameTemplate, meta.Id))
|
||||
c, err := f.New(ctx, GetBsrFileName(meta.Id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -189,7 +194,7 @@ func OpenSession(ctx context.Context, sessionRecordingId string, f storage.FS, k
|
||||
return nil, fmt.Errorf("%s: missing key unwrap function: %w", op, ErrInvalidParameter)
|
||||
}
|
||||
|
||||
c, err := f.Open(ctx, fmt.Sprintf(bsrFileNameTemplate, sessionRecordingId))
|
||||
c, err := f.Open(ctx, GetBsrFileName(sessionRecordingId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/plugin"
|
||||
"github.com/hashicorp/boundary/internal/plugin/loopback"
|
||||
"github.com/hashicorp/boundary/internal/ratelimit"
|
||||
"github.com/hashicorp/boundary/internal/recording"
|
||||
"github.com/hashicorp/boundary/internal/scheduler"
|
||||
"github.com/hashicorp/boundary/internal/scheduler/cleaner"
|
||||
"github.com/hashicorp/boundary/internal/scheduler/job"
|
||||
@@ -615,6 +616,9 @@ func (c *Controller) registerJobs() error {
|
||||
if err := purge.RegisterJobs(c.baseContext, c.scheduler, rw, rw); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := recording.RegisterJob(c.baseContext, c.scheduler, rw, rw, c.ControllerExtension, c.kms); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
begin;
|
||||
|
||||
create view find_session_recordings_for_delete as
|
||||
select
|
||||
-- fields for session recordings
|
||||
rs.public_id,
|
||||
rs.storage_bucket_id,
|
||||
|
||||
-- fields for storage buckets. note this is ALL storage bucket fields
|
||||
sb.scope_id as storage_bucket_scope_id,
|
||||
sb.name as storage_bucket_name,
|
||||
sb.description as storage_bucket_description,
|
||||
sb.create_time as storage_bucket_create_time,
|
||||
sb.update_time as storage_bucket_update_time,
|
||||
sb.version as storage_bucket_version,
|
||||
sb.plugin_id,
|
||||
sb.bucket_name,
|
||||
sb.bucket_prefix,
|
||||
sb.worker_filter,
|
||||
sb.attributes,
|
||||
sb.secrets_hmac,
|
||||
|
||||
-- fields for storage bucket secrets
|
||||
sbs.secrets_encrypted,
|
||||
sbs.key_id,
|
||||
|
||||
-- fields for storage bucket plugins
|
||||
plg.scope_id as plugin_scope_id,
|
||||
plg.name as plugin_name,
|
||||
plg.description as plugin_description
|
||||
|
||||
from recording_session rs
|
||||
left join storage_plugin_storage_bucket sb
|
||||
on sb.public_id = rs.storage_bucket_id
|
||||
left join storage_plugin_storage_bucket_secret sbs
|
||||
on sbs.storage_bucket_id = sb.public_id
|
||||
left join plugin plg
|
||||
on plg.public_id = sb.plugin_id
|
||||
where rs.delete_after < now() or rs.delete_time < now()
|
||||
order by rs.delete_time desc, rs.delete_after desc;
|
||||
comment on view find_session_recordings_for_delete is
|
||||
'find_session_recordings_for_delete is used by the delete_session_recording job to find all '
|
||||
'session recordings that need to be automatically deleted along with their storage buckets.';
|
||||
|
||||
commit;
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package recording
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/globals"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/scheduler"
|
||||
)
|
||||
|
||||
const deleteSessionRecordingJobName = "delete_session_recording"
|
||||
|
||||
var NewDeleteSessionRecordingJobFn = newDeleteSessionRecordingJob
|
||||
|
||||
type deleteSessionRecordingJob struct{}
|
||||
|
||||
func newDeleteSessionRecordingJob(_ context.Context,
|
||||
_ db.Reader,
|
||||
_ db.Writer,
|
||||
_ globals.ControllerExtension,
|
||||
_ kms.GetWrapperer,
|
||||
) (scheduler.Job, error) {
|
||||
return &deleteSessionRecordingJob{}, nil
|
||||
}
|
||||
|
||||
// Status reports the job’s current status.
|
||||
func (dsr *deleteSessionRecordingJob) Status() scheduler.JobStatus { return scheduler.JobStatus{} }
|
||||
|
||||
// Run performs the required work depending on the implementation.
|
||||
// The context is used to notify the job that it should exit early.
|
||||
func (dsr *deleteSessionRecordingJob) Run(_ context.Context) error { return nil }
|
||||
|
||||
// NextRunIn returns the duration until the next job run should be scheduled.
|
||||
// Delete Session Recording will run every hour unless we know there are more to delete,
|
||||
// then sooner
|
||||
func (dsr *deleteSessionRecordingJob) NextRunIn(_ context.Context) (time.Duration, error) {
|
||||
return 24 * time.Hour, nil
|
||||
}
|
||||
|
||||
// Name is the unique name of the job.
|
||||
func (dsr *deleteSessionRecordingJob) Name() string { return deleteSessionRecordingJobName }
|
||||
|
||||
// Description is the human-readable description of the job.
|
||||
func (dsr *deleteSessionRecordingJob) Description() string {
|
||||
return "Manages the retention of Session Recordings in accordance with org storage policies"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package recording
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/globals"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/scheduler"
|
||||
)
|
||||
|
||||
// RegisterJob registers the delete session recording job with the provided scheduler.
|
||||
func RegisterJob(ctx context.Context,
|
||||
s *scheduler.Scheduler,
|
||||
r db.Reader,
|
||||
w db.Writer,
|
||||
controllerExt globals.ControllerExtension,
|
||||
kms kms.GetWrapperer,
|
||||
) error {
|
||||
const op = "storage.RegisterJob"
|
||||
switch {
|
||||
case s == nil:
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing scheduler")
|
||||
case r == nil:
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing db.Reader")
|
||||
case w == nil:
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing db.Writer")
|
||||
case kms == nil:
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing kms")
|
||||
}
|
||||
|
||||
dsrJob, err := NewDeleteSessionRecordingJobFn(ctx, r, w, controllerExt, kms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating delete session recording job: %w", err)
|
||||
}
|
||||
if err := s.RegisterJob(ctx, dsrJob); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user