@@ -10,13 +10,7 @@ pub use openshell_core::proto::{
1010 StoredDraftChunk as DraftChunkRecord , StoredPolicyRevision as PolicyRecord ,
1111} ;
1212
13- use openshell_core:: {
14- Error as CoreError , Result as CoreResult ,
15- proto:: {
16- DraftChunkPayload , NetworkPolicyRule , PolicyRevisionPayload ,
17- SandboxPolicy as ProtoSandboxPolicy ,
18- } ,
19- } ;
13+ use openshell_core:: { Error as CoreError , Result as CoreResult } ;
2014use prost:: Message ;
2115use rand:: Rng ;
2216use std:: time:: { SystemTime , UNIX_EPOCH } ;
@@ -228,122 +222,6 @@ impl Store {
228222 }
229223 }
230224
231- // -----------------------------------------------------------------------
232- // Policy revision operations
233- // -----------------------------------------------------------------------
234- /// Insert a new policy revision.
235- pub async fn put_policy_revision (
236- & self ,
237- id : & str ,
238- sandbox_id : & str ,
239- version : i64 ,
240- payload : & [ u8 ] ,
241- hash : & str ,
242- ) -> PersistenceResult < ( ) > {
243- match self {
244- Self :: Postgres ( store) => {
245- store
246- . put_policy_revision ( id, sandbox_id, version, payload, hash)
247- . await
248- }
249- Self :: Sqlite ( store) => {
250- store
251- . put_policy_revision ( id, sandbox_id, version, payload, hash)
252- . await
253- }
254- }
255- }
256-
257- /// Get the latest policy revision for a sandbox (by highest version, any status).
258- pub async fn get_latest_policy (
259- & self ,
260- sandbox_id : & str ,
261- ) -> PersistenceResult < Option < PolicyRecord > > {
262- match self {
263- Self :: Postgres ( store) => store. get_latest_policy ( sandbox_id) . await ,
264- Self :: Sqlite ( store) => store. get_latest_policy ( sandbox_id) . await ,
265- }
266- }
267-
268- /// Get the latest loaded policy revision for a sandbox.
269- pub async fn get_latest_loaded_policy (
270- & self ,
271- sandbox_id : & str ,
272- ) -> PersistenceResult < Option < PolicyRecord > > {
273- match self {
274- Self :: Postgres ( store) => store. get_latest_loaded_policy ( sandbox_id) . await ,
275- Self :: Sqlite ( store) => store. get_latest_loaded_policy ( sandbox_id) . await ,
276- }
277- }
278-
279- /// Get a specific policy revision by sandbox id and version.
280- pub async fn get_policy_by_version (
281- & self ,
282- sandbox_id : & str ,
283- version : i64 ,
284- ) -> PersistenceResult < Option < PolicyRecord > > {
285- match self {
286- Self :: Postgres ( store) => store. get_policy_by_version ( sandbox_id, version) . await ,
287- Self :: Sqlite ( store) => store. get_policy_by_version ( sandbox_id, version) . await ,
288- }
289- }
290-
291- /// List policy revisions for a sandbox, ordered by version descending.
292- pub async fn list_policies (
293- & self ,
294- sandbox_id : & str ,
295- limit : u32 ,
296- offset : u32 ,
297- ) -> PersistenceResult < Vec < PolicyRecord > > {
298- match self {
299- Self :: Postgres ( store) => store. list_policies ( sandbox_id, limit, offset) . await ,
300- Self :: Sqlite ( store) => store. list_policies ( sandbox_id, limit, offset) . await ,
301- }
302- }
303-
304- /// Update the status of a policy revision.
305- pub async fn update_policy_status (
306- & self ,
307- sandbox_id : & str ,
308- version : i64 ,
309- status : & str ,
310- load_error : Option < & str > ,
311- loaded_at_ms : Option < i64 > ,
312- ) -> PersistenceResult < bool > {
313- match self {
314- Self :: Postgres ( store) => {
315- store
316- . update_policy_status ( sandbox_id, version, status, load_error, loaded_at_ms)
317- . await
318- }
319- Self :: Sqlite ( store) => {
320- store
321- . update_policy_status ( sandbox_id, version, status, load_error, loaded_at_ms)
322- . await
323- }
324- }
325- }
326-
327- /// Mark all pending and loaded policy revisions older than `before_version` as superseded.
328- pub async fn supersede_older_policies (
329- & self ,
330- sandbox_id : & str ,
331- before_version : i64 ,
332- ) -> PersistenceResult < u64 > {
333- match self {
334- Self :: Postgres ( store) => {
335- store
336- . supersede_older_policies ( sandbox_id, before_version)
337- . await
338- }
339- Self :: Sqlite ( store) => {
340- store
341- . supersede_older_policies ( sandbox_id, before_version)
342- . await
343- }
344- }
345- }
346-
347225 // -----------------------------------------------------------------------
348226 // Generic protobuf message helpers
349227 // -----------------------------------------------------------------------
@@ -402,191 +280,6 @@ impl Store {
402280 . map ( Some )
403281 . map_err ( |e| PersistenceError :: Decode ( format ! ( "protobuf decode error: {e}" ) ) )
404282 }
405-
406- /// Insert or merge a new draft policy chunk.
407- pub async fn put_draft_chunk ( & self , chunk : & DraftChunkRecord ) -> PersistenceResult < ( ) > {
408- match self {
409- Self :: Postgres ( store) => store. put_draft_chunk ( chunk) . await ,
410- Self :: Sqlite ( store) => store. put_draft_chunk ( chunk) . await ,
411- }
412- }
413-
414- /// Fetch a single draft chunk by id.
415- pub async fn get_draft_chunk ( & self , id : & str ) -> PersistenceResult < Option < DraftChunkRecord > > {
416- match self {
417- Self :: Postgres ( store) => store. get_draft_chunk ( id) . await ,
418- Self :: Sqlite ( store) => store. get_draft_chunk ( id) . await ,
419- }
420- }
421-
422- /// List draft chunks for a sandbox, optionally filtered by status.
423- pub async fn list_draft_chunks (
424- & self ,
425- sandbox_id : & str ,
426- status_filter : Option < & str > ,
427- ) -> PersistenceResult < Vec < DraftChunkRecord > > {
428- match self {
429- Self :: Postgres ( store) => store. list_draft_chunks ( sandbox_id, status_filter) . await ,
430- Self :: Sqlite ( store) => store. list_draft_chunks ( sandbox_id, status_filter) . await ,
431- }
432- }
433-
434- /// Update the status of a draft chunk.
435- pub async fn update_draft_chunk_status (
436- & self ,
437- id : & str ,
438- status : & str ,
439- decided_at_ms : Option < i64 > ,
440- ) -> PersistenceResult < bool > {
441- match self {
442- Self :: Postgres ( store) => {
443- store
444- . update_draft_chunk_status ( id, status, decided_at_ms)
445- . await
446- }
447- Self :: Sqlite ( store) => {
448- store
449- . update_draft_chunk_status ( id, status, decided_at_ms)
450- . await
451- }
452- }
453- }
454-
455- /// Update the proposed rule on a pending draft chunk.
456- pub async fn update_draft_chunk_rule (
457- & self ,
458- id : & str ,
459- proposed_rule : & [ u8 ] ,
460- ) -> PersistenceResult < bool > {
461- match self {
462- Self :: Postgres ( store) => store. update_draft_chunk_rule ( id, proposed_rule) . await ,
463- Self :: Sqlite ( store) => store. update_draft_chunk_rule ( id, proposed_rule) . await ,
464- }
465- }
466-
467- /// Delete all draft chunks for a sandbox with a given status.
468- pub async fn delete_draft_chunks (
469- & self ,
470- sandbox_id : & str ,
471- status : & str ,
472- ) -> PersistenceResult < u64 > {
473- match self {
474- Self :: Postgres ( store) => store. delete_draft_chunks ( sandbox_id, status) . await ,
475- Self :: Sqlite ( store) => store. delete_draft_chunks ( sandbox_id, status) . await ,
476- }
477- }
478-
479- /// Get the current maximum draft version for a sandbox.
480- pub async fn get_draft_version ( & self , sandbox_id : & str ) -> PersistenceResult < i64 > {
481- match self {
482- Self :: Postgres ( store) => store. get_draft_version ( sandbox_id) . await ,
483- Self :: Sqlite ( store) => store. get_draft_version ( sandbox_id) . await ,
484- }
485- }
486- }
487-
488- pub ( crate ) fn policy_payload_from_record ( record : & PolicyRecord ) -> PersistenceResult < Vec < u8 > > {
489- let policy = ProtoSandboxPolicy :: decode ( record. policy_payload . as_slice ( ) )
490- . map_err ( |e| PersistenceError :: Decode ( format ! ( "decode policy payload failed: {e}" ) ) ) ?;
491- Ok ( PolicyRevisionPayload {
492- policy : Some ( policy) ,
493- hash : record. policy_hash . clone ( ) ,
494- load_error : record. load_error . clone ( ) . unwrap_or_default ( ) ,
495- loaded_at_ms : record. loaded_at_ms . unwrap_or ( 0 ) ,
496- }
497- . encode_to_vec ( ) )
498- }
499-
500- pub ( crate ) fn policy_record_from_parts (
501- id : String ,
502- sandbox_id : String ,
503- version : i64 ,
504- status : String ,
505- payload : & [ u8 ] ,
506- created_at_ms : i64 ,
507- ) -> PersistenceResult < PolicyRecord > {
508- let wrapper = PolicyRevisionPayload :: decode ( payload)
509- . map_err ( |e| PersistenceError :: Decode ( format ! ( "decode policy wrapper failed: {e}" ) ) ) ?;
510- let policy = wrapper
511- . policy
512- . ok_or_else ( || PersistenceError :: Decode ( "policy wrapper missing policy" . to_string ( ) ) ) ?;
513- Ok ( PolicyRecord {
514- id,
515- sandbox_id,
516- version,
517- policy_payload : policy. encode_to_vec ( ) ,
518- policy_hash : wrapper. hash ,
519- status,
520- load_error : if wrapper. load_error . is_empty ( ) {
521- None
522- } else {
523- Some ( wrapper. load_error )
524- } ,
525- created_at_ms,
526- loaded_at_ms : ( wrapper. loaded_at_ms > 0 ) . then_some ( wrapper. loaded_at_ms ) ,
527- } )
528- }
529-
530- pub ( crate ) fn draft_chunk_payload_from_record (
531- chunk : & DraftChunkRecord ,
532- ) -> PersistenceResult < Vec < u8 > > {
533- let proposed_rule = if chunk. proposed_rule . is_empty ( ) {
534- None
535- } else {
536- Some (
537- NetworkPolicyRule :: decode ( chunk. proposed_rule . as_slice ( ) )
538- . map_err ( |e| PersistenceError :: Decode ( format ! ( "decode draft rule failed: {e}" ) ) ) ?,
539- )
540- } ;
541- Ok ( DraftChunkPayload {
542- rule_name : chunk. rule_name . clone ( ) ,
543- proposed_rule,
544- rationale : chunk. rationale . clone ( ) ,
545- security_notes : chunk. security_notes . clone ( ) ,
546- confidence : chunk. confidence as f32 ,
547- decided_at_ms : chunk. decided_at_ms . unwrap_or ( 0 ) ,
548- host : chunk. host . clone ( ) ,
549- port : chunk. port ,
550- binary : chunk. binary . clone ( ) ,
551- draft_version : chunk. draft_version ,
552- }
553- . encode_to_vec ( ) )
554- }
555-
556- pub ( crate ) fn draft_chunk_record_from_parts (
557- id : String ,
558- sandbox_id : String ,
559- status : String ,
560- hit_count : i64 ,
561- payload : & [ u8 ] ,
562- created_at_ms : i64 ,
563- updated_at_ms : i64 ,
564- ) -> PersistenceResult < DraftChunkRecord > {
565- let wrapper = DraftChunkPayload :: decode ( payload)
566- . map_err ( |e| PersistenceError :: Decode ( format ! ( "decode draft chunk wrapper failed: {e}" ) ) ) ?;
567- let proposed_rule = wrapper
568- . proposed_rule
569- . map ( |rule| rule. encode_to_vec ( ) )
570- . unwrap_or_default ( ) ;
571- Ok ( DraftChunkRecord {
572- id,
573- sandbox_id,
574- draft_version : wrapper. draft_version ,
575- status,
576- rule_name : wrapper. rule_name ,
577- proposed_rule,
578- rationale : wrapper. rationale ,
579- security_notes : wrapper. security_notes ,
580- confidence : f64:: from ( wrapper. confidence ) ,
581- created_at_ms,
582- decided_at_ms : ( wrapper. decided_at_ms > 0 ) . then_some ( wrapper. decided_at_ms ) ,
583- host : wrapper. host ,
584- port : wrapper. port ,
585- binary : wrapper. binary ,
586- hit_count : i32:: try_from ( hit_count) . unwrap_or ( i32:: MAX ) ,
587- first_seen_ms : created_at_ms,
588- last_seen_ms : updated_at_ms,
589- } )
590283}
591284
592285pub fn current_time_ms ( ) -> PersistenceResult < i64 > {
0 commit comments