calculate subnet/netmask from cidr
[yaml_builds.git] / scripts / jcopy.py
index fb3f21e..d124f08 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 ##############################################################################
-# Copyright © 2018 AT&T Intellectual Property. All rights reserved.          #
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.        #
 #                                                                            #
 # Licensed under the Apache License, Version 2.0 (the "License"); you may    #
 # not use this file except in compliance with the License.                   #
 # limitations under the License.                                             #
 ##############################################################################
 
-#
 #  jcopy.py - Copy a file or files to a target directory, making
 #    substitutions as needed from the values contained in a YAML file.
+#    compatibile with python and python3
 #
-#  usage: jcopy.py <yaml> <in_dir_or_file> <out_dir>
-#
-#  Note: jcopy.sh is for Python2, jcopy3.sh is for Python3
-#
+#  usage: jcopy.py <yaml_input> <template_dir_or_file> <out_dir>
 
 import os.path
 import jinja2
 import sys
 import yaml
+import netaddr
 
-def expand_files(target_dir, dir_name, files):
-  global total
-  xlen = len(sys.argv[2])
-  targdir = target_dir + dir_name[xlen:]
-  if not os.path.exists(targdir):
-    os.makedirs(targdir)
-  env = jinja2.Environment()
-  env.trim_blocks = True
-  env.lstrip_blocks = True
+def cidr_netmask(value):
+  if '/' in str(value):
+    v = netaddr.IPNetwork(value)
+    result = v.netmask
+  else:
+    result = "ERROR"
+  return result
 
-  for f in files:
-    if f.endswith(".j2"):
-      t = f.replace(".j2", ".yaml")
-      source_path = dir_name + '/' + f
-      target_path = targdir + '/' + t
-      if os.path.isfile(source_path):
-        with open(source_path) as fd:
-          template = env.from_string(fd.read())
-        data = template.render(yaml=yaml)
-        fd2 = open(target_path,'w')
-        fd2.write(data)
-        fd2.write("\n")
-        fd2.close()
-        print '{0} -> {1}'.format(source_path, target_path)
-        total += 1
+def cidr_subnet(value):
+  if '/' in str(value):
+    v = netaddr.IPNetwork(value)
+    result = v.network
+  else:
+    result = "ERROR"
+  return result
+
+def usage(msg=None):
+  if not msg is None:
+    print(msg)
+  print( 'usage: jcopy.py <yaml> <template_dir_or_file> <out_dir>' )
+  sys.exit(1)
 
-def expand_file(target_dir, file):
-  global total
-  if not os.path.exists(target_dir):
-    os.makedirs(target_dir)
-  env = jinja2.Environment()
-  env.trim_blocks = True
-  env.lstrip_blocks = True
-  with open(file) as fd:
-    template = env.from_string(fd.read())
-  data = template.render(yaml=yaml)
-  target_path = target_dir + '/' + os.path.basename(file)
-  fd2 = open(target_path,'w')
-  fd2.write(data)
-  fd2.write("\n")
-  fd2.close()
-  print '{0} -> {1}'.format(file, target_path)
-  total += 1
+def expand_template( t, output_fname, fill=60 ):
+  print( '### {0: <{fill}} ==> {1}'.format(t.filename, output_fname, fill=fill) )
+  if not os.path.exists(os.path.dirname(output_fname)):
+    os.makedirs(os.path.dirname(output_fname))
+  t.stream(yaml=siteyaml).dump(output_fname)
 
 if len(sys.argv) != 4:
-  print 'usage: jcopy.py <yaml> <in_dir_or_file> <out_dir>'
-  sys.exit(1)
+  usage('incorrect number of arguments')
+
+yaml_input=sys.argv[1]
+j2in_name=sys.argv[2]
+yaml_out=sys.argv[3]
 
-with open(sys.argv[1]) as f:
-  yaml = yaml.safe_load(f)
+if not os.path.isfile(yaml_input):
+  usage('input yaml file {} does not exist'.format(yaml_input))
 
-total = 0
-if os.path.isfile(sys.argv[2]):
-  expand_file(sys.argv[3], sys.argv[2])
+with open(yaml_input) as f:
+  siteyaml = yaml.safe_load(f)
+
+if os.path.isfile(j2in_name):
+  j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(j2in_name)), trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, undefined=jinja2.make_logging_undefined())
+  j2_env.filters['cidr_netmask'] = cidr_netmask
+  j2_env.filters['cidr_subnet'] = cidr_subnet
+  expand_template(j2_env.get_template(name=os.path.basename(j2in_name)),yaml_out,len(j2in_name))
 else:
-  os.path.walk(sys.argv[2], expand_files, sys.argv[3])
-print '%d files processed.' % total
+  j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(j2in_name), trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, undefined=jinja2.make_logging_undefined())
+  j2_env.filters['cidr_netmask'] = cidr_netmask
+  j2_env.filters['cidr_subnet'] = cidr_subnet
+  templates=j2_env.list_templates(extensions=('j2'))
+  fill=len(max(templates,key=len))+len(j2in_name)
+  for f in templates:
+    expand_template(j2_env.get_template(name=f), yaml_out+'/'+f.replace('.j2','.yaml'), fill)
+  print('%d files processed.' % len(templates))
+
 sys.exit(0)
 
-# sudo python -m ensurepip --default-pip
-# sudo python -m pip install --upgrade pip setuptools wheel
-# pip install --user jinja2 PyYAML
+# sudo apt-get install python-jinja2 python-yaml
+# sudo apt-get install python3-jinja2 python3-yaml