Advertisement
Guest User

Untitled

a guest
May 2nd, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 9.90 KB | None | 0 0
  1.  
  2. require 'json'
  3. require 'find'
  4. require 'fileutils'
  5. require 'optparse'
  6.  
  7. ARGV << '-h' if ARGV.empty?
  8. @jsonprovided = false
  9. @pathprovided = false
  10. ARGV.each do |i|
  11.   @jsonprovided = i.include?("-j") ? true : i.include?("--json") ? true : false unless @jsonprovided == true
  12.   @pathprovided = i.include?("-p") ? true : i.include?("--path") ? true : false unless @pathprovided == true
  13. end
  14.  
  15. ARGV.clear && ARGV[0] = '-h'  if @jsonprovided == false || @pathprovided == false
  16.  
  17. options = OpenStruct.new
  18.  
  19. def validateparam(param, option)
  20.   if param[0] == '-'
  21.     puts "Wrong argument passed to #{option}!!"
  22.     exit
  23.   end
  24. end
  25.  
  26. OptionParser.new do |opts|
  27.  
  28.   options.recreate = false
  29.   options.log = "auto"
  30.   options.env = nil
  31.   options.data = nil
  32.   options.app = nil
  33.  
  34.   opts.banner = "Usage: deployvm.rb [options]"
  35.  
  36.   opts.separator ""
  37.   opts.separator "Specific options:"
  38.  
  39.   opts.on("-jJSON", "--json-file=JSON", "REQUIRED : Json Provision File (machine name) ex.: ldcpjambon01") do |json|
  40.     validateparam(json, "--json-file")
  41.     options.json = json
  42.   end
  43.  
  44.   opts.on("-pPATH", "--path-json=PATH", "REQUIRED : Path to json provision file ex.: /home/path/to/prov") do |path|
  45.     validateparam(path, "--path-json")
  46.     options.path = path
  47.   end
  48.  
  49.   opts.on("-aAPP", "--app-name=APP", "OPTIONAL : Application name for multi-file provisioning") do |app|
  50.     options.app = app
  51.   end
  52.  
  53.   opts.on("-dDATA", "--data-center=DATA", "OPTIONAL : Data center : LDC or CDC") do |data|
  54.     options.data = data
  55.   end
  56.  
  57.   opts.on("-eENV", "--env=ENV", "OPTIONAL : Environment (Prod[p], Preprod[x], UAT[i], QA[q], Training[t], Test[s], Dev[d])") do |env|
  58.     options.env = env
  59.   end
  60.  
  61.   opts.on("-lLOG", "--log-level=LOG", "OPTIONAL : Chef run log level [auto error warn info debug] (default auto)") do |log|
  62.     options.log = log
  63.   end
  64.  
  65.   opts.on("-r", "--recreate", "OPTIONAL : Recreate machine (default no)") do |rec|
  66.     options.recreate = rec
  67.   end
  68.  
  69.   opts.on_tail("-h", "--help", "Show this message") do
  70.     puts opts
  71.     exit
  72.   end
  73.  
  74.   options
  75.  
  76. end.parse!
  77.  
  78. application_name = options.app unless options.app.nil?
  79. regionoption = options.data unless options.data.nil?
  80. environmentoption = options.env unless options.env.nil?
  81. provisionfileparameter = options.json.include?("json") ? "#{options.json}" : "#{options.json}.json"
  82. path_to_json_files = options.path[-1,1] == "/" ? options.path : "#{options.path}/"
  83. chef_log_level = options.log
  84. options.recreate ? recreatemachine = true : recreatemachine = false
  85. parser_used = true
  86.  
  87.  
  88.  
  89. node_name = "jproven3"
  90. vsphere_user = "YPG\\#{node_name}"
  91. vsphere_password = ""
  92. unless File.exist?("#{ENV["HOME"]}/.chef/dev_#{node_name}.pem") || File.exist?("#{ENV["HOME"]}/.chef/new_#{node_name}.pem")
  93.   puts "WARNING!"
  94.   puts "You are missing either the dev_#{node_name}.pem file or new_#{node_name}.pem file!! (in #{ENV["HOME"]}/.chef)"
  95.   puts "Please run sross1's chef setup script!"
  96.   exit
  97. end
  98. client_key = File.new("#{ENV["HOME"]}/.chef/#{node_name}.pem")
  99. client_key_dev = File.new("#{ENV["HOME"]}/.chef/dev_#{node_name}.pem")
  100. client_key_new = File.new("#{ENV["HOME"]}/.chef/new_#{node_name}.pem")
  101. puts "client_key.class = #{client_key.class}"
  102. cookbookdependencies = ["yp_devops_deployement"]
  103. runlist = ["yp_devops_deployement"]
  104. cookbookfolder = Dir.new("#{ENV["HOME"]}/cookbooks/")
  105. puts "cookbookfolder.class = #{cookbookfolder.class}"
  106. deployrepo = "/tmp/deployrepo"
  107. vssshkeypath = File.new("#{cookbookfolder.class == Dir ? cookbookfolder.path : cookbookfolder}/yp_devops_deployement/files/default/id_rsa_chef_deployer")
  108. cookbooknameprefix = "deployrepo__"
  109. cookbookname = "#{cookbooknameprefix}"
  110.  
  111.  
  112.  
  113. FileUtils.rm_rf(deployrepo) if Dir.exist?(deployrepo)
  114.  
  115. def getjsonfile(filename, dir_contain_json)
  116.   return_json = nil
  117.   if !File.exist?(filename)
  118.     Find.find(dir_contain_json) do |path|
  119.       if Dir.exist?(path)
  120.         next
  121.       else
  122.         return_json = File.file?(path) ? File.new(path) : path
  123.         break if File.basename(return_json) == File.basename(filename)
  124.       end
  125.     end
  126.   else
  127.     return_json = File.new(filename)
  128.   end
  129.   return_json.nil? ? nil : File.realpath(return_json)
  130. end
  131.  
  132. provisionfile = getjsonfile(provisionfileparameter, path_to_json_files)
  133.  
  134. environmentoption = provisionfileparameter[3] if environmentoption.nil?
  135. environmentparameter = case environmentoption.upcase
  136. when "PROD", "P"
  137.       "p"
  138.   when "PREPROD", "X"
  139.       "x"
  140.   when "UAT", "I"
  141.       "i"
  142.   when "QA", "Q"
  143.       "q"
  144.   when "TRAINING", "T"
  145.       "t"
  146.   when "TEST", "S"
  147.       "s"
  148.   when "DEV", "D"
  149.       "d"
  150.   else
  151.     puts "Invalid env #{environmentoption}"
  152.     exit
  153. end
  154.  
  155. regionsuffix = "#{environmentparameter}#{application_name}"
  156.  
  157. regionoption = provisionfileparameter[0..2] if regionoption.nil?
  158. regionfileparameter = case regionoption.upcase
  159.   when "CDC"
  160.       "cdc#{regionsuffix}.json"
  161.   when "LDC"
  162.       "ldc#{regionsuffix}.json"
  163.   else
  164.       puts "Invalid / No region parameter set (region = #{regionoption})"
  165.       exit 108
  166. end
  167.  
  168. regionfile = getjsonfile(regionfileparameter, path_to_json_files)
  169.  
  170. applicationfileparameter="#{application_name}.json"
  171. applicationfile = getjsonfile(applicationfileparameter, path_to_json_files)
  172.  
  173. cookbookdependsreplacement = cookbookdependencies.map {|cookbook| "depends '#{cookbook}'"}
  174.  
  175. def buildmachine(recreatemachine, actualfolder, deployrepo, cookbooknameprefix, cookbookname, cookbookfolder, provisionfile, regionfile, applicationfile, cookbookdependsreplacement, runlist, node_name, client_key, client_key_dev, client_key_new, chef_log_level, vssshkeypath, vsphere_user, vsphere_password)
  176.     Dir.chdir(actualfolder)
  177.   Dir.mkdir(deployrepo) if !Dir.exist?(deployrepo)
  178.     Dir.chdir(deployrepo)
  179.   FileUtils.rm_rf(cookbooknameprefix)
  180.   puts "Generating deployment cookbook"
  181.     system("chef generate cookbook #{cookbookname} > /dev/null")
  182.  
  183.     Dir.chdir(cookbookname)
  184.  
  185.   nodepath = File.join(Dir.pwd, File.join('nodes',File.basename(provisionfile)))
  186.     solofile = File.join(Dir.pwd, 'solo.rb')
  187.     tmpprovisionfile = File.join(Dir.pwd, File.basename(provisionfile))
  188.  
  189.   FileUtils.rm_rf(File.dirname(nodepath))
  190.   Dir.mkdir(File.dirname(nodepath))
  191.  
  192.   File.open("Berksfile", "w") do |file|
  193.     file.puts "source 'https://supermarket.chef.io'\nsource :chef_server\n\nmetadata".each_line {|line| line}
  194.   end
  195.     # puts "\nBerksfile\n" + File.read("Berksfile")
  196.  
  197.   File.open("metadata.rb", "a+") do |file|
  198.     file.puts cookbookdependsreplacement.join("\n").each_line {|line| line}
  199.   end
  200.     # puts "\nmetadata.rb\n" + File.read("metadata.rb")
  201.  
  202.  
  203.  
  204.   puts "Fetch require cookbooks"
  205.   system("berks vendor --delete \"#{deployrepo.path}\" > /dev/null")
  206.   customcred =
  207.   {
  208.     "deployeroptions": {
  209.       "VS_SSH_KEY": vssshkeypath.class == File ? vssshkeypath.path : vssshkeypath,
  210.       "vsphere_user": vsphere_user,
  211.       "vsphere_password": vsphere_password
  212.     },
  213.     "run_list": runlist
  214.   }
  215.   nodejson = JSON.parse(File.read(provisionfile)).to_h
  216.   puts "\nnodejson = #{nodejson}\n"
  217.   regionjson = JSON.parse(File.read(regionfile)).to_h unless regionfile.nil?
  218.   puts "\nregionjson = #{regionjson}\n" unless regionjson.nil?
  219.   appjson = JSON.parse(File.read(applicationfile)).to_h unless applicationfile.nil?
  220.   puts "\nappjson = #{appjson}\n" unless appjson.nil?
  221.   if ! regionjson.nil? || ! appjson.nil?
  222.     all_merged = appjson.deep_merge(regionjson).deep_merge(nodejson).deep_merge(customcred)
  223.   elsif regionjson.nil? || ! appjson.nil?
  224.     all_merged = appjson.deep_merge(nodejson).deep_merge(customcred)
  225.   elsif ! regionjson.nil? || appjson.nil?
  226.     all_merged = regionjson.deep_merge(nodejson).deep_merge(customcred)
  227.   else
  228.     all_merged = nodejson.deep_merge(customcred)
  229.   end
  230.  
  231.   puts "\nmerged_json = #{all_merged}"
  232.   finalclientkey = all_merged["ypchef"]["chefserver"].include?("chefdev") ? client_key_dev : all_merged["ypchef"]["chefserver"].include?("chefsrv") ? client_key_new : client_key
  233.   puts ("final client key = #{finalclientkey.path}")
  234.  
  235.   File.open(solofile, "w") do |file|
  236.     file.puts "cookbook_path [\n\t'#{cookbookfolder.path}'\n]\nnode_path '#{nodepath}'\nnode_name '#{node_name}'\nclient_key '#{finalclientkey.path}'\nsolo true\nlog_level :#{chef_log_level}".each_line {|line| line}
  237.   end
  238.  
  239.   File.open("all_merged.json", "w") do |file|
  240.     file.puts JSON.pretty_generate(all_merged)
  241.   end
  242.   puts "\nall_merged.json\n" + File.read("all_merged.json")
  243.  
  244.     if recreatemachine == true
  245.     then
  246.         puts "\nDestroying the machine"
  247.     destroyhash = all_merged.deep_merge({"ypvm": {"action": "destroy"}}.transform_keys{|k| k.to_s})
  248.     File.open("alldestroy.json", "w") do |file|
  249.       file.puts JSON.pretty_generate(destroyhash)
  250.     end
  251.     # puts "\nalldestroy.json\n" + File.read("alldestroy.json")
  252.         system("chef-solo -c solo.rb -j \"alldestroy.json\"")
  253.         puts "\nRebuilding the machine"
  254.     nodefile = File.join("nodes",File.join(File.basename(provisionfile),"#{node_name}.json"))
  255.     nodeinfo = JSON.parse(File.read(nodefile)).to_h
  256.     nodeinfo["normal"]["ypvm"]["action"] = "converge"
  257.     File.open(nodefile, "w") do |file|
  258.       file.puts JSON.pretty_generate(nodeinfo)
  259.     end
  260.   end
  261.   # machinename1 = provisionfile.split('.')[0].split('/').last
  262.   # system("#{ENV["HOME"]}/.chef/knife.sh dev vault update ssh_private_keys root -C #{machinename1}")
  263.     system("chef-solo -c solo.rb -j \"all_merged.json\"")
  264. end
  265.  
  266. class ::Hash
  267.   def deep_merge(second)
  268.       merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2  }
  269.       # puts "\nMerging json1\n#{self}\n\n with json2\n#{second}"
  270.       self.merge(second, &merger)
  271.   end
  272. end
  273.  
  274. buildmachine(recreatemachine, Dir.pwd, deployrepo, cookbooknameprefix, cookbookname, cookbookfolder, provisionfile, regionfile, applicationfile, cookbookdependsreplacement, runlist, node_name, client_key, client_key_dev, client_key_new, chef_log_level, vssshkeypath, vsphere_user, vsphere_password)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement