summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2025-01-29 21:08:14 -0600
committerJohn Estabrook <jestabro@vyos.io>2025-02-03 08:22:35 -0600
commit07595537a8020603cb36801cefa22314c2fe74e8 (patch)
tree669e370e43773b987b99d99fbb8d7a6c8fb257a9
parente19c9f0201d507471a7401733c5af7c776f9e6c2 (diff)
downloadvyos1x-config-07595537a8020603cb36801cefa22314c2fe74e8.tar.gz
vyos1x-config-07595537a8020603cb36801cefa22314c2fe74e8.zip
T6946: add function get_tagged_delete_tree to restore tag values
The config diff function produces both del(ete) and sub(tract) trees. The delete tree contains the minimal path difference between compared trees, for example, between the active and proposed configs; this is the information needed to execute removal of a path. The subtract tree contains the full paths in active that are not in proposed; this retains necessary information in certain cases. In case all tag values of a tag node are removed, the delete tree contains only the tag node itself, however for proper script execution of a deleted tag node, one will need the removed tag node values: restore this information from the subtract tree.
-rw-r--r--src/config_diff.ml27
-rw-r--r--src/config_diff.mli1
2 files changed, 28 insertions, 0 deletions
diff --git a/src/config_diff.ml b/src/config_diff.ml
index 6b84bc8..87b2663 100644
--- a/src/config_diff.ml
+++ b/src/config_diff.ml
@@ -262,6 +262,33 @@ let diff_tree path left right =
let ret = make Config_tree.default_data "" [add_node; sub_node; del_node; int_node] in
ret
+(* convenience function needed for commit algorithm:
+ we need a hybrid tree between the 'del' tree and the 'sub' tree, namely:
+ in case the del tree has a terminal tag node (== all tag values have
+ been removed) add tag node values for proper removal in commit execution
+ *)
+
+let get_tagged_delete_tree dt =
+ let del_tree = Config_tree.get_subtree dt ["del"] in
+ let sub_tree = Config_tree.get_subtree dt ["sub"] in
+ let f (p, a) _t =
+ let q = List.rev p in
+ match q with
+ | [] -> (p, a)
+ | _ ->
+ if Config_tree.is_tag a q && Vytree.is_terminal_path a q then
+ let children = Vytree.children_of_path sub_tree q in
+ let insert_child path node name =
+ Vytree.insert ~position:Lexical node (path @ [name]) Config_tree.default_data
+ in
+ let a' = List.fold_left (insert_child q) a children in
+ (p, a')
+ else
+ (p, a)
+ in
+ snd (Vytree.fold_tree_with_path f ([], del_tree) del_tree)
+
+
(* the following builds a diff_func to return a unified diff string of
configs or config commands
*)
diff --git a/src/config_diff.mli b/src/config_diff.mli
index af8f87d..ee34532 100644
--- a/src/config_diff.mli
+++ b/src/config_diff.mli
@@ -46,3 +46,4 @@ val show_diff : ?cmds:bool -> string list -> Config_tree.t -> Config_tree.t -> s
val tree_union : Config_tree.t -> Config_tree.t -> Config_tree.t
val mask_tree : Config_tree.t -> Config_tree.t -> Config_tree.t
val make_diff_cstore : Config_tree.t -> Config_tree.t -> int -> Diff_cstore.t result
+val get_tagged_delete_tree : Config_tree.t -> Config_tree.t