Add virtual-mcp11-ovs-ironic model

This patch add an example of cluster model with ironic enabled

Change-Id: Ifc43d39bea636ccee93f6aa62e10e5367b342960
diff --git a/scripts/node_updater.py b/scripts/node_updater.py
new file mode 100644
index 0000000..e1030f9
--- /dev/null
+++ b/scripts/node_updater.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+import argparse
+import os
+import sys
+import yaml
+
+def _merge_items(a, b, path=None):
+    """Merge b into a"""
+    if path is None: path = []
+    for key in b:
+        if key in a:
+            if isinstance(a[key], dict) and isinstance(b[key], dict):
+                _merge_items(a[key], b[key], path + [str(key)])
+            elif a[key] == b[key]:
+                pass # same leaf value
+            else:
+                raise Exception('Conflict at %s' % '.'.join(path + [str(key)]))
+        else:
+            a[key] = b[key]
+    return a
+
+def repo_add(content, name, source, pin_priority=None):
+  """Adds repo dict to provided content"""
+  t = {}
+  r = {name: {'architectures': 'amd64',
+              'source': source}}
+  if pin_priority:
+      r[name]['pin'] = [{'package': '*',
+                         'priority': pin_priority,
+                         'pin': 'release o=Ubuntu'}]
+  t['parameters'] = {'linux': {'system': {'repo': r}}}
+  _merge_items(content, t)
+
+def main():
+    parser = argparse.ArgumentParser(description='Update reclass model for specific node')
+    parser.add_argument('--node',
+                        type=str,
+                        help='FQDN of the node to update.')
+    parser.add_argument('--node-path',
+                        type=str,
+                        default='/srv/salt/reclass/nodes/_generated',
+                        help='Path to directory with the nodes.')
+    subparsers = parser.add_subparsers()
+
+   
+    # create the parser for the "add" command
+    parser_add = subparsers.add_parser('repo_add', help='Add a new repo.')
+    parser_add.set_defaults(command='repo_add')
+    parser_add.add_argument('--repo-name',
+                            type=str,
+                            required=True,
+                            help='The name of the repo to add.')
+    parser_add.add_argument('--source',
+                            type=str,
+                            required=True,
+                            help='The source link of the repo. For example: '
+                                 'deb http://my.repo.com/xenial ocata main')
+    parser_add.add_argument('--priority',
+                            type=int,
+                            help='The pin priority of the repo.')
+    args = parser.parse_args()
+    
+    if args.node:
+        node_files = ['%s/%s.yml' % (args.node_path, args.node)]
+    else:
+        
+        node_files = ['%s/%s' % (args.node_path, f) for f in os.listdir(args.node_path) if f.endswith('.yml')]
+
+    # check we can read the file
+    for node_file in node_files:
+        node_name = os.path.basename(node_file)[:-4]
+        if not os.access(node_file, os.W_OK):
+            print("Can not write to nodes file %s" % node_file, file=sys.stderr)
+            sys.exit(1)
+
+        try:
+            content = {}
+            with open(node_file) as f:
+                content = yaml.load(f)
+
+            if args.command == 'repo_add':
+                print("Adding repo to the node: %s" % node_name)
+                repo_add(content, args.repo_name, args.source, args.priority)
+
+            with open(node_file, "w") as f:
+                yaml.dump(content, f, default_flow_style=False)
+            print("Node: %s has been updated successfully." % node_name)
+
+        except Exception as e:
+            print(e, file=sys.stderr)
+            sys.exit(1)
+
+if __name__ == '__main__':
+    main()