summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/vyconf.proto10
-rw-r--r--src/session.ml16
-rw-r--r--src/session.mli2
-rw-r--r--src/vycli.ml3
-rw-r--r--src/vyconf_client.ml7
-rw-r--r--src/vyconf_client.mli2
-rw-r--r--src/vyconf_pbt.ml78
-rw-r--r--src/vyconf_pbt.mli22
-rw-r--r--src/vyconfd.ml8
9 files changed, 140 insertions, 8 deletions
diff --git a/data/vyconf.proto b/data/vyconf.proto
index 6bd2796..f2245aa 100644
--- a/data/vyconf.proto
+++ b/data/vyconf.proto
@@ -17,6 +17,11 @@ message Request {
optional int32 OnBehalfOf = 2;
}
+ message Validate {
+ repeated string Path = 1;
+ optional OutputFormat output_format = 2;
+ }
+
message Set {
repeated string Path = 1;
optional bool Ephemeral = 3;
@@ -129,8 +134,9 @@ message Request {
Confirm confirm = 18;
EnterConfigurationMode configure = 19;
ExitConfigurationMode exit_configure = 20;
- string teardown = 21;
- }
+ Validate validate = 21;
+ string teardown = 22;
+ }
}
message RequestEnvelope {
diff --git a/src/session.ml b/src/session.ml
index db3b039..a8eccad 100644
--- a/src/session.ml
+++ b/src/session.ml
@@ -64,9 +64,17 @@ let rec apply_changes changeset config =
| [] -> config
| c :: cs -> apply_changes cs (apply_cfg_op c config)
+let validate w _s path =
+ try
+ RT.validate_path D.(w.dirs.validators) w.reference_tree path
+ with RT.Validation_error x -> raise (Session_error x)
+
+let split_path w _s path =
+ RT.split_path w.reference_tree path
+
let set w s path =
- let path, value = RT.validate_path D.(w.dirs.validators)
- w.reference_tree path in
+ let _ = validate w s path in
+ let path, value = split_path w s path in
let refpath = RT.refpath w.reference_tree path in
let value_behaviour = if RT.is_multi w.reference_tree refpath then CT.AddValue else CT.ReplaceValue in
let op = CfgSet (path, value, value_behaviour) in
@@ -74,8 +82,8 @@ let set w s path =
{s with proposed_config=config; changeset=(op :: s.changeset)}
let delete w s path =
- let path, value = RT.validate_path D.(w.dirs.validators)
- w.reference_tree path in
+ let _ = validate w s path in
+ let path, value = split_path w s path in
let op = CfgDelete (path, value) in
let config = apply_cfg_op op s.proposed_config in
{s with proposed_config=config; changeset=(op :: s.changeset)}
diff --git a/src/session.mli b/src/session.mli
index 8d10707..16d8e35 100644
--- a/src/session.mli
+++ b/src/session.mli
@@ -26,6 +26,8 @@ val set_modified : session_data -> session_data
val apply_changes : cfg_op list -> Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t
+val validate : world -> session_data -> string list -> unit
+
val set : world -> session_data -> string list -> session_data
val delete : world -> session_data -> string list -> session_data
diff --git a/src/vycli.ml b/src/vycli.ml
index 4310cbd..83c5eb1 100644
--- a/src/vycli.ml
+++ b/src/vycli.ml
@@ -10,6 +10,7 @@ type op_t =
| OpGetValue
| OpGetValues
| OpListChildren
+ | OpValidate
let token : string option ref = ref None
let conf_format_opt = ref "curly"
@@ -34,6 +35,7 @@ let args = [
("--list-children", Arg.Unit (fun () -> op := Some OpListChildren), "List children of the node at the specified path");
("--show-config", Arg.Unit (fun () -> op := Some OpShowConfig), "Show the configuration at the specified path");
("--status", Arg.Unit (fun () -> op := Some OpStatus), "Send a status/keepalive message");
+ ("--validate", Arg.Unit (fun () -> op := Some OpValidate), "Validate path");
]
let config_format_of_string s =
@@ -74,6 +76,7 @@ let main socket op path out_format config_format =
| OpGetValues -> get_values client path
| OpListChildren -> list_children client path
| OpShowConfig -> show_config client path
+ | OpValidate -> validate client path
| _ -> Error "Unimplemented" |> Lwt.return
end
in match result with
diff --git a/src/vyconf_client.ml b/src/vyconf_client.ml
index f6ce448..5cbd798 100644
--- a/src/vyconf_client.ml
+++ b/src/vyconf_client.ml
@@ -101,3 +101,10 @@ let show_config client path =
| Success -> unwrap resp.output |> Lwt.return
| _ -> Error (Option.value resp.error ~default:"") |> Lwt.return
+let validate client path =
+ let req = Validate {path=path; output_format=(Some client.out_format)} in
+ let%lwt resp = do_request client req in
+ match resp.status with
+ | Success -> Lwt.return (Ok "")
+ | Fail -> Error (Option.value resp.error ~default:"") |> Lwt.return
+ | _ -> Error (Option.value resp.error ~default:"") |> Lwt.return
diff --git a/src/vyconf_client.mli b/src/vyconf_client.mli
index dbf9e25..ec78780 100644
--- a/src/vyconf_client.mli
+++ b/src/vyconf_client.mli
@@ -38,3 +38,5 @@ val get_values : t -> string list -> (string, string) result Lwt.t
val list_children : t -> string list -> (string, string) result Lwt.t
val show_config : t -> string list -> (string, string) result Lwt.t
+
+val validate : t -> string list -> (string, string) result Lwt.t
diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml
index 7e0aaad..1e481b9 100644
--- a/src/vyconf_pbt.ml
+++ b/src/vyconf_pbt.ml
@@ -15,6 +15,11 @@ type request_setup_session = {
on_behalf_of : int32 option;
}
+type request_validate = {
+ path : string list;
+ output_format : request_output_format option;
+}
+
type request_set = {
path : string list;
ephemeral : bool option;
@@ -125,6 +130,7 @@ type request =
| Confirm
| Configure of request_enter_configuration_mode
| Exit_configure
+ | Validate of request_validate
| Teardown of string
type request_envelope = {
@@ -164,6 +170,14 @@ let rec default_request_setup_session
on_behalf_of;
}
+let rec default_request_validate
+ ?path:((path:string list) = [])
+ ?output_format:((output_format:request_output_format option) = None)
+ () : request_validate = {
+ path;
+ output_format;
+}
+
let rec default_request_set
?path:((path:string list) = [])
?ephemeral:((ephemeral:bool option) = None)
@@ -338,6 +352,16 @@ let default_request_setup_session_mutable () : request_setup_session_mutable = {
on_behalf_of = None;
}
+type request_validate_mutable = {
+ mutable path : string list;
+ mutable output_format : request_output_format option;
+}
+
+let default_request_validate_mutable () : request_validate_mutable = {
+ path = [];
+ output_format = None;
+}
+
type request_set_mutable = {
mutable path : string list;
mutable ephemeral : bool option;
@@ -559,6 +583,13 @@ let rec pp_request_setup_session fmt (v:request_setup_session) =
in
Pbrt.Pp.pp_brk pp_i fmt ()
+let rec pp_request_validate fmt (v:request_validate) =
+ 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 "output_format" (Pbrt.Pp.pp_option pp_request_output_format) fmt v.output_format;
+ in
+ Pbrt.Pp.pp_brk pp_i fmt ()
+
let rec pp_request_set fmt (v:request_set) =
let pp_i fmt () =
Pbrt.Pp.pp_record_field ~first:true "path" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.path;
@@ -712,6 +743,7 @@ let rec pp_request fmt (v:request) =
| Confirm -> Format.fprintf fmt "Confirm"
| Configure x -> Format.fprintf fmt "@[<hv2>Configure(@,%a)@]" pp_request_enter_configuration_mode x
| Exit_configure -> Format.fprintf fmt "Exit_configure"
+ | Validate x -> Format.fprintf fmt "@[<hv2>Validate(@,%a)@]" pp_request_validate x
| Teardown x -> Format.fprintf fmt "@[<hv2>Teardown(@,%a)@]" Pbrt.Pp.pp_string x
let rec pp_request_envelope fmt (v:request_envelope) =
@@ -774,6 +806,19 @@ let rec encode_pb_request_setup_session (v:request_setup_session) encoder =
end;
()
+let rec encode_pb_request_validate (v:request_validate) 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;
+ begin match v.output_format with
+ | Some x ->
+ encode_pb_request_output_format x encoder;
+ Pbrt.Encoder.key 2 Pbrt.Varint encoder;
+ | None -> ();
+ end;
+ ()
+
let rec encode_pb_request_set (v:request_set) encoder =
Pbrt.List_util.rev_iter_with (fun x encoder ->
Pbrt.Encoder.string x encoder;
@@ -1031,9 +1076,12 @@ let rec encode_pb_request (v:request) encoder =
| Exit_configure ->
Pbrt.Encoder.key 20 Pbrt.Bytes encoder;
Pbrt.Encoder.empty_nested encoder
+ | Validate x ->
+ Pbrt.Encoder.nested encode_pb_request_validate x encoder;
+ Pbrt.Encoder.key 21 Pbrt.Bytes encoder;
| Teardown x ->
Pbrt.Encoder.string x encoder;
- Pbrt.Encoder.key 21 Pbrt.Bytes encoder;
+ Pbrt.Encoder.key 22 Pbrt.Bytes encoder;
end
let rec encode_pb_request_envelope (v:request_envelope) encoder =
@@ -1128,6 +1176,31 @@ let rec decode_pb_request_setup_session d =
on_behalf_of = v.on_behalf_of;
} : request_setup_session)
+let rec decode_pb_request_validate d =
+ let v = default_request_validate_mutable () in
+ let continue__= ref true 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_validate), field(1)" pk
+ | Some (2, Pbrt.Varint) -> begin
+ v.output_format <- Some (decode_pb_request_output_format d);
+ end
+ | Some (2, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_validate), field(2)" pk
+ | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
+ done;
+ ({
+ path = v.path;
+ output_format = v.output_format;
+ } : request_validate)
+
let rec decode_pb_request_set d =
let v = default_request_set_mutable () in
let continue__= ref true in
@@ -1614,7 +1687,8 @@ let rec decode_pb_request d =
Pbrt.Decoder.empty_nested d ;
(Exit_configure : request)
end
- | Some (21, _) -> (Teardown (Pbrt.Decoder.string d) : request)
+ | Some (21, _) -> (Validate (decode_pb_request_validate (Pbrt.Decoder.nested d)) : request)
+ | Some (22, _) -> (Teardown (Pbrt.Decoder.string 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 fc0df2f..2cc550f 100644
--- a/src/vyconf_pbt.mli
+++ b/src/vyconf_pbt.mli
@@ -22,6 +22,11 @@ type request_setup_session = {
on_behalf_of : int32 option;
}
+type request_validate = {
+ path : string list;
+ output_format : request_output_format option;
+}
+
type request_set = {
path : string list;
ephemeral : bool option;
@@ -132,6 +137,7 @@ type request =
| Confirm
| Configure of request_enter_configuration_mode
| Exit_configure
+ | Validate of request_validate
| Teardown of string
type request_envelope = {
@@ -176,6 +182,13 @@ val default_request_setup_session :
request_setup_session
(** [default_request_setup_session ()] is the default value for type [request_setup_session] *)
+val default_request_validate :
+ ?path:string list ->
+ ?output_format:request_output_format option ->
+ unit ->
+ request_validate
+(** [default_request_validate ()] is the default value for type [request_validate] *)
+
val default_request_set :
?path:string list ->
?ephemeral:bool option ->
@@ -338,6 +351,9 @@ val pp_request_status : Format.formatter -> request_status -> unit
val pp_request_setup_session : Format.formatter -> request_setup_session -> unit
(** [pp_request_setup_session v] formats v *)
+val pp_request_validate : Format.formatter -> request_validate -> unit
+(** [pp_request_validate v] formats v *)
+
val pp_request_set : Format.formatter -> request_set -> unit
(** [pp_request_set v] formats v *)
@@ -422,6 +438,9 @@ val encode_pb_request_status : request_status -> Pbrt.Encoder.t -> unit
val encode_pb_request_setup_session : request_setup_session -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_setup_session v encoder] encodes [v] with the given [encoder] *)
+val encode_pb_request_validate : request_validate -> Pbrt.Encoder.t -> unit
+(** [encode_pb_request_validate v encoder] encodes [v] with the given [encoder] *)
+
val encode_pb_request_set : request_set -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_set v encoder] encodes [v] with the given [encoder] *)
@@ -506,6 +525,9 @@ val decode_pb_request_status : Pbrt.Decoder.t -> request_status
val decode_pb_request_setup_session : Pbrt.Decoder.t -> request_setup_session
(** [decode_pb_request_setup_session decoder] decodes a [request_setup_session] binary value from [decoder] *)
+val decode_pb_request_validate : Pbrt.Decoder.t -> request_validate
+(** [decode_pb_request_validate decoder] decodes a [request_validate] binary value from [decoder] *)
+
val decode_pb_request_set : Pbrt.Decoder.t -> request_set
(** [decode_pb_request_set decoder] decodes a [request_set] binary value from [decoder] *)
diff --git a/src/vyconfd.ml b/src/vyconfd.ml
index 9117e46..2bb3253 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -136,6 +136,13 @@ let show_config world token (req: request_show_config) =
{response_tmpl with output=(Some conf_str)}
with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+let validate world token (req: request_validate) =
+ try
+ let () = (Lwt_log.debug @@ Printf.sprintf "[%s]\n" (Vyos1x.Util.string_of_list req.path)) |> Lwt.ignore_result in
+ let () = Session.validate world (find_session token) req.path in
+ response_tmpl
+ with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+
let send_response oc resp =
let enc = Pbrt.Encoder.create () in
let%lwt () = encode_pb_response resp enc |> return in
@@ -169,6 +176,7 @@ let rec handle_connection world ic oc fd () =
| Some t, Get_values r -> get_values world t r
| Some t, List_children r -> list_children world t r
| Some t, Show_config r -> show_config world t r
+ | Some t, Validate r -> validate world t r
| _ -> failwith "Unimplemented"
end) |> Lwt.return
in