summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/vyconf.proto6
-rw-r--r--src/session.ml14
-rw-r--r--src/session.mli2
-rw-r--r--src/vyconf_cli_compat.ml9
-rw-r--r--src/vyconf_client.ml9
-rw-r--r--src/vyconf_client.mli2
-rw-r--r--src/vyconf_pbt.ml72
-rw-r--r--src/vyconf_pbt.mli22
-rw-r--r--src/vyconfd.ml12
9 files changed, 147 insertions, 1 deletions
diff --git a/data/vyconf.proto b/data/vyconf.proto
index af10d68..6ba6e6a 100644
--- a/data/vyconf.proto
+++ b/data/vyconf.proto
@@ -198,6 +198,11 @@ message Request {
required bool legacy_format = 2;
}
+ message GetCompletionEnv {
+ repeated string path = 1;
+ required bool legacy_format = 2;
+ }
+
oneof msg {
Prompt prompt = 1;
SetupSession setup_session = 2;
@@ -239,6 +244,7 @@ message Request {
ConfigUnsaved config_unsaved = 38;
ReferencePathExists reference_path_exists = 39;
GetPathType get_path_type = 40;
+ GetCompletionEnv get_completion_env = 41;
}
}
diff --git a/src/session.ml b/src/session.ml
index f924591..0bd3d95 100644
--- a/src/session.ml
+++ b/src/session.ml
@@ -397,6 +397,20 @@ let reference_path_exists w _s path =
let get_path_type ?(legacy_format=false) w _s path =
RT.get_path_type_str ~legacy_format w.reference_tree path
+let get_completion_env ?(legacy_format=false) w s path =
+ let op, path =
+ match path with
+ | [] -> raise (Session_error "Missing op and path")
+ | h :: tl -> (h, tl)
+ in
+ let config = get_proposed_config w s in
+ let res =
+ Vyos1x.Completion.get_completion_env_str ~legacy_format w.reference_tree config op path
+ in
+ match res with
+ | Ok env -> env
+ | Error e -> raise (Session_error e)
+
let write_running_cache w =
(* alert exn Internal.write_internal:
[Internal.Write_error] caught
diff --git a/src/session.mli b/src/session.mli
index 5209878..9711402 100644
--- a/src/session.mli
+++ b/src/session.mli
@@ -98,3 +98,5 @@ val show_config : world -> session_data -> string list -> string
val reference_path_exists : world -> session_data -> string list -> bool
val get_path_type : ?legacy_format:bool -> world -> session_data -> string list -> string
+
+val get_completion_env : ?legacy_format:bool -> world -> session_data -> string list -> string
diff --git a/src/vyconf_cli_compat.ml b/src/vyconf_cli_compat.ml
index c86ca2c..eb14136 100644
--- a/src/vyconf_cli_compat.ml
+++ b/src/vyconf_cli_compat.ml
@@ -12,6 +12,7 @@ type op_t =
| OpConfigUnsaved
| OpReferencePathExists
| OpGetPathType
+ | OpGetCompletionEnv
let op_of_arg s =
match s with
@@ -25,6 +26,7 @@ let op_of_arg s =
| "sessionUnsaved" -> OpConfigUnsaved
| "validateTmplPath" -> OpReferencePathExists
| "getNodeType" -> OpGetPathType
+ | "getCompletionEnv" -> OpGetCompletionEnv
| _ -> failwith (Printf.sprintf "Unknown operation %s" s)
let in_cli_config_session () =
@@ -97,6 +99,7 @@ let main op path =
| OpConfigUnsaved -> config_unsaved c None
| OpReferencePathExists -> reference_path_exists c path
| OpGetPathType -> get_path_type c path
+ | OpGetCompletionEnv -> get_completion_env c path
end
| Error e -> Error e |> Lwt.return
in
@@ -134,7 +137,11 @@ let () =
with Failure msg -> let () = print_endline msg in exit 1
in
match op, path_list with
- | OpSetEditLevel, [] | OpReferencePathExists, [] | OpGetPathType, [] ->
+ | OpSetEditLevel, []
+ | OpReferencePathExists, []
+ | OpGetPathType, [] ->
let () = print_endline "Must specify config path" in exit 1
+ | OpGetCompletionEnv, [] | OpGetCompletionEnv, [_] ->
+ let () = print_endline "Must specify command and at least one component" in exit 1
| _, _ ->
let result = Lwt_main.run (main op path_list) in exit result
diff --git a/src/vyconf_client.ml b/src/vyconf_client.ml
index 8a8dc46..6b6c6f1 100644
--- a/src/vyconf_client.ml
+++ b/src/vyconf_client.ml
@@ -245,3 +245,12 @@ let get_path_type client path =
| Success -> unwrap resp.output |> Lwt.return
| Fail -> Error (Option.value resp.error ~default:"") |> Lwt.return
| _ -> Error (Option.value resp.error ~default:"") |> Lwt.return
+
+let get_completion_env client path =
+ let req = Get_completion_env {path=path; legacy_format=true;} in
+ let%lwt resp = do_request client req in
+ match resp.status with
+ | Success -> unwrap resp.output |> Lwt.return
+ (* legacy getCompletionEnv is silent on error *)
+ | Fail -> Error "" |> Lwt.return
+ | _ -> Error (Option.value resp.error ~default:"") |> Lwt.return
diff --git a/src/vyconf_client.mli b/src/vyconf_client.mli
index fabbbed..3ee1083 100644
--- a/src/vyconf_client.mli
+++ b/src/vyconf_client.mli
@@ -53,3 +53,5 @@ val config_unsaved : t -> string option -> (string, string) result Lwt.t
val reference_path_exists : t -> string list -> (string, string) result Lwt.t
val get_path_type : t -> string list -> (string, string) result Lwt.t
+
+val get_completion_env : t -> string list -> (string, string) result Lwt.t
diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml
index 9e5873f..939af0c 100644
--- a/src/vyconf_pbt.ml
+++ b/src/vyconf_pbt.ml
@@ -192,6 +192,11 @@ type request_get_path_type = {
legacy_format : bool;
}
+type request_get_completion_env = {
+ path : string list;
+ legacy_format : bool;
+}
+
type request =
| Prompt
| Setup_session of request_setup_session
@@ -233,6 +238,7 @@ type request =
| Config_unsaved of request_config_unsaved
| Reference_path_exists of request_reference_path_exists
| Get_path_type of request_get_path_type
+ | Get_completion_env of request_get_completion_env
type request_envelope = {
token : string option;
@@ -550,6 +556,14 @@ let rec default_request_get_path_type
legacy_format;
}
+let rec default_request_get_completion_env
+ ?path:((path:string list) = [])
+ ?legacy_format:((legacy_format:bool) = false)
+ () : request_get_completion_env = {
+ path;
+ legacy_format;
+}
+
let rec default_request (): request = Prompt
let rec default_request_envelope
@@ -930,6 +944,16 @@ let default_request_get_path_type_mutable () : request_get_path_type_mutable = {
legacy_format = false;
}
+type request_get_completion_env_mutable = {
+ mutable path : string list;
+ mutable legacy_format : bool;
+}
+
+let default_request_get_completion_env_mutable () : request_get_completion_env_mutable = {
+ path = [];
+ legacy_format = false;
+}
+
type request_envelope_mutable = {
mutable token : string option;
mutable request : request;
@@ -1238,6 +1262,13 @@ let rec pp_request_get_path_type fmt (v:request_get_path_type) =
in
Pbrt.Pp.pp_brk pp_i fmt ()
+let rec pp_request_get_completion_env fmt (v:request_get_completion_env) =
+ 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 "legacy_format" Pbrt.Pp.pp_bool fmt v.legacy_format;
+ in
+ Pbrt.Pp.pp_brk pp_i fmt ()
+
let rec pp_request fmt (v:request) =
match v with
| Prompt -> Format.fprintf fmt "Prompt"
@@ -1280,6 +1311,7 @@ let rec pp_request fmt (v:request) =
| Config_unsaved x -> Format.fprintf fmt "@[<hv2>Config_unsaved(@,%a)@]" pp_request_config_unsaved x
| Reference_path_exists x -> Format.fprintf fmt "@[<hv2>Reference_path_exists(@,%a)@]" pp_request_reference_path_exists x
| Get_path_type x -> Format.fprintf fmt "@[<hv2>Get_path_type(@,%a)@]" pp_request_get_path_type x
+ | Get_completion_env x -> Format.fprintf fmt "@[<hv2>Get_completion_env(@,%a)@]" pp_request_get_completion_env x
let rec pp_request_envelope fmt (v:request_envelope) =
let pp_i fmt () =
@@ -1732,6 +1764,15 @@ let rec encode_pb_request_get_path_type (v:request_get_path_type) encoder =
Pbrt.Encoder.key 2 Pbrt.Varint encoder;
()
+let rec encode_pb_request_get_completion_env (v:request_get_completion_env) 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.bool v.legacy_format encoder;
+ Pbrt.Encoder.key 2 Pbrt.Varint encoder;
+ ()
+
let rec encode_pb_request (v:request) encoder =
begin match v with
| Prompt ->
@@ -1854,6 +1895,9 @@ let rec encode_pb_request (v:request) encoder =
| Get_path_type x ->
Pbrt.Encoder.nested encode_pb_request_get_path_type x encoder;
Pbrt.Encoder.key 40 Pbrt.Bytes encoder;
+ | Get_completion_env x ->
+ Pbrt.Encoder.nested encode_pb_request_get_completion_env x encoder;
+ Pbrt.Encoder.key 41 Pbrt.Bytes encoder;
end
let rec encode_pb_request_envelope (v:request_envelope) encoder =
@@ -2840,6 +2884,33 @@ let rec decode_pb_request_get_path_type d =
legacy_format = v.legacy_format;
} : request_get_path_type)
+let rec decode_pb_request_get_completion_env d =
+ let v = default_request_get_completion_env_mutable () in
+ let continue__= ref true in
+ let legacy_format_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_get_completion_env), field(1)" pk
+ | Some (2, Pbrt.Varint) -> begin
+ v.legacy_format <- Pbrt.Decoder.bool d; legacy_format_is_set := true;
+ end
+ | Some (2, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_get_completion_env), field(2)" pk
+ | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
+ done;
+ begin if not !legacy_format_is_set then Pbrt.Decoder.missing_field "legacy_format" end;
+ ({
+ path = v.path;
+ legacy_format = v.legacy_format;
+ } : request_get_completion_env)
+
let rec decode_pb_request d =
let rec loop () =
let ret:request = match Pbrt.Decoder.key d with
@@ -2893,6 +2964,7 @@ let rec decode_pb_request d =
| Some (38, _) -> (Config_unsaved (decode_pb_request_config_unsaved (Pbrt.Decoder.nested d)) : request)
| Some (39, _) -> (Reference_path_exists (decode_pb_request_reference_path_exists (Pbrt.Decoder.nested d)) : request)
| Some (40, _) -> (Get_path_type (decode_pb_request_get_path_type (Pbrt.Decoder.nested d)) : request)
+ | Some (41, _) -> (Get_completion_env (decode_pb_request_get_completion_env (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 5c71016..2558dc0 100644
--- a/src/vyconf_pbt.mli
+++ b/src/vyconf_pbt.mli
@@ -199,6 +199,11 @@ type request_get_path_type = {
legacy_format : bool;
}
+type request_get_completion_env = {
+ path : string list;
+ legacy_format : bool;
+}
+
type request =
| Prompt
| Setup_session of request_setup_session
@@ -240,6 +245,7 @@ type request =
| Config_unsaved of request_config_unsaved
| Reference_path_exists of request_reference_path_exists
| Get_path_type of request_get_path_type
+ | Get_completion_env of request_get_completion_env
type request_envelope = {
token : string option;
@@ -535,6 +541,13 @@ val default_request_get_path_type :
request_get_path_type
(** [default_request_get_path_type ()] is the default value for type [request_get_path_type] *)
+val default_request_get_completion_env :
+ ?path:string list ->
+ ?legacy_format:bool ->
+ unit ->
+ request_get_completion_env
+(** [default_request_get_completion_env ()] is the default value for type [request_get_completion_env] *)
+
val default_request : unit -> request
(** [default_request ()] is the default value for type [request] *)
@@ -686,6 +699,9 @@ val pp_request_reference_path_exists : Format.formatter -> request_reference_pat
val pp_request_get_path_type : Format.formatter -> request_get_path_type -> unit
(** [pp_request_get_path_type v] formats v *)
+val pp_request_get_completion_env : Format.formatter -> request_get_completion_env -> unit
+(** [pp_request_get_completion_env v] formats v *)
+
val pp_request : Format.formatter -> request -> unit
(** [pp_request v] formats v *)
@@ -827,6 +843,9 @@ val encode_pb_request_reference_path_exists : request_reference_path_exists -> P
val encode_pb_request_get_path_type : request_get_path_type -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_get_path_type v encoder] encodes [v] with the given [encoder] *)
+val encode_pb_request_get_completion_env : request_get_completion_env -> Pbrt.Encoder.t -> unit
+(** [encode_pb_request_get_completion_env v encoder] encodes [v] with the given [encoder] *)
+
val encode_pb_request : request -> Pbrt.Encoder.t -> unit
(** [encode_pb_request v encoder] encodes [v] with the given [encoder] *)
@@ -968,6 +987,9 @@ val decode_pb_request_reference_path_exists : Pbrt.Decoder.t -> request_referenc
val decode_pb_request_get_path_type : Pbrt.Decoder.t -> request_get_path_type
(** [decode_pb_request_get_path_type decoder] decodes a [request_get_path_type] binary value from [decoder] *)
+val decode_pb_request_get_completion_env : Pbrt.Decoder.t -> request_get_completion_env
+(** [decode_pb_request_get_completion_env decoder] decodes a [request_get_completion_env] binary value from [decoder] *)
+
val decode_pb_request : Pbrt.Decoder.t -> request
(** [decode_pb_request decoder] decodes a [request] binary value from [decoder] *)
diff --git a/src/vyconfd.ml b/src/vyconfd.ml
index 96c2e42..d34deab 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -433,6 +433,17 @@ let get_path_type world token (req: request_get_path_type) =
with Session.Session_error msg ->
{response_tmpl with status=Fail; error=(Some msg)}
+let get_completion_env world token (req: request_get_completion_env) =
+ let s = find_session token in
+ try
+ let node_type =
+ Session.get_completion_env
+ ~legacy_format:req.legacy_format world s req.path
+ in
+ {response_tmpl with output=(Some node_type)}
+ 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
@@ -492,6 +503,7 @@ let rec handle_connection world ic oc () =
| Some t, Config_unsaved r -> config_unsaved world t r
| Some t, Reference_path_exists r -> reference_path_exists world t r
| Some t, Get_path_type r -> get_path_type world t r
+ | Some t, Get_completion_env r -> get_completion_env world t r
| _ -> failwith "Unimplemented"
) |> Lwt.return
end