From b109872b5c29f401ecf059c7d763f14d8ed51134 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Sun, 6 Apr 2025 22:02:52 -0500 Subject: T7321: add session_changed check --- data/vyconf.proto | 5 +++++ src/session.ml | 10 ++++++++++ src/session.mli | 2 ++ src/vyconf_pbt.ml | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vyconf_pbt.mli | 20 +++++++++++++++++++ src/vyconfd.ml | 5 +++++ 6 files changed, 99 insertions(+) diff --git a/data/vyconf.proto b/data/vyconf.proto index 69bc1d4..815ec68 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -38,6 +38,10 @@ message Request { optional int32 dummy = 1; } + message SessionChanged { + optional int32 dummy = 1; + } + message Rename { repeated string EditLevel = 1; required string From = 2; @@ -154,6 +158,7 @@ message Request { ReloadReftree reload_reftree = 23; Load load = 24; Discard discard = 25; + SessionChanged session_changed = 26; } } diff --git a/src/session.ml b/src/session.ml index 953df25..8cfe355 100644 --- a/src/session.ml +++ b/src/session.ml @@ -1,4 +1,5 @@ module CT = Vyos1x.Config_tree +module CD = Vyos1x.Config_diff module VT = Vyos1x.Vytree module RT = Vyos1x.Reference_tree module D = Directories @@ -110,6 +111,15 @@ let delete w s path = let discard w s = {s with proposed_config=w.running_config} +let session_changed w s = + (* structural equality test requires consistent ordering, which is + * practised, but may be unreliable; test actual difference + *) + let diff = CD.diff_tree [] w.running_config s.proposed_config in + let add_tree = CT.get_subtree diff ["add"] in + let del_tree = CT.get_subtree diff ["del"] in + (del_tree <> CT.default) || (add_tree <> CT.default) + let load w s file = let ct = Vyos1x.Config_file.load_config file in match ct with diff --git a/src/session.mli b/src/session.mli index af12af8..9b8c5a0 100644 --- a/src/session.mli +++ b/src/session.mli @@ -34,6 +34,8 @@ val delete : world -> session_data -> string list -> session_data val discard : world -> session_data -> session_data +val session_changed : world -> session_data -> bool + val load : world -> session_data -> string -> session_data val save : world -> session_data -> string -> session_data diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index c8e76ef..5518e27 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -36,6 +36,10 @@ type request_discard = { dummy : int32 option; } +type request_session_changed = { + dummy : int32 option; +} + type request_rename = { edit_level : string list; from : string; @@ -147,6 +151,7 @@ type request = | Reload_reftree of request_reload_reftree | Load of request_load | Discard of request_discard + | Session_changed of request_session_changed type request_envelope = { token : string option; @@ -217,6 +222,12 @@ let rec default_request_discard dummy; } +let rec default_request_session_changed + ?dummy:((dummy:int32 option) = None) + () : request_session_changed = { + dummy; +} + let rec default_request_rename ?edit_level:((edit_level:string list) = []) ?from:((from:string) = "") @@ -427,6 +438,14 @@ let default_request_discard_mutable () : request_discard_mutable = { dummy = None; } +type request_session_changed_mutable = { + mutable dummy : int32 option; +} + +let default_request_session_changed_mutable () : request_session_changed_mutable = { + dummy = None; +} + type request_rename_mutable = { mutable edit_level : string list; mutable from : string; @@ -671,6 +690,12 @@ let rec pp_request_discard fmt (v:request_discard) = in Pbrt.Pp.pp_brk pp_i fmt () +let rec pp_request_session_changed fmt (v:request_session_changed) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "dummy" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.dummy; + in + Pbrt.Pp.pp_brk pp_i fmt () + let rec pp_request_rename fmt (v:request_rename) = let pp_i fmt () = Pbrt.Pp.pp_record_field ~first:true "edit_level" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.edit_level; @@ -823,6 +848,7 @@ let rec pp_request fmt (v:request) = | Reload_reftree x -> Format.fprintf fmt "@[Reload_reftree(@,%a)@]" pp_request_reload_reftree x | Load x -> Format.fprintf fmt "@[Load(@,%a)@]" pp_request_load x | Discard x -> Format.fprintf fmt "@[Discard(@,%a)@]" pp_request_discard x + | Session_changed x -> Format.fprintf fmt "@[Session_changed(@,%a)@]" pp_request_session_changed x let rec pp_request_envelope fmt (v:request_envelope) = let pp_i fmt () = @@ -929,6 +955,15 @@ let rec encode_pb_request_discard (v:request_discard) encoder = end; () +let rec encode_pb_request_session_changed (v:request_session_changed) encoder = + begin match v.dummy with + | Some x -> + Pbrt.Encoder.int32_as_varint x encoder; + Pbrt.Encoder.key 1 Pbrt.Varint encoder; + | None -> (); + end; + () + let rec encode_pb_request_rename (v:request_rename) encoder = Pbrt.List_util.rev_iter_with (fun x encoder -> Pbrt.Encoder.string x encoder; @@ -1196,6 +1231,9 @@ let rec encode_pb_request (v:request) encoder = | Discard x -> Pbrt.Encoder.nested encode_pb_request_discard x encoder; Pbrt.Encoder.key 25 Pbrt.Bytes encoder; + | Session_changed x -> + Pbrt.Encoder.nested encode_pb_request_session_changed x encoder; + Pbrt.Encoder.key 26 Pbrt.Bytes encoder; end let rec encode_pb_request_envelope (v:request_envelope) encoder = @@ -1389,6 +1427,24 @@ let rec decode_pb_request_discard d = dummy = v.dummy; } : request_discard) +let rec decode_pb_request_session_changed d = + let v = default_request_session_changed_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + ); continue__ := false + | Some (1, Pbrt.Varint) -> begin + v.dummy <- Some (Pbrt.Decoder.int32_as_varint d); + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_session_changed), field(1)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + dummy = v.dummy; + } : request_session_changed) + let rec decode_pb_request_rename d = let v = default_request_rename_mutable () in let continue__= ref true in @@ -1860,6 +1916,7 @@ let rec decode_pb_request d = | Some (23, _) -> (Reload_reftree (decode_pb_request_reload_reftree (Pbrt.Decoder.nested d)) : request) | Some (24, _) -> (Load (decode_pb_request_load (Pbrt.Decoder.nested d)) : request) | Some (25, _) -> (Discard (decode_pb_request_discard (Pbrt.Decoder.nested d)) : request) + | Some (26, _) -> (Session_changed (decode_pb_request_session_changed (Pbrt.Decoder.nested d)) : request) | Some (n, payload_kind) -> ( Pbrt.Decoder.skip d payload_kind; loop () diff --git a/src/vyconf_pbt.mli b/src/vyconf_pbt.mli index b4affb8..5f768f8 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -43,6 +43,10 @@ type request_discard = { dummy : int32 option; } +type request_session_changed = { + dummy : int32 option; +} + type request_rename = { edit_level : string list; from : string; @@ -154,6 +158,7 @@ type request = | Reload_reftree of request_reload_reftree | Load of request_load | Discard of request_discard + | Session_changed of request_session_changed type request_envelope = { token : string option; @@ -228,6 +233,12 @@ val default_request_discard : request_discard (** [default_request_discard ()] is the default value for type [request_discard] *) +val default_request_session_changed : + ?dummy:int32 option -> + unit -> + request_session_changed +(** [default_request_session_changed ()] is the default value for type [request_session_changed] *) + val default_request_rename : ?edit_level:string list -> ?from:string -> @@ -399,6 +410,9 @@ val pp_request_delete : Format.formatter -> request_delete -> unit val pp_request_discard : Format.formatter -> request_discard -> unit (** [pp_request_discard v] formats v *) +val pp_request_session_changed : Format.formatter -> request_session_changed -> unit +(** [pp_request_session_changed v] formats v *) + val pp_request_rename : Format.formatter -> request_rename -> unit (** [pp_request_rename v] formats v *) @@ -495,6 +509,9 @@ val encode_pb_request_delete : request_delete -> Pbrt.Encoder.t -> unit val encode_pb_request_discard : request_discard -> Pbrt.Encoder.t -> unit (** [encode_pb_request_discard v encoder] encodes [v] with the given [encoder] *) +val encode_pb_request_session_changed : request_session_changed -> Pbrt.Encoder.t -> unit +(** [encode_pb_request_session_changed v encoder] encodes [v] with the given [encoder] *) + val encode_pb_request_rename : request_rename -> Pbrt.Encoder.t -> unit (** [encode_pb_request_rename v encoder] encodes [v] with the given [encoder] *) @@ -591,6 +608,9 @@ val decode_pb_request_delete : Pbrt.Decoder.t -> request_delete val decode_pb_request_discard : Pbrt.Decoder.t -> request_discard (** [decode_pb_request_discard decoder] decodes a [request_discard] binary value from [decoder] *) +val decode_pb_request_session_changed : Pbrt.Decoder.t -> request_session_changed +(** [decode_pb_request_session_changed decoder] decodes a [request_session_changed] binary value from [decoder] *) + val decode_pb_request_rename : Pbrt.Decoder.t -> request_rename (** [decode_pb_request_rename decoder] decodes a [request_rename] binary value from [decoder] *) diff --git a/src/vyconfd.ml b/src/vyconfd.ml index e37a6ae..885fd20 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -95,6 +95,10 @@ let teardown token = with Not_found -> {response_tmpl with status=Fail; error=(Some "Session not found")} +let session_changed world token (_req: request_session_changed) = + if Session.session_changed world (find_session token) then response_tmpl + else {response_tmpl with status=Fail} + let exists world token (req: request_exists) = if Session.exists world (find_session token) req.path then response_tmpl else {response_tmpl with status=Fail} @@ -275,6 +279,7 @@ let rec handle_connection world ic oc () = | Some t, Set r -> set world t r | Some t, Delete r -> delete world t r | Some t, Discard r -> discard world t r + | Some t, Session_changed r -> session_changed world t r | Some t, Load r -> load world t r | Some t, Save r -> save world t r | _ -> failwith "Unimplemented" -- cgit v1.2.3