diff --git a/internal/daemon/controller/handlers/session_recordings/session_recording_service.go b/internal/daemon/controller/handlers/session_recordings/session_recording_service.go index c6298dab35..f7b6c39c02 100644 --- a/internal/daemon/controller/handlers/session_recordings/session_recording_service.go +++ b/internal/daemon/controller/handlers/session_recordings/session_recording_service.go @@ -25,6 +25,7 @@ var ( action.Read, action.Download, action.Delete, + action.ReApplyStoragePolicy, ) // CollectionActions contains the set of actions that can be performed on diff --git a/internal/daemon/controller/rate_limiter_test.go b/internal/daemon/controller/rate_limiter_test.go index c09f71a50b..179b2d516e 100644 --- a/internal/daemon/controller/rate_limiter_test.go +++ b/internal/daemon/controller/rate_limiter_test.go @@ -63,7 +63,7 @@ func Test_newRateLimiterConfig(t *testing.T) { ratelimit.DefaultLimiterMaxQuotas(), false, &rateLimiterConfig{ - maxSize: 314157, + maxSize: 316158, configs: nil, disabled: false, limits: defaultLimits, @@ -642,7 +642,7 @@ func Test_rateLimiterConfig_writeSysEvent(t *testing.T) { wantResourceLimits := v.(map[string]interface{}) gotResourceLimits := gotv.(map[string]interface{}) - require.Equal(t, len(gotResourceLimits), len(wantResourceLimits)) + require.Equal(t, len(wantResourceLimits), len(gotResourceLimits)) for k, v := range wantResourceLimits { gotv, ok := gotResourceLimits[k] diff --git a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/defaults.json b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/defaults.json index 0494168a5c..1803b342d1 100644 --- a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/defaults.json +++ b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/defaults.json @@ -2791,6 +2791,32 @@ ] }, "session-recording": { + "reapply-storage-policy": [ + { + "action": "reapply-storage-policy", + "limit": 30000, + "per": "total", + "period": "30s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 3000, + "per": "auth-token", + "period": "30s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 30000, + "per": "ip-address", + "period": "30s", + "resource": "session-recording", + "unlimited": false + } + ], "download": [ { "action": "download", @@ -3971,7 +3997,7 @@ ] } }, - "max_size": 314157, + "max_size": 316158, "msg": "controller api rate limiter" }, "op": "controller.(rateLimiterConfig).writeSysEvent", diff --git a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/max_size.json b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/max_size.json index 182de468f6..5c02a87d3e 100644 --- a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/max_size.json +++ b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/max_size.json @@ -2791,6 +2791,32 @@ ] }, "session-recording": { + "reapply-storage-policy": [ + { + "action": "reapply-storage-policy", + "limit": 30000, + "per": "total", + "period": "30s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 3000, + "per": "auth-token", + "period": "30s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 30000, + "per": "ip-address", + "period": "30s", + "resource": "session-recording", + "unlimited": false + } + ], "download": [ { "action": "download", diff --git a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/override.json b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/override.json index ce2d4b8ca6..cbe66203e1 100644 --- a/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/override.json +++ b/internal/daemon/controller/testdata/Test_rateLimiterConfig_writeSysEvent/override.json @@ -2791,6 +2791,32 @@ ] }, "session-recording": { + "reapply-storage-policy": [ + { + "action": "reapply-storage-policy", + "limit": 100, + "per": "total", + "period": "1m0s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 100, + "per": "auth-token", + "period": "1m0s", + "resource": "session-recording", + "unlimited": false + }, + { + "action": "reapply-storage-policy", + "limit": 100, + "per": "ip-address", + "period": "1m0s", + "resource": "session-recording", + "unlimited": false + } + ], "download": [ { "action": "download", @@ -3971,7 +3997,7 @@ ] } }, - "max_size": 314157, + "max_size": 316158, "msg": "controller api rate limiter" }, "op": "controller.(rateLimiterConfig).writeSysEvent", diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index afad0c795f..4b32c37ec9 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -3361,7 +3361,7 @@ } }, "/v1/session-recordings/{id}:reapply-storage-policy": { - "get": { + "post": { "summary": "ReApplyStoragePolicy will recalculate the resultant set of policy and apply the result to the given session recording.", "operationId": "SessionRecordingService_ReApplyStoragePolicy", "responses": { diff --git a/internal/gen/controller/api/services/session_recording_service.pb.go b/internal/gen/controller/api/services/session_recording_service.pb.go index 23cbe0756d..5e445b5a67 100644 --- a/internal/gen/controller/api/services/session_recording_service.pb.go +++ b/internal/gen/controller/api/services/session_recording_service.pb.go @@ -739,7 +739,7 @@ var file_controller_api_services_v1_session_recording_service_proto_rawDesc = [] 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x62, 0x04, 0x69, - 0x74, 0x65, 0x6d, 0x12, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x74, 0x65, 0x6d, 0x22, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0xd4, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, diff --git a/internal/gen/controller/api/services/session_recording_service.pb.gw.go b/internal/gen/controller/api/services/session_recording_service.pb.gw.go index 4c9066f627..1777aa4b16 100644 --- a/internal/gen/controller/api/services/session_recording_service.pb.gw.go +++ b/internal/gen/controller/api/services/session_recording_service.pb.gw.go @@ -331,7 +331,7 @@ func RegisterSessionRecordingServiceHandlerServer(ctx context.Context, mux *runt return }) - mux.Handle("GET", pattern_SessionRecordingService_ReApplyStoragePolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_SessionRecordingService_ReApplyStoragePolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -488,7 +488,7 @@ func RegisterSessionRecordingServiceHandlerClient(ctx context.Context, mux *runt }) - mux.Handle("GET", pattern_SessionRecordingService_ReApplyStoragePolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_SessionRecordingService_ReApplyStoragePolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) diff --git a/internal/gen/controller/api/services/session_recording_service_grpc.pb.go b/internal/gen/controller/api/services/session_recording_service_grpc.pb.go index c2cdeaae4d..5fb84a1246 100644 --- a/internal/gen/controller/api/services/session_recording_service_grpc.pb.go +++ b/internal/gen/controller/api/services/session_recording_service_grpc.pb.go @@ -48,6 +48,10 @@ type SessionRecordingServiceClient interface { // A Channel recording ID is required to look up a Channel recording. // The only supported mime type is "application/x-asciicast". Download(ctx context.Context, in *DownloadRequest, opts ...grpc.CallOption) (SessionRecordingService_DownloadClient, error) + // ReApplyStoragePolicy calculates the resultant set of policy for a given session recording + // and updates the retain until and delete after values. The provided request + // must include the Session recording ID for the Session recording to be updated. If that ID + // is missing, malformed or reference a non existing resource, an error is returned. ReApplyStoragePolicy(ctx context.Context, in *ReApplyStoragePolicyRequest, opts ...grpc.CallOption) (*ReApplyStoragePolicyResponse, error) // DeleteSessionRecording removes a Session Recording from Boundary. If the Session Recording id // is malformed or not provided an error is returned. @@ -148,6 +152,10 @@ type SessionRecordingServiceServer interface { // A Channel recording ID is required to look up a Channel recording. // The only supported mime type is "application/x-asciicast". Download(*DownloadRequest, SessionRecordingService_DownloadServer) error + // ReApplyStoragePolicy calculates the resultant set of policy for a given session recording + // and updates the retain until and delete after values. The provided request + // must include the Session recording ID for the Session recording to be updated. If that ID + // is missing, malformed or reference a non existing resource, an error is returned. ReApplyStoragePolicy(context.Context, *ReApplyStoragePolicyRequest) (*ReApplyStoragePolicyResponse, error) // DeleteSessionRecording removes a Session Recording from Boundary. If the Session Recording id // is malformed or not provided an error is returned. diff --git a/internal/perms/acl_test.go b/internal/perms/acl_test.go index b57477b3c4..918855dd4c 100644 --- a/internal/perms/acl_test.go +++ b/internal/perms/acl_test.go @@ -932,7 +932,7 @@ func Test_AnonRestrictions(t *testing.T) { if i == resource.Controller || i == resource.Worker { continue } - for j := action.Type(1); j <= action.DetachStoragePolicy; j++ { + for j := action.Type(1); j <= action.ReApplyStoragePolicy; j++ { id := "foobar" prefixes := globals.ResourcePrefixesFromType(resource.Type(i)) if len(prefixes) > 0 { diff --git a/internal/proto/controller/api/services/v1/session_recording_service.proto b/internal/proto/controller/api/services/v1/session_recording_service.proto index 36a3774feb..0caed56a1f 100644 --- a/internal/proto/controller/api/services/v1/session_recording_service.proto +++ b/internal/proto/controller/api/services/v1/session_recording_service.proto @@ -42,9 +42,13 @@ service SessionRecordingService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "Download returns the contents of the specified resource in the specified mime type. Supports both Session ID and Session recording ID for looking up a Session recording. Supports both Connection ID and Connection recording ID to look up a Connection recording. A Channel recording ID is required to look up a Channel recording. The only supported mime type is \"application/x-asciicast\"."}; } + // ReApplyStoragePolicy calculates the resultant set of policy for a given session recording + // and updates the retain until and delete after values. The provided request + // must include the Session recording ID for the Session recording to be updated. If that ID + // is missing, malformed or reference a non existing resource, an error is returned. rpc ReApplyStoragePolicy(ReApplyStoragePolicyRequest) returns (ReApplyStoragePolicyResponse) { option (google.api.http) = { - get: "/v1/session-recordings/{id}:reapply-storage-policy" + post: "/v1/session-recordings/{id}:reapply-storage-policy" response_body: "item" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "ReApplyStoragePolicy will recalculate the resultant set of policy and apply the result to the given session recording."}; diff --git a/internal/types/action/action.go b/internal/types/action/action.go index 6f8ac80483..997cb8c1ba 100644 --- a/internal/types/action/action.go +++ b/internal/types/action/action.go @@ -70,6 +70,7 @@ const ( Download Type = 56 AttachStoragePolicy Type = 57 DetachStoragePolicy Type = 58 + ReApplyStoragePolicy Type = 59 // When adding new actions, be sure to update: // @@ -136,6 +137,7 @@ var Map = map[string]Type{ Download.String(): Download, AttachStoragePolicy.String(): AttachStoragePolicy, DetachStoragePolicy.String(): DetachStoragePolicy, + ReApplyStoragePolicy.String(): ReApplyStoragePolicy, } var DeprecatedMap = map[string]Type{ @@ -208,6 +210,7 @@ func (a Type) String() string { "download", "attach-storage-policy", "detach-storage-policy", + "reapply-storage-policy", }[a] }