From 024de8901245d531a85ef6ba5623aec6e33616d7 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Wed, 10 Sep 2025 09:31:52 -0500 Subject: T7737: normalize protobuf field name style Enforce consistent naming style according to https://protobuf.dev/programming-guides/style/ --- data/vyconf.proto | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index 30f95aa..e67312c 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -13,17 +13,17 @@ message Request { } message SetupSession { - required int32 ClientPid = 1; - optional string ClientApplication = 2; - optional int32 OnBehalfOf = 3; + required int32 client_pid = 1; + optional string client_application = 2; + optional int32 on_behalf_of = 3; } message SessionOfPid { - required int32 ClientPid = 1; + required int32 client_pid = 1; } message SessionUpdatePid { - required int32 ClientPid = 1; + required int32 client_pid = 1; } message GetConfig { @@ -31,7 +31,7 @@ message Request { } message Teardown { - optional int32 OnBehalfOf = 1; + optional int32 on_behalf_of = 1; } message Validate { @@ -40,11 +40,11 @@ message Request { } message Set { - repeated string Path = 1; + repeated string path = 1; } message Delete { - repeated string Path = 1; + repeated string path = 1; } message Discard { @@ -56,76 +56,76 @@ message Request { } message Rename { - repeated string EditLevel = 1; - required string From = 2; - required string To = 3; + repeated string edit_level = 1; + required string source = 2; + required string destination = 3; } message Copy { - repeated string EditLevel = 1; - required string From = 2; - required string To = 3; + repeated string edit_level = 1; + required string source = 2; + required string destination = 3; } message Comment { - repeated string Path = 1; - required string Comment = 2; + repeated string path = 1; + required string comment = 2; } message Commit { - optional bool Confirm = 1; - optional int32 ConfirmTimeout = 2; - optional string Comment = 3; - optional bool DryRun = 4; + optional bool confirm = 1; + optional int32 confirm_timeout = 2; + optional string comment = 3; + optional bool dry_run = 4; } message Rollback { - required int32 Revision = 1; + required int32 revision = 1; } message Load { - required string Location = 1; + required string location = 1; required bool cached = 2; optional ConfigFormat format = 3; } message Merge { - required string Location = 1; + required string location = 1; required bool destructive = 2; optional ConfigFormat format = 3; } message Save { - required string Location = 1; + required string location = 1; optional ConfigFormat format = 2; } message ShowConfig { - repeated string Path = 1; + repeated string path = 1; optional ConfigFormat format = 2; } message Exists { - repeated string Path = 1; + repeated string path = 1; } message GetValue { - repeated string Path = 1; + repeated string path = 1; optional OutputFormat output_format = 2; } message GetValues { - repeated string Path = 1; + repeated string path = 1; optional OutputFormat output_format = 2; } message ListChildren { - repeated string Path = 1; + repeated string path = 1; optional OutputFormat output_format = 2; } message RunOpMode { - repeated string Path = 1; + repeated string path = 1; optional OutputFormat output_format = 2; } @@ -133,8 +133,8 @@ message Request { } message EnterConfigurationMode { - required bool Exclusive = 1; - required bool OverrideExclusive = 2; + required bool exclusive = 1; + required bool override_exclusive = 2; } message ExitConfigurationMode { @@ -143,7 +143,7 @@ message Request { message ReloadReftree { // this is a temporary workaround for a bug with empty messages, and // will be removed when the issue is resolved - optional int32 OnBehalfOf = 1; + optional int32 on_behalf_of = 1; } -- cgit v1.2.3 From 895f52e54fe32ba5c98d8bb69c5c8c67ddaad0fc Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Wed, 10 Sep 2025 11:39:24 -0500 Subject: T7737: replace unuseful session_update_pid with session_exists The request session_update_pid is not useful, possibly dangerous, in the current design. Remove and add a simple session_exists for use in client initialization. --- data/vyconf.proto | 6 +++--- src/vyconf_pbt.ml | 58 ++++++++++++++++++++++++++++-------------------------- src/vyconf_pbt.mli | 26 ++++++++++++------------ src/vyconfd.ml | 12 +++-------- 4 files changed, 49 insertions(+), 53 deletions(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index e67312c..9b6c882 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -22,8 +22,8 @@ message Request { required int32 client_pid = 1; } - message SessionUpdatePid { - required int32 client_pid = 1; + message SessionExists { + optional int32 dummy = 1; } message GetConfig { @@ -175,7 +175,7 @@ message Request { Discard discard = 25; SessionChanged session_changed = 26; SessionOfPid session_of_pid = 27; - SessionUpdatePid session_update_pid = 28; + SessionExists session_exists = 28; GetConfig get_config = 29; } } diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index 4bb26f2..96ba497 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -20,8 +20,8 @@ type request_session_of_pid = { client_pid : int32; } -type request_session_update_pid = { - client_pid : int32; +type request_session_exists = { + dummy : int32 option; } type request_get_config = { @@ -168,7 +168,7 @@ type request = | Discard of request_discard | Session_changed of request_session_changed | Session_of_pid of request_session_of_pid - | Session_update_pid of request_session_update_pid + | Session_exists of request_session_exists | Get_config of request_get_config type request_envelope = { @@ -217,10 +217,10 @@ let rec default_request_session_of_pid client_pid; } -let rec default_request_session_update_pid - ?client_pid:((client_pid:int32) = 0l) - () : request_session_update_pid = { - client_pid; +let rec default_request_session_exists + ?dummy:((dummy:int32 option) = None) + () : request_session_exists = { + dummy; } let rec default_request_get_config @@ -449,12 +449,12 @@ let default_request_session_of_pid_mutable () : request_session_of_pid_mutable = client_pid = 0l; } -type request_session_update_pid_mutable = { - mutable client_pid : int32; +type request_session_exists_mutable = { + mutable dummy : int32 option; } -let default_request_session_update_pid_mutable () : request_session_update_pid_mutable = { - client_pid = 0l; +let default_request_session_exists_mutable () : request_session_exists_mutable = { + dummy = None; } type request_get_config_mutable = { @@ -739,9 +739,9 @@ let rec pp_request_session_of_pid fmt (v:request_session_of_pid) = in Pbrt.Pp.pp_brk pp_i fmt () -let rec pp_request_session_update_pid fmt (v:request_session_update_pid) = +let rec pp_request_session_exists fmt (v:request_session_exists) = let pp_i fmt () = - Pbrt.Pp.pp_record_field ~first:true "client_pid" Pbrt.Pp.pp_int32 fmt v.client_pid; + 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 () @@ -944,7 +944,7 @@ let rec pp_request fmt (v:request) = | 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 | Session_of_pid x -> Format.fprintf fmt "@[Session_of_pid(@,%a)@]" pp_request_session_of_pid x - | Session_update_pid x -> Format.fprintf fmt "@[Session_update_pid(@,%a)@]" pp_request_session_update_pid x + | Session_exists x -> Format.fprintf fmt "@[Session_exists(@,%a)@]" pp_request_session_exists x | Get_config x -> Format.fprintf fmt "@[Get_config(@,%a)@]" pp_request_get_config x let rec pp_request_envelope fmt (v:request_envelope) = @@ -1015,9 +1015,13 @@ let rec encode_pb_request_session_of_pid (v:request_session_of_pid) encoder = Pbrt.Encoder.key 1 Pbrt.Varint encoder; () -let rec encode_pb_request_session_update_pid (v:request_session_update_pid) encoder = - Pbrt.Encoder.int32_as_varint v.client_pid encoder; - Pbrt.Encoder.key 1 Pbrt.Varint encoder; +let rec encode_pb_request_session_exists (v:request_session_exists) 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_get_config (v:request_get_config) encoder = @@ -1360,8 +1364,8 @@ let rec encode_pb_request (v:request) encoder = | Session_of_pid x -> Pbrt.Encoder.nested encode_pb_request_session_of_pid x encoder; Pbrt.Encoder.key 27 Pbrt.Bytes encoder; - | Session_update_pid x -> - Pbrt.Encoder.nested encode_pb_request_session_update_pid x encoder; + | Session_exists x -> + Pbrt.Encoder.nested encode_pb_request_session_exists x encoder; Pbrt.Encoder.key 28 Pbrt.Bytes encoder; | Get_config x -> Pbrt.Encoder.nested encode_pb_request_get_config x encoder; @@ -1489,25 +1493,23 @@ let rec decode_pb_request_session_of_pid d = client_pid = v.client_pid; } : request_session_of_pid) -let rec decode_pb_request_session_update_pid d = - let v = default_request_session_update_pid_mutable () in +let rec decode_pb_request_session_exists d = + let v = default_request_session_exists_mutable () in let continue__= ref true in - let client_pid_is_set = ref false in while !continue__ do match Pbrt.Decoder.key d with | None -> ( ); continue__ := false | Some (1, Pbrt.Varint) -> begin - v.client_pid <- Pbrt.Decoder.int32_as_varint d; client_pid_is_set := true; + v.dummy <- Some (Pbrt.Decoder.int32_as_varint d); end | Some (1, pk) -> - Pbrt.Decoder.unexpected_payload "Message(request_session_update_pid), field(1)" pk + Pbrt.Decoder.unexpected_payload "Message(request_session_exists), field(1)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; - begin if not !client_pid_is_set then Pbrt.Decoder.missing_field "client_pid" end; ({ - client_pid = v.client_pid; - } : request_session_update_pid) + dummy = v.dummy; + } : request_session_exists) let rec decode_pb_request_get_config d = let v = default_request_get_config_mutable () in @@ -2133,7 +2135,7 @@ let rec decode_pb_request d = | 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 (27, _) -> (Session_of_pid (decode_pb_request_session_of_pid (Pbrt.Decoder.nested d)) : request) - | Some (28, _) -> (Session_update_pid (decode_pb_request_session_update_pid (Pbrt.Decoder.nested d)) : request) + | Some (28, _) -> (Session_exists (decode_pb_request_session_exists (Pbrt.Decoder.nested d)) : request) | Some (29, _) -> (Get_config (decode_pb_request_get_config (Pbrt.Decoder.nested d)) : request) | Some (n, payload_kind) -> ( Pbrt.Decoder.skip d payload_kind; diff --git a/src/vyconf_pbt.mli b/src/vyconf_pbt.mli index 85e8ba4..e2c2245 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -27,8 +27,8 @@ type request_session_of_pid = { client_pid : int32; } -type request_session_update_pid = { - client_pid : int32; +type request_session_exists = { + dummy : int32 option; } type request_get_config = { @@ -175,7 +175,7 @@ type request = | Discard of request_discard | Session_changed of request_session_changed | Session_of_pid of request_session_of_pid - | Session_update_pid of request_session_update_pid + | Session_exists of request_session_exists | Get_config of request_get_config type request_envelope = { @@ -228,11 +228,11 @@ val default_request_session_of_pid : request_session_of_pid (** [default_request_session_of_pid ()] is the default value for type [request_session_of_pid] *) -val default_request_session_update_pid : - ?client_pid:int32 -> +val default_request_session_exists : + ?dummy:int32 option -> unit -> - request_session_update_pid -(** [default_request_session_update_pid ()] is the default value for type [request_session_update_pid] *) + request_session_exists +(** [default_request_session_exists ()] is the default value for type [request_session_exists] *) val default_request_get_config : ?dummy:int32 option -> @@ -438,8 +438,8 @@ val pp_request_setup_session : Format.formatter -> request_setup_session -> unit val pp_request_session_of_pid : Format.formatter -> request_session_of_pid -> unit (** [pp_request_session_of_pid v] formats v *) -val pp_request_session_update_pid : Format.formatter -> request_session_update_pid -> unit -(** [pp_request_session_update_pid v] formats v *) +val pp_request_session_exists : Format.formatter -> request_session_exists -> unit +(** [pp_request_session_exists v] formats v *) val pp_request_get_config : Format.formatter -> request_get_config -> unit (** [pp_request_get_config v] formats v *) @@ -546,8 +546,8 @@ val encode_pb_request_setup_session : request_setup_session -> Pbrt.Encoder.t -> val encode_pb_request_session_of_pid : request_session_of_pid -> Pbrt.Encoder.t -> unit (** [encode_pb_request_session_of_pid v encoder] encodes [v] with the given [encoder] *) -val encode_pb_request_session_update_pid : request_session_update_pid -> Pbrt.Encoder.t -> unit -(** [encode_pb_request_session_update_pid v encoder] encodes [v] with the given [encoder] *) +val encode_pb_request_session_exists : request_session_exists -> Pbrt.Encoder.t -> unit +(** [encode_pb_request_session_exists v encoder] encodes [v] with the given [encoder] *) val encode_pb_request_get_config : request_get_config -> Pbrt.Encoder.t -> unit (** [encode_pb_request_get_config v encoder] encodes [v] with the given [encoder] *) @@ -654,8 +654,8 @@ val decode_pb_request_setup_session : Pbrt.Decoder.t -> request_setup_session val decode_pb_request_session_of_pid : Pbrt.Decoder.t -> request_session_of_pid (** [decode_pb_request_session_of_pid decoder] decodes a [request_session_of_pid] binary value from [decoder] *) -val decode_pb_request_session_update_pid : Pbrt.Decoder.t -> request_session_update_pid -(** [decode_pb_request_session_update_pid decoder] decodes a [request_session_update_pid] binary value from [decoder] *) +val decode_pb_request_session_exists : Pbrt.Decoder.t -> request_session_exists +(** [decode_pb_request_session_exists decoder] decodes a [request_session_exists] binary value from [decoder] *) val decode_pb_request_get_config : Pbrt.Decoder.t -> request_get_config (** [decode_pb_request_get_config decoder] decodes a [request_get_config] binary value from [decoder] *) diff --git a/src/vyconfd.ml b/src/vyconfd.ml index f1b1694..d765ed8 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -77,15 +77,9 @@ let session_of_pid _world (req: request_session_of_pid) = let extant = find_session_by_pid pid in {response_tmpl with output=extant} -let session_update_pid _world token (req: request_session_update_pid) = - let pid = req.client_pid in +let session_exists _world token (_req: request_session_exists) = try - begin - let s = Hashtbl.find sessions token in - if s.client_pid <> pid then - let session = {s with client_pid=pid} in - Hashtbl.replace sessions token session - end; + let _ = Hashtbl.find sessions token in {response_tmpl with output=(Some token)} with Not_found -> {response_tmpl with status=Fail; output=None} @@ -320,7 +314,7 @@ let rec handle_connection world ic oc () = | _, Session_of_pid r -> session_of_pid world r | _, Reload_reftree r -> reload_reftree world r | None, _ -> {response_tmpl with status=Fail; output=(Some "Operation requires session token")} - | Some t, Session_update_pid r -> session_update_pid world t r + | Some t, Session_exists r -> session_exists world t r | Some t, Teardown _ -> teardown world t | Some t, Enter_configuration_mode r -> enter_conf_mode r t | Some t, Exit_configuration_mode -> exit_conf_mode world t -- cgit v1.2.3 From a0a14ea1ee38ce78f7433b3a93f7eea61c8163fc Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Wed, 10 Sep 2025 12:50:52 -0500 Subject: T7737: add user and sudo_user fields to session for use in commit Add optional protobuf fields to convey environment variables USER and SUDO_USER, as needed for some config_mode scripts. Add non-option fields to the session record type, defaulting to the empty string. --- data/vyconf.proto | 2 ++ src/session.ml | 8 +++++--- src/session.mli | 7 ++++--- src/vycli.ml | 10 +++++++++- src/vyconf_cli.ml | 10 +++++++++- src/vyconf_client.ml | 10 ++++++++-- src/vyconf_client.mli | 2 +- src/vyconf_client_session.ml | 12 +++++++++++- src/vyconf_pbt.ml | 36 ++++++++++++++++++++++++++++++++++++ src/vyconf_pbt.mli | 4 ++++ src/vyconfd.ml | 13 +++++++++++-- 11 files changed, 100 insertions(+), 14 deletions(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index 9b6c882..5323856 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -16,6 +16,8 @@ message Request { required int32 client_pid = 1; optional string client_application = 2; optional int32 on_behalf_of = 3; + optional string client_user = 4; + optional string client_sudo_user = 5; } message SessionOfPid { diff --git a/src/session.ml b/src/session.ml index 5efc9f5..23c3d19 100644 --- a/src/session.ml +++ b/src/session.ml @@ -26,17 +26,19 @@ type session_data = { conf_mode: bool; changeset: cfg_op list; client_app: string; - user: string; client_pid: int32; + client_user: string; + client_sudo_user: string; } -let make world client_app user pid = { +let make world client_app sudo_user user pid = { proposed_config = world.running_config; modified = false; conf_mode = false; changeset = []; client_app = client_app; - user = user; + client_user = user; + client_sudo_user = sudo_user; client_pid = pid; } diff --git a/src/session.mli b/src/session.mli index abe5165..5dbbaf0 100644 --- a/src/session.mli +++ b/src/session.mli @@ -15,13 +15,14 @@ type session_data = { conf_mode: bool; changeset: cfg_op list; client_app: string; - user: string; - client_pid: int32 + client_pid: int32; + client_user: string; + client_sudo_user: string; } exception Session_error of string -val make : world -> string -> string -> int32 -> session_data +val make : world -> string -> string -> string -> int32 -> session_data val set_modified : session_data -> session_data diff --git a/src/vycli.ml b/src/vycli.ml index 174d6f4..6b13bdd 100644 --- a/src/vycli.ml +++ b/src/vycli.ml @@ -68,7 +68,15 @@ let main socket op path out_format config_format = end | OpSetupSession -> let pid = Int32.of_int (Unix.getppid ()) in - let%lwt resp = setup_session client "vycli" pid in + let user = + try Sys.getenv "USER" + with Not_found -> "" + in + let sudo_user = + try Sys.getenv "SUDO_USER" + with Not_found -> "" + in + let%lwt resp = setup_session client "vycli" sudo_user user pid in begin match resp with | Ok c -> get_token c diff --git a/src/vyconf_cli.ml b/src/vyconf_cli.ml index 0d1535e..b2ee630 100644 --- a/src/vyconf_cli.ml +++ b/src/vyconf_cli.ml @@ -39,6 +39,14 @@ let in_cli_config_session () = let get_session () = let pid = Int32.of_int (Unix.getppid()) in + let user = + try Sys.getenv "USER" + with Not_found -> "" + in + let sudo_user = + try Sys.getenv "SUDO_USER" + with Not_found -> "" + in let socket = "/var/run/vyconfd.sock" in let config_format = config_format_of_string "curly" in let out_format = output_format_of_string "plain" in @@ -47,7 +55,7 @@ let get_session () = in let%lwt resp = session_of_pid client pid in match resp with - | Error _ -> setup_session client "vyconf_cli" pid + | Error _ -> setup_session client "vyconf_cli" sudo_user user pid | _ as c -> c |> Lwt.return let close_session () = diff --git a/src/vyconf_client.ml b/src/vyconf_client.ml index 05b5548..25b923f 100644 --- a/src/vyconf_client.ml +++ b/src/vyconf_client.ml @@ -53,10 +53,16 @@ let prompt client = let%lwt resp = do_request client req in Lwt.return resp -let setup_session ?(on_behalf_of=None) client client_app pid = +let setup_session ?(on_behalf_of=None) client client_app sudo_user user pid = if Option.is_some client.session then Lwt.return (Error "Client is already associated with a session") else let id = on_behalf_of |> (function None -> None | Some x -> (Some (Int32.of_int x))) in - let req = Setup_session {client_application=(Some client_app); on_behalf_of=id; client_pid=pid} in + let req = + Setup_session { client_application=(Some client_app); + on_behalf_of=id; + client_sudo_user=Some sudo_user; + client_user=Some user; + client_pid=pid; } + in let%lwt resp = do_request client req in match resp.status with | Success -> diff --git a/src/vyconf_client.mli b/src/vyconf_client.mli index 762495d..9c63652 100644 --- a/src/vyconf_client.mli +++ b/src/vyconf_client.mli @@ -8,7 +8,7 @@ val shutdown : t -> t Lwt.t val prompt : t -> Vyconf_connect.Vyconf_pbt.response Lwt.t -val setup_session : ?on_behalf_of:(int option) -> t -> string -> int32 -> (t, string) result Lwt.t +val setup_session : ?on_behalf_of:(int option) -> t -> string -> string -> string -> int32 -> (t, string) result Lwt.t val session_of_pid : t -> int32 -> (t, string) result Lwt.t diff --git a/src/vyconf_client_session.ml b/src/vyconf_client_session.ml index 93068fa..035f191 100644 --- a/src/vyconf_client_session.ml +++ b/src/vyconf_client_session.ml @@ -34,7 +34,17 @@ let call_op ?(out_format="plain") ?(config_format="curly") socket token op path match o with | OpSetupSession -> let pid = Int32.of_int (Unix.getppid ()) in - let%lwt resp = Vyconf_client.setup_session client "vyconf_client_session" pid in + let user = + try Sys.getenv "USER" + with Not_found -> "" + in + let sudo_user = + try Sys.getenv "SUDO_USER" + with Not_found -> "" + in + let%lwt resp = + Vyconf_client.setup_session client "vyconf_client_session" sudo_user user pid + in begin match resp with | Ok c -> Vyconf_client.get_token c diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index 96ba497..a89f9a8 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -14,6 +14,8 @@ type request_setup_session = { client_pid : int32; client_application : string option; on_behalf_of : int32 option; + client_user : string option; + client_sudo_user : string option; } type request_session_of_pid = { @@ -205,10 +207,14 @@ let rec default_request_setup_session ?client_pid:((client_pid:int32) = 0l) ?client_application:((client_application:string option) = None) ?on_behalf_of:((on_behalf_of:int32 option) = None) + ?client_user:((client_user:string option) = None) + ?client_sudo_user:((client_sudo_user:string option) = None) () : request_setup_session = { client_pid; client_application; on_behalf_of; + client_user; + client_sudo_user; } let rec default_request_session_of_pid @@ -433,12 +439,16 @@ type request_setup_session_mutable = { mutable client_pid : int32; mutable client_application : string option; mutable on_behalf_of : int32 option; + mutable client_user : string option; + mutable client_sudo_user : string option; } let default_request_setup_session_mutable () : request_setup_session_mutable = { client_pid = 0l; client_application = None; on_behalf_of = None; + client_user = None; + client_sudo_user = None; } type request_session_of_pid_mutable = { @@ -730,6 +740,8 @@ let rec pp_request_setup_session fmt (v:request_setup_session) = Pbrt.Pp.pp_record_field ~first:true "client_pid" Pbrt.Pp.pp_int32 fmt v.client_pid; Pbrt.Pp.pp_record_field ~first:false "client_application" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_application; Pbrt.Pp.pp_record_field ~first:false "on_behalf_of" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.on_behalf_of; + Pbrt.Pp.pp_record_field ~first:false "client_user" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_user; + Pbrt.Pp.pp_record_field ~first:false "client_sudo_user" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_sudo_user; in Pbrt.Pp.pp_brk pp_i fmt () @@ -1008,6 +1020,18 @@ let rec encode_pb_request_setup_session (v:request_setup_session) encoder = Pbrt.Encoder.key 3 Pbrt.Varint encoder; | None -> (); end; + begin match v.client_user with + | Some x -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 4 Pbrt.Bytes encoder; + | None -> (); + end; + begin match v.client_sudo_user with + | Some x -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 5 Pbrt.Bytes encoder; + | None -> (); + end; () let rec encode_pb_request_session_of_pid (v:request_session_of_pid) encoder = @@ -1464,6 +1488,16 @@ let rec decode_pb_request_setup_session d = end | Some (3, pk) -> Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(3)" pk + | Some (4, Pbrt.Bytes) -> begin + v.client_user <- Some (Pbrt.Decoder.string d); + end + | Some (4, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(4)" pk + | Some (5, Pbrt.Bytes) -> begin + v.client_sudo_user <- Some (Pbrt.Decoder.string d); + end + | Some (5, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(5)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; begin if not !client_pid_is_set then Pbrt.Decoder.missing_field "client_pid" end; @@ -1471,6 +1505,8 @@ let rec decode_pb_request_setup_session d = client_pid = v.client_pid; client_application = v.client_application; on_behalf_of = v.on_behalf_of; + client_user = v.client_user; + client_sudo_user = v.client_sudo_user; } : request_setup_session) let rec decode_pb_request_session_of_pid d = diff --git a/src/vyconf_pbt.mli b/src/vyconf_pbt.mli index e2c2245..2755f61 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -21,6 +21,8 @@ type request_setup_session = { client_pid : int32; client_application : string option; on_behalf_of : int32 option; + client_user : string option; + client_sudo_user : string option; } type request_session_of_pid = { @@ -218,6 +220,8 @@ val default_request_setup_session : ?client_pid:int32 -> ?client_application:string option -> ?on_behalf_of:int32 option -> + ?client_user:string option -> + ?client_sudo_user:string option -> unit -> request_setup_session (** [default_request_setup_session ()] is the default value for type [request_setup_session] *) diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 51014c7..0a0d246 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -67,9 +67,18 @@ let make_session_token () = let setup_session world (req: request_setup_session) = let token = make_session_token () in let pid = req.client_pid in - let user = "unknown user" in + let user = + match req.client_user with + | None -> "" + | Some u -> u + in + let sudo_user = + match req.client_sudo_user with + | None -> "" + | Some u -> u + in let client_app = Option.value req.client_application ~default:"unknown client" in - let () = Hashtbl.add sessions token (Session.make world client_app user pid) in + let () = Hashtbl.add sessions token (Session.make world client_app sudo_user user pid) in {response_tmpl with output=(Some token)} let session_of_pid _world (req: request_session_of_pid) = -- cgit v1.2.3 From 4a10cd92e8e5d3f7bf53c1a80c408c68073535c8 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Wed, 10 Sep 2025 14:36:49 -0500 Subject: T7737: provide session pid, user, sudo_user to vyos-commitd Send vyconfd session pid and client env vars to vyos-commitd for use in config mode scripts. --- data/vycall.proto | 14 +++++----- src/commit.ml | 54 +++++++++++++++++++++------------------ src/commit.mli | 7 ++--- src/session.ml | 4 +-- src/session.mli | 2 +- src/vycall_client.ml | 3 +++ src/vycall_pbt.ml | 72 +++++++++++++++++++++++++++++++++++++++++++--------- src/vycall_pbt.mli | 6 +++++ src/vyconfd.ml | 11 ++++++-- 9 files changed, 122 insertions(+), 51 deletions(-) (limited to 'data') diff --git a/data/vycall.proto b/data/vycall.proto index 0037aa7..9517217 100644 --- a/data/vycall.proto +++ b/data/vycall.proto @@ -12,10 +12,12 @@ message Call { message Commit { required string session_id = 1; - required bool dry_run = 4; - required bool atomic = 5; - required bool background = 6; - - optional Status init = 7; - repeated Call calls = 8; + required int32 session_pid = 2; + required string sudo_user = 3; + required string user = 4; + required bool dry_run = 5; + required bool atomic = 6; + required bool background = 7; + optional Status init = 8; + repeated Call calls = 9; } diff --git a/src/commit.ml b/src/commit.ml index 8913ceb..7b04c36 100644 --- a/src/commit.ml +++ b/src/commit.ml @@ -12,10 +12,20 @@ let tree_source_to_yojson = function | ADD -> `String "ADD" type status = { - success : bool; - out : string; + success : bool; + out : string; } [@@deriving to_yojson] +let default_status = { + success = true; + out = ""; +} + +let fail_status msg = + { success = false; + out = msg; + } + type node_data = { script_name: string; priority: int; @@ -39,6 +49,9 @@ let default_node_data = { type commit_data = { session_id: string; + session_pid: int32; + sudo_user: string; + user: string; dry_run: bool; atomic: bool; background: bool; @@ -49,21 +62,6 @@ type commit_data = { result : status; } [@@deriving to_yojson] -let default_commit_data = { - session_id = ""; - dry_run = false; - atomic = false; - background = false; - init = None; - node_list = []; - config_diff = CT.default; - config_result = CT.default; - result = { success = true; out = ""; }; -} - -let fail_status msg = - { success=false; out=msg } - let lex_order c1 c2 = let c = Vyos1x.Util.lex_order c1.path c2.path in match c with @@ -224,25 +222,31 @@ let config_result_update c_data n_data = let commit_update c_data = match c_data.init with | None -> - { default_commit_data with - init=Some (fail_status "commitd failure: no init status provided") + { c_data with + init = Some (fail_status "commitd failure: no init status provided") } | Some _ -> let func acc_data nd = match nd.reply with | None -> - { default_commit_data with - init=Some (fail_status"commitd failure: no reply status provided") + { c_data with + init = Some (fail_status "commitd failure: no reply status provided") } | Some _ -> config_result_update acc_data nd in List.fold_left func c_data c_data.node_list -let make_commit_data ?(dry_run=false) rt at wt id = +let make_commit_data ?(dry_run=false) rt at wt id pid sudo_user user = let diff = CD.diff_tree [] at wt in let del_list, add_list = calculate_priority_lists rt diff in - { default_commit_data with - session_id = id; + { session_id = id; + session_pid = pid; + sudo_user = sudo_user; + user = user; dry_run = dry_run; + atomic = false; + background = false; + init = None; config_diff = diff; config_result = CT.get_subtree diff ["inter"]; - node_list = del_list @ add_list; } + node_list = del_list @ add_list; + result = default_status; } diff --git a/src/commit.mli b/src/commit.mli index 01022ec..ee38768 100644 --- a/src/commit.mli +++ b/src/commit.mli @@ -17,6 +17,9 @@ type node_data = { type commit_data = { session_id: string; + session_pid: int32; + sudo_user: string; + user: string; dry_run: bool; atomic: bool; background: bool; @@ -33,9 +36,7 @@ val tree_source_to_yojson : tree_source -> [> `String of string ] val default_node_data : node_data -val default_commit_data : commit_data - -val make_commit_data : ?dry_run:bool -> Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t -> string -> commit_data +val make_commit_data : ?dry_run:bool -> Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> commit_data val calculate_priority_lists : Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> node_data list * node_data list diff --git a/src/session.ml b/src/session.ml index 23c3d19..5fd20b5 100644 --- a/src/session.ml +++ b/src/session.ml @@ -191,7 +191,7 @@ let save w s file = | Error e -> raise (Session_error (Printf.sprintf "Error saving config: %s" e)) | Ok () -> s -let prepare_commit ?(dry_run=false) w config id = +let prepare_commit ?(dry_run=false) w config id pid sudo_user user = let at = w.running_config in let rt = w.reference_tree in let vc = w.vyconf_config in @@ -207,7 +207,7 @@ let prepare_commit ?(dry_run=false) w config id = with Vyos1x.Internal.Write_error msg -> raise (Session_error msg) in - CC.make_commit_data ~dry_run:dry_run rt at config id + CC.make_commit_data ~dry_run:dry_run rt at config id pid sudo_user user let get_config w s id = let at = w.running_config in diff --git a/src/session.mli b/src/session.mli index 5dbbaf0..fc2acf4 100644 --- a/src/session.mli +++ b/src/session.mli @@ -56,7 +56,7 @@ val list_children : world -> session_data -> string list -> string list val string_of_op : cfg_op -> string -val prepare_commit : ?dry_run:bool -> world -> Vyos1x.Config_tree.t -> string -> Commitd_client.Commit.commit_data +val prepare_commit : ?dry_run:bool -> world -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> Commitd_client.Commit.commit_data val get_config : world -> session_data -> string -> string diff --git a/src/vycall_client.ml b/src/vycall_client.ml index 11bbe3f..515f5df 100644 --- a/src/vycall_client.ml +++ b/src/vycall_client.ml @@ -31,6 +31,9 @@ let call_to_node_data ((c: call), (nd: node_data)) = let commit_data_to_commit_proto cd = { session_id = cd.session_id; + session_pid = cd.session_pid; + sudo_user = cd.sudo_user; + user = cd.user; dry_run = cd.dry_run; atomic = cd.atomic; background = cd.background; diff --git a/src/vycall_pbt.ml b/src/vycall_pbt.ml index 715c453..89d2c67 100644 --- a/src/vycall_pbt.ml +++ b/src/vycall_pbt.ml @@ -14,6 +14,9 @@ type call = { type commit = { session_id : string; + session_pid : int32; + sudo_user : string; + user : string; dry_run : bool; atomic : bool; background : bool; @@ -43,6 +46,9 @@ let rec default_call let rec default_commit ?session_id:((session_id:string) = "") + ?session_pid:((session_pid:int32) = 0l) + ?sudo_user:((sudo_user:string) = "") + ?user:((user:string) = "") ?dry_run:((dry_run:bool) = false) ?atomic:((atomic:bool) = false) ?background:((background:bool) = false) @@ -50,6 +56,9 @@ let rec default_commit ?calls:((calls:call list) = []) () : commit = { session_id; + session_pid; + sudo_user; + user; dry_run; atomic; background; @@ -83,6 +92,9 @@ let default_call_mutable () : call_mutable = { type commit_mutable = { mutable session_id : string; + mutable session_pid : int32; + mutable sudo_user : string; + mutable user : string; mutable dry_run : bool; mutable atomic : bool; mutable background : bool; @@ -92,6 +104,9 @@ type commit_mutable = { let default_commit_mutable () : commit_mutable = { session_id = ""; + session_pid = 0l; + sudo_user = ""; + user = ""; dry_run = false; atomic = false; background = false; @@ -122,6 +137,9 @@ let rec pp_call fmt (v:call) = let rec pp_commit fmt (v:commit) = let pp_i fmt () = Pbrt.Pp.pp_record_field ~first:true "session_id" Pbrt.Pp.pp_string fmt v.session_id; + Pbrt.Pp.pp_record_field ~first:false "session_pid" Pbrt.Pp.pp_int32 fmt v.session_pid; + Pbrt.Pp.pp_record_field ~first:false "sudo_user" Pbrt.Pp.pp_string fmt v.sudo_user; + Pbrt.Pp.pp_record_field ~first:false "user" Pbrt.Pp.pp_string fmt v.user; Pbrt.Pp.pp_record_field ~first:false "dry_run" Pbrt.Pp.pp_bool fmt v.dry_run; Pbrt.Pp.pp_record_field ~first:false "atomic" Pbrt.Pp.pp_bool fmt v.atomic; Pbrt.Pp.pp_record_field ~first:false "background" Pbrt.Pp.pp_bool fmt v.background; @@ -167,21 +185,27 @@ let rec encode_pb_call (v:call) encoder = let rec encode_pb_commit (v:commit) encoder = Pbrt.Encoder.string v.session_id encoder; Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + Pbrt.Encoder.int32_as_varint v.session_pid encoder; + Pbrt.Encoder.key 2 Pbrt.Varint encoder; + Pbrt.Encoder.string v.sudo_user encoder; + Pbrt.Encoder.key 3 Pbrt.Bytes encoder; + Pbrt.Encoder.string v.user encoder; + Pbrt.Encoder.key 4 Pbrt.Bytes encoder; Pbrt.Encoder.bool v.dry_run encoder; - Pbrt.Encoder.key 4 Pbrt.Varint encoder; - Pbrt.Encoder.bool v.atomic encoder; Pbrt.Encoder.key 5 Pbrt.Varint encoder; - Pbrt.Encoder.bool v.background encoder; + Pbrt.Encoder.bool v.atomic encoder; Pbrt.Encoder.key 6 Pbrt.Varint encoder; + Pbrt.Encoder.bool v.background encoder; + Pbrt.Encoder.key 7 Pbrt.Varint encoder; begin match v.init with | Some x -> Pbrt.Encoder.nested encode_pb_status x encoder; - Pbrt.Encoder.key 7 Pbrt.Bytes encoder; + Pbrt.Encoder.key 8 Pbrt.Bytes encoder; | None -> (); end; Pbrt.List_util.rev_iter_with (fun x encoder -> Pbrt.Encoder.nested encode_pb_call x encoder; - Pbrt.Encoder.key 8 Pbrt.Bytes encoder; + Pbrt.Encoder.key 9 Pbrt.Bytes encoder; ) v.calls encoder; () @@ -261,6 +285,9 @@ let rec decode_pb_commit d = let background_is_set = ref false in let atomic_is_set = ref false in let dry_run_is_set = ref false in + let user_is_set = ref false in + let sudo_user_is_set = ref false in + let session_pid_is_set = ref false in let session_id_is_set = ref false in while !continue__ do match Pbrt.Decoder.key d with @@ -272,39 +299,60 @@ let rec decode_pb_commit d = end | Some (1, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(1)" pk - | Some (4, Pbrt.Varint) -> begin - v.dry_run <- Pbrt.Decoder.bool d; dry_run_is_set := true; + | Some (2, Pbrt.Varint) -> begin + v.session_pid <- Pbrt.Decoder.int32_as_varint d; session_pid_is_set := true; + end + | Some (2, pk) -> + Pbrt.Decoder.unexpected_payload "Message(commit), field(2)" pk + | Some (3, Pbrt.Bytes) -> begin + v.sudo_user <- Pbrt.Decoder.string d; sudo_user_is_set := true; + end + | Some (3, pk) -> + Pbrt.Decoder.unexpected_payload "Message(commit), field(3)" pk + | Some (4, Pbrt.Bytes) -> begin + v.user <- Pbrt.Decoder.string d; user_is_set := true; end | Some (4, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(4)" pk | Some (5, Pbrt.Varint) -> begin - v.atomic <- Pbrt.Decoder.bool d; atomic_is_set := true; + v.dry_run <- Pbrt.Decoder.bool d; dry_run_is_set := true; end | Some (5, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(5)" pk | Some (6, Pbrt.Varint) -> begin - v.background <- Pbrt.Decoder.bool d; background_is_set := true; + v.atomic <- Pbrt.Decoder.bool d; atomic_is_set := true; end | Some (6, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(6)" pk - | Some (7, Pbrt.Bytes) -> begin - v.init <- Some (decode_pb_status (Pbrt.Decoder.nested d)); + | Some (7, Pbrt.Varint) -> begin + v.background <- Pbrt.Decoder.bool d; background_is_set := true; end | Some (7, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(7)" pk | Some (8, Pbrt.Bytes) -> begin - v.calls <- (decode_pb_call (Pbrt.Decoder.nested d)) :: v.calls; + v.init <- Some (decode_pb_status (Pbrt.Decoder.nested d)); end | Some (8, pk) -> Pbrt.Decoder.unexpected_payload "Message(commit), field(8)" pk + | Some (9, Pbrt.Bytes) -> begin + v.calls <- (decode_pb_call (Pbrt.Decoder.nested d)) :: v.calls; + end + | Some (9, pk) -> + Pbrt.Decoder.unexpected_payload "Message(commit), field(9)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; begin if not !background_is_set then Pbrt.Decoder.missing_field "background" end; begin if not !atomic_is_set then Pbrt.Decoder.missing_field "atomic" end; begin if not !dry_run_is_set then Pbrt.Decoder.missing_field "dry_run" end; + begin if not !user_is_set then Pbrt.Decoder.missing_field "user" end; + begin if not !sudo_user_is_set then Pbrt.Decoder.missing_field "sudo_user" end; + begin if not !session_pid_is_set then Pbrt.Decoder.missing_field "session_pid" end; begin if not !session_id_is_set then Pbrt.Decoder.missing_field "session_id" end; ({ session_id = v.session_id; + session_pid = v.session_pid; + sudo_user = v.sudo_user; + user = v.user; dry_run = v.dry_run; atomic = v.atomic; background = v.background; diff --git a/src/vycall_pbt.mli b/src/vycall_pbt.mli index f389302..fd39a0c 100644 --- a/src/vycall_pbt.mli +++ b/src/vycall_pbt.mli @@ -21,6 +21,9 @@ type call = { type commit = { session_id : string; + session_pid : int32; + sudo_user : string; + user : string; dry_run : bool; atomic : bool; background : bool; @@ -49,6 +52,9 @@ val default_call : val default_commit : ?session_id:string -> + ?session_pid:int32 -> + ?sudo_user:string -> + ?user:string -> ?dry_run:bool -> ?atomic:bool -> ?background:bool -> diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 0a0d246..707ce4b 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -245,8 +245,15 @@ let commit world token (req: request_commit) = let s = find_session token in let proposed_config = Session.get_proposed_config world s in let req_dry_run = Option.value req.dry_run ~default:false in - - let commit_data = Session.prepare_commit ~dry_run:req_dry_run world proposed_config token + let commit_data = + Session.prepare_commit + ~dry_run:req_dry_run + world + proposed_config + token + s.client_pid + s.client_sudo_user + s.client_user in let%lwt received_commit_data = VC.do_commit commit_data in let%lwt result_commit_data = -- cgit v1.2.3 From 6577d7ac1b10557b5087bc959dad3c21971a539b Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Wed, 10 Sep 2025 15:45:56 -0500 Subject: T7737: add requests to provide auxiliary set/delete operations on config Occasionally, it is useful to update the config tree _during a commit_ with non-actionable data (meaning data not required for the actions of currently invoked config_mode scripts): the classic example is that of removing the entries of plaintext passwords and adding the encrypted entry. Add the relevent requests and session record field. --- data/vyconf.proto | 14 +++++ src/session.ml | 60 ++++++++++++++++++ src/session.mli | 13 ++++ src/vyconf_pbt.ml | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vyconf_pbt.mli | 48 ++++++++++++++ src/vyconfd.ml | 33 +++++++++- 6 files changed, 347 insertions(+), 1 deletion(-) (limited to 'data') diff --git a/data/vyconf.proto b/data/vyconf.proto index 5323856..0cd2883 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -49,6 +49,18 @@ message Request { repeated string path = 1; } + message AuxSet { + repeated string path = 1; + required string script_name = 2; + optional string tag_value = 3; + } + + message AuxDelete { + repeated string path = 1; + required string script_name = 2; + optional string tag_value = 3; + } + message Discard { optional int32 dummy = 1; } @@ -179,6 +191,8 @@ message Request { SessionOfPid session_of_pid = 27; SessionExists session_exists = 28; GetConfig get_config = 29; + AuxSet aux_set = 30; + AuxDelete aux_delete = 31; } } diff --git a/src/session.ml b/src/session.ml index 5fd20b5..4829d76 100644 --- a/src/session.ml +++ b/src/session.ml @@ -3,6 +3,7 @@ module IC = Vyos1x.Internal.Make(CT) module CC = Commitd_client.Commit module CD = Vyos1x.Config_diff module VT = Vyos1x.Vytree +module VL = Vyos1x.Vylist module RT = Vyos1x.Reference_tree module D = Directories module FP = FilePath @@ -12,6 +13,7 @@ exception Session_error of string type cfg_op = | CfgSet of string list * string option * CT.value_behaviour | CfgDelete of string list * string option + [@@deriving yojson] type world = { mutable running_config: CT.t; @@ -20,11 +22,19 @@ type world = { dirs: Directories.t } +type aux_op = { + script_name: string; + tag_value: string option; + changeset: cfg_op list; +} [@@deriving yojson] + + type session_data = { proposed_config : CT.t; modified: bool; conf_mode: bool; changeset: cfg_op list; + mutable aux_changeset: aux_op list; client_app: string; client_pid: int32; client_user: string; @@ -36,6 +46,7 @@ let make world client_app sudo_user user pid = { modified = false; conf_mode = false; changeset = []; + aux_changeset = []; client_app = client_app; client_user = user; client_sudo_user = sudo_user; @@ -55,6 +66,10 @@ let string_of_op op = | None -> Printf.sprintf "delete %s" path_str | Some v -> Printf.sprintf "delete %s \"%s\"" path_str v) +let sprint_changeset ss = + let ss = List.map (fun x -> aux_op_to_yojson x) ss in + Yojson.Safe.to_string (`List ss) + let set_modified s = if s.modified = true then s else {s with modified = true} @@ -144,6 +159,51 @@ let delete w s path = let changeset' = update_delete w s.changeset path in { s with changeset = changeset' } +let aux_set w s path name tagval = + let _ = validate w s path in + let aux = s.aux_changeset in + let ident y = + if (y.script_name <> name || y.tag_value <> tagval) then false + else true + in + let op' = VL.find ident aux in + let changeset' = + match op' with + | None -> + update_set w [] path + | Some o -> + update_set w o.changeset path + in + let op = + { script_name = name; tag_value = tagval; changeset = changeset' } + in + let aux_changeset' = + VL.replace ~force:true ident op aux + in + s.aux_changeset <- aux_changeset' + +let aux_delete w s path name tagval = + let aux = s.aux_changeset in + let ident y = + if (y.script_name <> name || y.tag_value <> tagval) then false + else true + in + let op' = VL.find ident aux in + let changeset' = + match op' with + | None -> + update_delete w [] path + | Some o -> + update_delete w o.changeset path + in + let op = + { script_name = name; tag_value = tagval; changeset = changeset' } + in + let aux_changeset' = + VL.replace ~force:true ident op aux + in + s.aux_changeset <- aux_changeset' + let discard _w s = { s with changeset = []; } diff --git a/src/session.mli b/src/session.mli index fc2acf4..96fa4d1 100644 --- a/src/session.mli +++ b/src/session.mli @@ -9,11 +9,18 @@ type world = { dirs: Directories.t } +type aux_op = { + script_name: string; + tag_value: string option; + changeset: cfg_op list; +} [@@deriving yojson] + type session_data = { proposed_config : Vyos1x.Config_tree.t; modified: bool; conf_mode: bool; changeset: cfg_op list; + mutable aux_changeset: aux_op list; client_app: string; client_pid: int32; client_user: string; @@ -22,6 +29,8 @@ type session_data = { exception Session_error of string +val sprint_changeset : aux_op list -> string + val make : world -> string -> string -> string -> int32 -> session_data val set_modified : session_data -> session_data @@ -34,6 +43,10 @@ val set : world -> session_data -> string list -> session_data val delete : world -> session_data -> string list -> session_data +val aux_set : world -> session_data -> string list -> string -> string option -> unit + +val aux_delete : world -> session_data -> string list -> string -> string option -> unit + val get_proposed_config : world -> session_data -> Vyos1x.Config_tree.t val discard : world -> session_data -> session_data diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index a89f9a8..1fbbf75 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -47,6 +47,18 @@ type request_delete = { path : string list; } +type request_aux_set = { + path : string list; + script_name : string; + tag_value : string option; +} + +type request_aux_delete = { + path : string list; + script_name : string; + tag_value : string option; +} + type request_discard = { dummy : int32 option; } @@ -172,6 +184,8 @@ type request = | Session_of_pid of request_session_of_pid | Session_exists of request_session_exists | Get_config of request_get_config + | Aux_set of request_aux_set + | Aux_delete of request_aux_delete type request_envelope = { token : string option; @@ -261,6 +275,26 @@ let rec default_request_delete path; } +let rec default_request_aux_set + ?path:((path:string list) = []) + ?script_name:((script_name:string) = "") + ?tag_value:((tag_value:string option) = None) + () : request_aux_set = { + path; + script_name; + tag_value; +} + +let rec default_request_aux_delete + ?path:((path:string list) = []) + ?script_name:((script_name:string) = "") + ?tag_value:((tag_value:string option) = None) + () : request_aux_delete = { + path; + script_name; + tag_value; +} + let rec default_request_discard ?dummy:((dummy:int32 option) = None) () : request_discard = { @@ -509,6 +543,30 @@ let default_request_delete_mutable () : request_delete_mutable = { path = []; } +type request_aux_set_mutable = { + mutable path : string list; + mutable script_name : string; + mutable tag_value : string option; +} + +let default_request_aux_set_mutable () : request_aux_set_mutable = { + path = []; + script_name = ""; + tag_value = None; +} + +type request_aux_delete_mutable = { + mutable path : string list; + mutable script_name : string; + mutable tag_value : string option; +} + +let default_request_aux_delete_mutable () : request_aux_delete_mutable = { + path = []; + script_name = ""; + tag_value = None; +} + type request_discard_mutable = { mutable dummy : int32 option; } @@ -788,6 +846,22 @@ let rec pp_request_delete fmt (v:request_delete) = in Pbrt.Pp.pp_brk pp_i fmt () +let rec pp_request_aux_set fmt (v:request_aux_set) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "path" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.path; + Pbrt.Pp.pp_record_field ~first:false "script_name" Pbrt.Pp.pp_string fmt v.script_name; + Pbrt.Pp.pp_record_field ~first:false "tag_value" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.tag_value; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_request_aux_delete fmt (v:request_aux_delete) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "path" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.path; + Pbrt.Pp.pp_record_field ~first:false "script_name" Pbrt.Pp.pp_string fmt v.script_name; + Pbrt.Pp.pp_record_field ~first:false "tag_value" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.tag_value; + in + Pbrt.Pp.pp_brk pp_i fmt () + let rec pp_request_discard fmt (v:request_discard) = let pp_i fmt () = Pbrt.Pp.pp_record_field ~first:true "dummy" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.dummy; @@ -958,6 +1032,8 @@ let rec pp_request fmt (v:request) = | Session_of_pid x -> Format.fprintf fmt "@[Session_of_pid(@,%a)@]" pp_request_session_of_pid x | Session_exists x -> Format.fprintf fmt "@[Session_exists(@,%a)@]" pp_request_session_exists x | Get_config x -> Format.fprintf fmt "@[Get_config(@,%a)@]" pp_request_get_config x + | Aux_set x -> Format.fprintf fmt "@[Aux_set(@,%a)@]" pp_request_aux_set x + | Aux_delete x -> Format.fprintf fmt "@[Aux_delete(@,%a)@]" pp_request_aux_delete x let rec pp_request_envelope fmt (v:request_envelope) = let pp_i fmt () = @@ -1093,6 +1169,36 @@ let rec encode_pb_request_delete (v:request_delete) encoder = ) v.path encoder; () +let rec encode_pb_request_aux_set (v:request_aux_set) encoder = + Pbrt.List_util.rev_iter_with (fun x encoder -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + ) v.path encoder; + Pbrt.Encoder.string v.script_name encoder; + Pbrt.Encoder.key 2 Pbrt.Bytes encoder; + begin match v.tag_value with + | Some x -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 3 Pbrt.Bytes encoder; + | None -> (); + end; + () + +let rec encode_pb_request_aux_delete (v:request_aux_delete) encoder = + Pbrt.List_util.rev_iter_with (fun x encoder -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + ) v.path encoder; + Pbrt.Encoder.string v.script_name encoder; + Pbrt.Encoder.key 2 Pbrt.Bytes encoder; + begin match v.tag_value with + | Some x -> + Pbrt.Encoder.string x encoder; + Pbrt.Encoder.key 3 Pbrt.Bytes encoder; + | None -> (); + end; + () + let rec encode_pb_request_discard (v:request_discard) encoder = begin match v.dummy with | Some x -> @@ -1394,6 +1500,12 @@ let rec encode_pb_request (v:request) encoder = | Get_config x -> Pbrt.Encoder.nested encode_pb_request_get_config x encoder; Pbrt.Encoder.key 29 Pbrt.Bytes encoder; + | Aux_set x -> + Pbrt.Encoder.nested encode_pb_request_aux_set x encoder; + Pbrt.Encoder.key 30 Pbrt.Bytes encoder; + | Aux_delete x -> + Pbrt.Encoder.nested encode_pb_request_aux_delete x encoder; + Pbrt.Encoder.key 31 Pbrt.Bytes encoder; end let rec encode_pb_request_envelope (v:request_envelope) encoder = @@ -1646,6 +1758,72 @@ let rec decode_pb_request_delete d = path = v.path; } : request_delete) +let rec decode_pb_request_aux_set d = + let v = default_request_aux_set_mutable () in + let continue__= ref true in + let script_name_is_set = ref false in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + v.path <- List.rev v.path; + ); continue__ := false + | Some (1, Pbrt.Bytes) -> begin + v.path <- (Pbrt.Decoder.string d) :: v.path; + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(1)" pk + | Some (2, Pbrt.Bytes) -> begin + v.script_name <- Pbrt.Decoder.string d; script_name_is_set := true; + end + | Some (2, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(2)" pk + | Some (3, Pbrt.Bytes) -> begin + v.tag_value <- Some (Pbrt.Decoder.string d); + end + | Some (3, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(3)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + begin if not !script_name_is_set then Pbrt.Decoder.missing_field "script_name" end; + ({ + path = v.path; + script_name = v.script_name; + tag_value = v.tag_value; + } : request_aux_set) + +let rec decode_pb_request_aux_delete d = + let v = default_request_aux_delete_mutable () in + let continue__= ref true in + let script_name_is_set = ref false in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + v.path <- List.rev v.path; + ); continue__ := false + | Some (1, Pbrt.Bytes) -> begin + v.path <- (Pbrt.Decoder.string d) :: v.path; + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(1)" pk + | Some (2, Pbrt.Bytes) -> begin + v.script_name <- Pbrt.Decoder.string d; script_name_is_set := true; + end + | Some (2, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(2)" pk + | Some (3, Pbrt.Bytes) -> begin + v.tag_value <- Some (Pbrt.Decoder.string d); + end + | Some (3, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(3)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + begin if not !script_name_is_set then Pbrt.Decoder.missing_field "script_name" end; + ({ + path = v.path; + script_name = v.script_name; + tag_value = v.tag_value; + } : request_aux_delete) + let rec decode_pb_request_discard d = let v = default_request_discard_mutable () in let continue__= ref true in @@ -2173,6 +2351,8 @@ let rec decode_pb_request d = | Some (27, _) -> (Session_of_pid (decode_pb_request_session_of_pid (Pbrt.Decoder.nested d)) : request) | Some (28, _) -> (Session_exists (decode_pb_request_session_exists (Pbrt.Decoder.nested d)) : request) | Some (29, _) -> (Get_config (decode_pb_request_get_config (Pbrt.Decoder.nested d)) : request) + | Some (30, _) -> (Aux_set (decode_pb_request_aux_set (Pbrt.Decoder.nested d)) : request) + | Some (31, _) -> (Aux_delete (decode_pb_request_aux_delete (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 2755f61..d63962e 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -54,6 +54,18 @@ type request_delete = { path : string list; } +type request_aux_set = { + path : string list; + script_name : string; + tag_value : string option; +} + +type request_aux_delete = { + path : string list; + script_name : string; + tag_value : string option; +} + type request_discard = { dummy : int32 option; } @@ -179,6 +191,8 @@ type request = | Session_of_pid of request_session_of_pid | Session_exists of request_session_exists | Get_config of request_get_config + | Aux_set of request_aux_set + | Aux_delete of request_aux_delete type request_envelope = { token : string option; @@ -269,6 +283,22 @@ val default_request_delete : request_delete (** [default_request_delete ()] is the default value for type [request_delete] *) +val default_request_aux_set : + ?path:string list -> + ?script_name:string -> + ?tag_value:string option -> + unit -> + request_aux_set +(** [default_request_aux_set ()] is the default value for type [request_aux_set] *) + +val default_request_aux_delete : + ?path:string list -> + ?script_name:string -> + ?tag_value:string option -> + unit -> + request_aux_delete +(** [default_request_aux_delete ()] is the default value for type [request_aux_delete] *) + val default_request_discard : ?dummy:int32 option -> unit -> @@ -460,6 +490,12 @@ val pp_request_set : Format.formatter -> request_set -> unit val pp_request_delete : Format.formatter -> request_delete -> unit (** [pp_request_delete v] formats v *) +val pp_request_aux_set : Format.formatter -> request_aux_set -> unit +(** [pp_request_aux_set v] formats v *) + +val pp_request_aux_delete : Format.formatter -> request_aux_delete -> unit +(** [pp_request_aux_delete v] formats v *) + val pp_request_discard : Format.formatter -> request_discard -> unit (** [pp_request_discard v] formats v *) @@ -568,6 +604,12 @@ val encode_pb_request_set : request_set -> Pbrt.Encoder.t -> unit val encode_pb_request_delete : request_delete -> Pbrt.Encoder.t -> unit (** [encode_pb_request_delete v encoder] encodes [v] with the given [encoder] *) +val encode_pb_request_aux_set : request_aux_set -> Pbrt.Encoder.t -> unit +(** [encode_pb_request_aux_set v encoder] encodes [v] with the given [encoder] *) + +val encode_pb_request_aux_delete : request_aux_delete -> Pbrt.Encoder.t -> unit +(** [encode_pb_request_aux_delete v encoder] encodes [v] with the given [encoder] *) + val encode_pb_request_discard : request_discard -> Pbrt.Encoder.t -> unit (** [encode_pb_request_discard v encoder] encodes [v] with the given [encoder] *) @@ -676,6 +718,12 @@ val decode_pb_request_set : Pbrt.Decoder.t -> request_set val decode_pb_request_delete : Pbrt.Decoder.t -> request_delete (** [decode_pb_request_delete decoder] decodes a [request_delete] binary value from [decoder] *) +val decode_pb_request_aux_set : Pbrt.Decoder.t -> request_aux_set +(** [decode_pb_request_aux_set decoder] decodes a [request_aux_set] binary value from [decoder] *) + +val decode_pb_request_aux_delete : Pbrt.Decoder.t -> request_aux_delete +(** [decode_pb_request_aux_delete decoder] decodes a [request_aux_delete] binary value from [decoder] *) + val decode_pb_request_discard : Pbrt.Decoder.t -> request_discard (** [decode_pb_request_discard decoder] decodes a [request_discard] binary value from [decoder] *) diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 707ce4b..9e8c57e 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -210,6 +210,34 @@ let delete world token (req: request_delete) = response_tmpl with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} +let aux_set world token (req: request_aux_set) = + try + let () = (Lwt_log.debug @@ Printf.sprintf "[%s]\n" (Vyos1x.Util.string_of_list req.path)) |> Lwt.ignore_result in + let () = + Session.aux_set + world + (find_session token) + req.path + req.script_name + req.tag_value + in + response_tmpl + with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} + +let aux_delete world token (req: request_aux_delete) = + try + let () = (Lwt_log.debug @@ Printf.sprintf "[%s]\n" (Vyos1x.Util.string_of_list req.path)) |> Lwt.ignore_result in + let () = + Session.aux_delete + world + (find_session token) + req.path + req.script_name + req.tag_value + in + response_tmpl + with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} + let discard world token (_req: request_discard) = try let session = Session.discard world (find_session token) @@ -279,7 +307,8 @@ let commit world token (req: request_commit) = Session.get_changeset world world.Session.running_config - proposed_config } + proposed_config; + aux_changeset = []; } in Hashtbl.replace sessions token session; let success, msg_str = @@ -342,6 +371,8 @@ let rec handle_connection world ic oc () = | Some t, Validate r -> validate world t r | Some t, Set r -> set world t r | Some t, Delete r -> delete world t r + | Some t, Aux_set r -> aux_set world t r + | Some t, Aux_delete r -> aux_delete world t r | Some t, Discard r -> discard world t r | Some t, Session_changed r -> session_changed world t r | Some t, Get_config r -> get_config world t r -- cgit v1.2.3