From 1e4f661b8c29edf0b03eac4adf032735d6a885a7 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Mon, 23 Jun 2025 14:42:05 -0500 Subject: T7499: allow load from internal representation to avoid re-parsing --- data/vyconf.proto | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index 30f213c..4466837 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -85,7 +85,8 @@ message Request { message Load { required string Location = 1; - optional ConfigFormat format = 2; + required bool cached = 2; + optional ConfigFormat format = 3; } message Merge { -- cgit v1.2.3 From 59ebae9198439ddd1e9bbdec61d163f638e1071a Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Tue, 24 Jun 2025 07:07:09 -0500 Subject: T7499: use direct request to vyconfd to avoid re-validating paths Merging before passing to the backend results in re-validation of existing paths in the proposed config; this is unavoidable with the legacy backend. For vyconf, send the merge proposal with the request, so validation is only required on new paths. --- data/vyconf.proto | 3 ++- src/session.ml | 10 ++++++++++ src/session.mli | 2 ++ src/vyconf_pbt.ml | 20 ++++++++++++++++++-- src/vyconf_pbt.mli | 2 ++ src/vyconfd.ml | 9 +++++++++ 6 files changed, 43 insertions(+), 3 deletions(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index 4466837..30f95aa 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -91,7 +91,8 @@ message Request { message Merge { required string Location = 1; - optional ConfigFormat format = 2; + required bool destructive = 2; + optional ConfigFormat format = 3; } message Save { diff --git a/src/session.ml b/src/session.ml index 72e766d..5e276c2 100644 --- a/src/session.ml +++ b/src/session.ml @@ -142,6 +142,16 @@ let load w s file cached = | Ok config -> validate_tree w config; {s with proposed_config=config;} +let merge w s file destructive = + let ct = Vyos1x.Config_file.load_config file in + match ct with + | Error e -> raise (Session_error (Printf.sprintf "Error loading config: %s" e)) + | Ok config -> + let () = validate_tree w config in + let merged = CD.tree_merge ~destructive:destructive s.proposed_config config + in + {s with proposed_config=merged;} + let save w s file = let ct = w.running_config in let res = Vyos1x.Config_file.save_config ct file in diff --git a/src/session.mli b/src/session.mli index 0398bb1..1a9b79f 100644 --- a/src/session.mli +++ b/src/session.mli @@ -39,6 +39,8 @@ val session_changed : world -> session_data -> bool val load : world -> session_data -> string -> bool -> session_data +val merge : world -> session_data -> string -> bool -> session_data + val save : world -> session_data -> string -> session_data val get_value : world -> session_data -> string list -> string diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index facf9f5..913fcea 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -89,6 +89,7 @@ type request_load = { type request_merge = { location : string; + destructive : bool; format : request_config_format option; } @@ -324,9 +325,11 @@ let rec default_request_load let rec default_request_merge ?location:((location:string) = "") + ?destructive:((destructive:bool) = false) ?format:((format:request_config_format option) = None) () : request_merge = { location; + destructive; format; } @@ -582,11 +585,13 @@ let default_request_load_mutable () : request_load_mutable = { type request_merge_mutable = { mutable location : string; + mutable destructive : bool; mutable format : request_config_format option; } let default_request_merge_mutable () : request_merge_mutable = { location = ""; + destructive = false; format = None; } @@ -832,6 +837,7 @@ let rec pp_request_load fmt (v:request_load) = let rec pp_request_merge fmt (v:request_merge) = let pp_i fmt () = Pbrt.Pp.pp_record_field ~first:true "location" Pbrt.Pp.pp_string fmt v.location; + Pbrt.Pp.pp_record_field ~first:false "destructive" Pbrt.Pp.pp_bool fmt v.destructive; Pbrt.Pp.pp_record_field ~first:false "format" (Pbrt.Pp.pp_option pp_request_config_format) fmt v.format; in Pbrt.Pp.pp_brk pp_i fmt () @@ -1156,10 +1162,12 @@ let rec encode_pb_request_load (v:request_load) encoder = let rec encode_pb_request_merge (v:request_merge) encoder = Pbrt.Encoder.string v.location encoder; Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + Pbrt.Encoder.bool v.destructive encoder; + Pbrt.Encoder.key 2 Pbrt.Varint encoder; begin match v.format with | Some x -> encode_pb_request_config_format x encoder; - Pbrt.Encoder.key 2 Pbrt.Varint encoder; + Pbrt.Encoder.key 3 Pbrt.Varint encoder; | None -> (); end; () @@ -1826,6 +1834,7 @@ let rec decode_pb_request_load d = let rec decode_pb_request_merge d = let v = default_request_merge_mutable () in let continue__= ref true in + let destructive_is_set = ref false in let location_is_set = ref false in while !continue__ do match Pbrt.Decoder.key d with @@ -1837,15 +1846,22 @@ let rec decode_pb_request_merge d = | Some (1, pk) -> Pbrt.Decoder.unexpected_payload "Message(request_merge), field(1)" pk | Some (2, Pbrt.Varint) -> begin - v.format <- Some (decode_pb_request_config_format d); + v.destructive <- Pbrt.Decoder.bool d; destructive_is_set := true; end | Some (2, pk) -> Pbrt.Decoder.unexpected_payload "Message(request_merge), field(2)" pk + | Some (3, Pbrt.Varint) -> begin + v.format <- Some (decode_pb_request_config_format d); + end + | Some (3, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_merge), field(3)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; + begin if not !destructive_is_set then Pbrt.Decoder.missing_field "destructive" end; begin if not !location_is_set then Pbrt.Decoder.missing_field "location" end; ({ location = v.location; + destructive = v.destructive; format = v.format; } : request_merge) diff --git a/src/vyconf_pbt.mli b/src/vyconf_pbt.mli index 42a4af6..c9a7530 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -96,6 +96,7 @@ type request_load = { type request_merge = { location : string; + destructive : bool; format : request_config_format option; } @@ -324,6 +325,7 @@ val default_request_load : val default_request_merge : ?location:string -> + ?destructive:bool -> ?format:request_config_format option -> unit -> request_merge diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 379a55e..a0be019 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -223,6 +223,14 @@ let load world token (req: request_load) = response_tmpl with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} +let merge world token (req: request_merge) = + try + let session = Session.merge world (find_session token) req.location req.destructive + in + Hashtbl.replace sessions token session; + response_tmpl + with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} + let save world token (req: request_save) = try let _ = Session.save world (find_session token) req.location @@ -319,6 +327,7 @@ let rec handle_connection world ic oc () = | Some t, Session_changed r -> session_changed world t r | Some t, Get_config r -> get_config world t r | Some t, Load r -> load world t r + | Some t, Merge r -> merge world t r | Some t, Save r -> save world t r | _ -> failwith "Unimplemented" ) |> Lwt.return -- cgit v1.2.3