require'mixlib/cli'require'iapi-idlc-sdk-pfm/helpers'require'securerandom'require'json'require'aws-sdk-s3'modulePfmmoduleCommandclassBaseincludeMixlib::CLIincludePfm::HelpersclassInvalidRepository<StandardError;endclassBuildFailure<StandardError;endclassDeploymentFailure<StandardError;endoption:help,short: '-h',long: '--help',description: 'Show this message',boolean: trueoption:version,short: '-v',long: '--version',description: 'Show pfm version',boolean: trueoption:verbose,short: '-V',long: '--verbose',description: 'Show detailed output',boolean: true,default: falsedefinitializesuper@workspace=Idlc::Workspace.newend## optparser overwrites -h / --help options with its own.# In order to control this behavior, make sure the default options are# handled here.#defrun_with_default_options(params=[])ifneeds_help?(params)msg(opt_parser.to_s)0elsifneeds_version?(params)msg("Pfm Version: #{Pfm::VERSION}")0elseENV['DEBUG']='true'ifverbose?(params)run(params)endrescueNameError=>eerr("ERROR: #{e.message}\n")1rescueOptionParser::InvalidOption,OptionParser::MissingArgument=>eerr("ERROR: #{e.message}\n")msg(opt_parser)1rescueIdlc::Build::MissingMetadataFile,Idlc::Build::MissingRequiredMetadataAttribute,InvalidRepository=>eerr("ERROR: #{e.message}\n")1ensure@workspace.cleanupunless@workspace.empty?enddefdownload_private_key(bucket,subkey,outdir)s3=Aws::S3::Client.new(region: SETTINGS['AWS_REGION'])resp=s3.get_object(bucket: bucket,key: "#{subkey}/private_key.pem",response_target: "#{outdir}/private_key.pem")truerescueAws::S3::Errors::NoSuchKeyfalseenddefbuild_setupPacker::Binary.configuredo|config|config.version=SETTINGS['PACKER_VERSION']config.download_path="/tmp/#{SecureRandom.uuid}"end@build_config=Idlc::Build::Config.new(SETTINGS['AWS_REGION'])@workspace.add(build_base_dir)build_dir="#{@workspace.tmp_dir}/#{build_base_dir}".freezemsg("Using build template: Build::#{@params.first}::#{@config[:build_template]}::#{@config[:build_metadata]}")# Include build metadata@build_metadata=Idlc::Build::Metadata.new(@params.first,@config[:build_metadata])# load the rest of the metadata@build_metadata.load# load version from command line if specified@build_metadata.attributes['version']=Idlc::Build::Metadata::MetadataAttribute.new(@config[:build_version],true)unless@config[:build_version].nil?# check metadata requirements@build_metadata.requirements_satisfied?msg("Template Version: #{@build_metadata.attributes['version'].value}")@build_metadata.attributes.eachdo|key,att|# load metadata file as packer user vars@build_config.add_build_var_v2(key,att.value)end# Copy over the base template and auxillary files for Packertpl=Idlc::Build::Template.new(@build_metadata.attributes,"#{build_dir}/build.json")tpl.write# copy auxiliary filessystem("cp -a #{templates_dir}/files #{build_dir}")Dir.chdir(build_dir)enddefdeploy_setupTerraform::Binary.configuredo|config|config.version=SETTINGS['TERRAFORM_VERSION']config.download_path="/tmp/#{SecureRandom.uuid}"endraiseInvalidRepository,'This doesn\'t look like a valid infrastructure repository'unlessFile.directory?"#{inf_base_dir}/tf"config=Idlc::Deploy::Config.new(SETTINGS['AWS_REGION'])config.parse("#{inf_base_dir}/env/config/default.yml")ifFile.exist?"#{inf_base_dir}/env/config/default.yml"ifENV['PROD']=='true'||ENV['PROD']=='1'config.parse("#{inf_base_dir}/env/config/prod.yml")elseconfig.parse("#{inf_base_dir}/env/config/devtest.yml")endconfig.parse("#{inf_base_dir}/env/size/#{ENV['SIZE']}.yml")ifFile.exist?"#{inf_base_dir}/env/size/#{ENV['SIZE']}.yml"inf_conf_file='inf.config.yml'# For unit testsinf_conf_file='inf.config.example.yml'unlessFile.exist?inf_conf_fileconfig.parse(inf_conf_file)bucket_name=Idlc::Deploy::Config.get_deployment_var('tfstate_bucket')sub_bucket="#{Idlc::Deploy::Config.get_deployment_var('job_code')}"\"#{Idlc::Deploy::Config.get_deployment_var('job')}"\"-#{Idlc::Deploy::Config.get_deployment_var('env')}".freeze# Pass some ENV vars for TerraformIdlc::Deploy::Config.add_deployment_var('environment_key',sub_bucket)Idlc::Deploy::Config.add_deployment_var('version',REPO_VERSION)Idlc::Deploy::Config.add_deployment_var('major_minor',Idlc::Utility.major_minor(REPO_VERSION))Idlc::Deploy::Config.add_deployment_var('major_minor_patch',Idlc::Utility.major_minor_patch(REPO_VERSION))Idlc::Deploy::Config.add_deployment_var('build',@config[:server_build])Idlc::Deploy::Config.add_deployment_var('app_release',@config[:app_release])FileUtils.mkdir_p"inf/env/kp"download_private_key(bucket_name,sub_bucket,"#{inf_base_dir}/env/kp")Idlc::Deploy::Keypair.generate("#{inf_base_dir}/env/kp")@workspace.flatten("#{inf_base_dir}/tf",'tf')@workspace.add("#{inf_base_dir}/env/kp")@workspace.add('lib/tf/modules')config.configure_state(bucket_name,sub_bucket,@workspace.tmp_dir)enddefdeploy_setupv2Terraform::Binary.configuredo|config|config.version=SETTINGS['TERRAFORM_VERSION']config.download_path="/tmp/#{SecureRandom.uuid}"end# Create dynamic variables file for terraform based on configkeys={}vars_file=''env_metadata=JSON.parse(open(@config[:config_file]).read)['account','environment','ec2','application'].eachdo|section|env_metadata[section].eachdo|key,value|# skip dupsnextunlesskeys[key].nil?# replace null with empty stringvalue=''ifvalue.nil?# skip lists and mapsnextunless(value.instance_of?String)# add to vars file and record key for dupskeys[key]='parsed'vars_file+=<<~EOH
variable "#{key}" {}
EOH# load value into envrionmentIdlc::Deploy::Config.add_deployment_var(key,value)endend# write vars fileFile.open("#{config[:working_dir]}/#{env_metadata['environment_key']}-tfvars.tf",'w'){|file|file.write(vars_file)}# Pass some extra vars for TerraformIdlc::Deploy::Config.add_deployment_var('aws_region',SETTINGS['AWS_REGION'])Idlc::Deploy::Config.add_deployment_var('environment_key',env_metadata['environment_key'])Idlc::Deploy::Config.add_deployment_var('version',env_metadata['environment']['inf_version'])Idlc::Deploy::Config.add_deployment_var('app_release',@config[:app_release])Idlc::Deploy::Config.add_deployment_var('encrypted_svc_pass',env_metadata['environment']['encrypted']['svc_pass'])ENV['APP_RELEASE']=@config[:app_release]FileUtils.mkdir_p"inf/env/kp"download_private_key(env_metadata['account']['tfstate_bucket'],env_metadata['environment_key'],"inf/env/kp")Idlc::Deploy::Keypair.generate("inf/env/kp")config=Idlc::Deploy::Config.new(SETTINGS['AWS_REGION'])config.configure_state(env_metadata['account']['tfstate_bucket'],env_metadata['environment_key'],@config[:working_dir])enddeftemplates_dir"#{__dir__}/templates/#{@build_metadata.attributes['build_stage'].value}"enddefbuild_base_dir"#{SETTINGS['BUILD_BASE_DIR']}/#{@params.first}"enddefinf_base_dirSETTINGS['INF_BASE_DIR']enddefbuild_dir"#{@workspace.tmp_dir}/#{build_base_dir}".freezeenddefbuild_exists?returntrueifDir.exist?build_base_dir# doesn't exist@errors.push("Build::#{@params.first} doesnt exist")falseenddefneeds_help?(params)params.include?('-h')||params.include?('--help')enddefneeds_version?(params)params.include?('-v')||params.include?('--version')enddefverbose?(params)params.include?('-V')||params.include?('--verbose')endendendend