Add method to merge dict objects to yaml files

PROD-36050

Change-Id: I7e3cfb005a575bc5ffa078746f6623870307d005
diff --git a/.gitignore b/.gitignore
index 72364f9..9e00340 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,3 +87,6 @@
 
 # Rope project settings
 .ropeproject
+
+# PyCharm project settings
+.idea/
diff --git a/reclass_tools/cli.py b/reclass_tools/cli.py
index b46f542..7fc1baf 100644
--- a/reclass_tools/cli.py
+++ b/reclass_tools/cli.py
@@ -147,6 +147,12 @@
                           contexts=self.params.contexts,
                           env_name=self.params.env_name)
 
+    def do_merge_context(self):
+        content = yaml.load(open(self.params.yaml).read(), yaml.SafeLoader)
+        walk_models.merge_dict_to_reclass(
+            self.params.path,
+            content)
+
     def get_params(self):
 
         verbose_parser = argparse.ArgumentParser(add_help=False)
@@ -177,6 +183,11 @@
             help=('Value to add to the reclass model files, can be in the '
                   'inline YAML format'))
 
+        yaml_parser = argparse.ArgumentParser(add_help=False)
+        yaml_parser.add_argument(
+            'yaml',
+            help='Path to YAML file with extra context')
+
         path_parser = argparse.ArgumentParser(add_help=False)
         path_parser.add_argument(
             'path',
@@ -295,6 +306,10 @@
                               parents=[render_parser, env_name_parser],
                               help=("Render cookiecutter template using "
                                     "multiple metadata sources"))
+        subparsers.add_parser('merge-context',
+                              parents=[yaml_parser, path_parser],
+                              help=("Merge nested content from YAML file "
+                                    "to specified reclass models"))
 
         if len(self.args) == 0:
             self.args = ['-h']
diff --git a/reclass_tools/walk_models.py b/reclass_tools/walk_models.py
index 533a120..86cc2ef 100644
--- a/reclass_tools/walk_models.py
+++ b/reclass_tools/walk_models.py
@@ -245,3 +245,32 @@
                                     )
                                 )
     # return found_keys
+
+
+def merge_dict_to_reclass(paths, dict_obj,
+                          verbose=False):
+    """
+    Add bunch of values to the specific reclass models
+    :param paths: list, paths to reclass files to edit
+    :param dict: obj be added to the reclass model
+    :return: None
+    """
+    for path in paths:
+        for fyml in walkfiles(path, verbose=verbose):
+            if not fyml.fname.endswith('.yml'): continue
+            try:
+                model = helpers.yaml_read(fyml.fname)
+            except yaml.scanner.ScannerError as e:
+                print(e, file=sys.stderr)
+                continue
+            if model is None: continue
+            # ----------------------------
+            merged_model = helpers.merge_nested_objects(model, dict_obj)
+            # ----------------------------
+            with open(fyml.fname, 'w') as f:
+                f.write(
+                    yaml.dump(
+                        merged_model, default_flow_style=False,
+                        width=255
+                    )
+                )
\ No newline at end of file