summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/session.ml28
-rw-r--r--src/session.mli4
-rw-r--r--src/vyconf_cli.ml19
-rw-r--r--src/vyconf_pbt.ml40
-rw-r--r--src/vyconf_pbt.mli4
-rw-r--r--src/vyconfd.ml11
6 files changed, 97 insertions, 9 deletions
diff --git a/src/session.ml b/src/session.ml
index 9ce2807..1ff9bae 100644
--- a/src/session.ml
+++ b/src/session.ml
@@ -104,8 +104,12 @@ let set w s path =
apply_cfg_op op s.proposed_config |>
(fun c -> RT.set_tag_data w.reference_tree c path) |>
(fun c -> RT.set_leaf_data w.reference_tree c path)
- with CT.Useless_set ->
+ with
+ | CT.Useless_set ->
raise (Session_error (Printf.sprintf "Useless set, path: %s" (string_of_op op)))
+ | CT.Duplicate_value ->
+ raise (Session_error (Printf.sprintf "Duplicate value, path: %s" (string_of_op op)))
+
in
{s with proposed_config=config; changeset=(op :: s.changeset)}
@@ -127,13 +131,31 @@ let session_changed w s =
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
+let load w s file cached =
+ let ct =
+ if cached then
+ try
+ Ok (IC.read_internal file)
+ with Vyos1x.Internal.Read_error e ->
+ Error e
+ else
+ Vyos1x.Config_file.load_config file
+ in
match ct with
| Error e -> raise (Session_error (Printf.sprintf "Error loading config: %s" e))
| 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 8e5805d..1a9b79f 100644
--- a/src/session.mli
+++ b/src/session.mli
@@ -37,7 +37,9 @@ val discard : world -> session_data -> session_data
val session_changed : world -> session_data -> bool
-val load : world -> session_data -> string -> session_data
+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
diff --git a/src/vyconf_cli.ml b/src/vyconf_cli.ml
index ded03df..0d1535e 100644
--- a/src/vyconf_cli.ml
+++ b/src/vyconf_cli.ml
@@ -29,6 +29,14 @@ let output_format_of_string s =
| "json" -> Out_json
| _ -> failwith (Printf.sprintf "Unknown output format %s, should be plain or json" s)
+let in_cli_config_session () =
+ let env = Unix.environment () in
+ let res = Array.find_opt (fun c -> String.starts_with ~prefix:"_OFR_CONFIGURE" c) env
+ in
+ match res with
+ | Some _ -> true
+ | None -> false
+
let get_session () =
let pid = Int32.of_int (Unix.getppid()) in
let socket = "/var/run/vyconfd.sock" in
@@ -42,6 +50,13 @@ let get_session () =
| Error _ -> setup_session client "vyconf_cli" pid
| _ as c -> c |> Lwt.return
+let close_session () =
+ let%lwt client = get_session () in
+ match client with
+ | Ok c ->
+ teardown_session c
+ | Error e -> Error e |> Lwt.return
+
let main op path =
let%lwt client = get_session () in
let%lwt result =
@@ -57,6 +72,10 @@ let main op path =
end
| Error e -> Error e |> Lwt.return
in
+ let () =
+ if not (in_cli_config_session ()) then
+ close_session () |> Lwt.ignore_result
+ in
match result with
| Ok s -> let%lwt () = Lwt_io.write Lwt_io.stdout s in Lwt.return 0
| Error e -> let%lwt () = Lwt_io.write Lwt_io.stderr (Printf.sprintf "%s\n" e) in Lwt.return 1
diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml
index 0afa0bd..913fcea 100644
--- a/src/vyconf_pbt.ml
+++ b/src/vyconf_pbt.ml
@@ -83,11 +83,13 @@ type request_rollback = {
type request_load = {
location : string;
+ cached : bool;
format : request_config_format option;
}
type request_merge = {
location : string;
+ destructive : bool;
format : request_config_format option;
}
@@ -313,17 +315,21 @@ let rec default_request_rollback
let rec default_request_load
?location:((location:string) = "")
+ ?cached:((cached:bool) = false)
?format:((format:request_config_format option) = None)
() : request_load = {
location;
+ cached;
format;
}
let rec default_request_merge
?location:((location:string) = "")
+ ?destructive:((destructive:bool) = false)
?format:((format:request_config_format option) = None)
() : request_merge = {
location;
+ destructive;
format;
}
@@ -567,21 +573,25 @@ let default_request_rollback_mutable () : request_rollback_mutable = {
type request_load_mutable = {
mutable location : string;
+ mutable cached : bool;
mutable format : request_config_format option;
}
let default_request_load_mutable () : request_load_mutable = {
location = "";
+ cached = false;
format = None;
}
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;
}
@@ -819,6 +829,7 @@ let rec pp_request_rollback fmt (v:request_rollback) =
let rec pp_request_load fmt (v:request_load) =
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 "cached" Pbrt.Pp.pp_bool fmt v.cached;
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 ()
@@ -826,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 ()
@@ -1137,10 +1149,12 @@ let rec encode_pb_request_rollback (v:request_rollback) encoder =
let rec encode_pb_request_load (v:request_load) encoder =
Pbrt.Encoder.string v.location encoder;
Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
+ Pbrt.Encoder.bool v.cached 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;
()
@@ -1148,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;
()
@@ -1784,6 +1800,7 @@ let rec decode_pb_request_rollback d =
let rec decode_pb_request_load d =
let v = default_request_load_mutable () in
let continue__= ref true in
+ let cached_is_set = ref false in
let location_is_set = ref false in
while !continue__ do
match Pbrt.Decoder.key d with
@@ -1795,21 +1812,29 @@ let rec decode_pb_request_load d =
| Some (1, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_load), field(1)" pk
| Some (2, Pbrt.Varint) -> begin
- v.format <- Some (decode_pb_request_config_format d);
+ v.cached <- Pbrt.Decoder.bool d; cached_is_set := true;
end
| Some (2, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_load), 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_load), field(3)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
+ begin if not !cached_is_set then Pbrt.Decoder.missing_field "cached" end;
begin if not !location_is_set then Pbrt.Decoder.missing_field "location" end;
({
location = v.location;
+ cached = v.cached;
format = v.format;
} : request_load)
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
@@ -1821,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 d9eb8ef..c9a7530 100644
--- a/src/vyconf_pbt.mli
+++ b/src/vyconf_pbt.mli
@@ -90,11 +90,13 @@ type request_rollback = {
type request_load = {
location : string;
+ cached : bool;
format : request_config_format option;
}
type request_merge = {
location : string;
+ destructive : bool;
format : request_config_format option;
}
@@ -315,6 +317,7 @@ val default_request_rollback :
val default_request_load :
?location:string ->
+ ?cached:bool ->
?format:request_config_format option ->
unit ->
request_load
@@ -322,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 0b92fd1..a0be019 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -217,7 +217,15 @@ let discard world token (_req: request_discard) =
let load world token (req: request_load) =
try
- let session = Session.load world (find_session token) req.location
+ let session = Session.load world (find_session token) req.location req.cached
+ in
+ Hashtbl.replace sessions token session;
+ 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
@@ -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