idlc-sdk-pfm 1.0.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +37 -0
  9. data/Rakefile +6 -0
  10. data/bin/pfm +8 -0
  11. data/docs/GettingStarted.md +299 -0
  12. data/idlc-sdk-pfm.gemspec +44 -0
  13. data/lib/idlc-sdk-pfm/builtin_commands.rb +11 -0
  14. data/lib/idlc-sdk-pfm/cli.rb +150 -0
  15. data/lib/idlc-sdk-pfm/command/apply.rb +71 -0
  16. data/lib/idlc-sdk-pfm/command/base.rb +195 -0
  17. data/lib/idlc-sdk-pfm/command/build.rb +120 -0
  18. data/lib/idlc-sdk-pfm/command/configure.rb +41 -0
  19. data/lib/idlc-sdk-pfm/command/destroy.rb +61 -0
  20. data/lib/idlc-sdk-pfm/command/exec.rb +24 -0
  21. data/lib/idlc-sdk-pfm/command/format.rb +64 -0
  22. data/lib/idlc-sdk-pfm/command/generate.rb +83 -0
  23. data/lib/idlc-sdk-pfm/command/generator_commands/base.rb +50 -0
  24. data/lib/idlc-sdk-pfm/command/generator_commands/server_build.rb +58 -0
  25. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/Berksfile +3 -0
  26. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/build_cookbook/.kitchen.yml +21 -0
  27. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/build_cookbook/README.md +146 -0
  28. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +8 -0
  29. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/chefignore +107 -0
  30. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -0
  31. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -0
  32. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/delivery-config.json +12 -0
  33. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/delivery-project.toml +36 -0
  34. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/gitignore +21 -0
  35. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/README.md +24 -0
  36. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -0
  37. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -0
  38. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +6 -0
  39. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -0
  40. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -0
  41. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +4 -0
  42. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -0
  43. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/environments/README.md +9 -0
  44. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/environments/example.json +13 -0
  45. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/policies/README.md +24 -0
  46. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/roles/README.md +9 -0
  47. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/repo/roles/example.json +13 -0
  48. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/spec_helper.rb +2 -0
  49. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -0
  50. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/metadata.rb +7 -0
  51. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/app.rb +89 -0
  52. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/attribute.rb +12 -0
  53. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/build_cookbook.rb +182 -0
  54. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/cookbook.rb +144 -0
  55. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/cookbook_file.rb +24 -0
  56. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/lwrp.rb +23 -0
  57. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/policyfile.rb +8 -0
  58. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/recipe.rb +51 -0
  59. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/repo.rb +67 -0
  60. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/recipes/template.rb +32 -0
  61. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
  62. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -0
  63. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
  64. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
  65. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
  66. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -0
  67. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/README.md.erb +4 -0
  68. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  69. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -0
  70. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -0
  71. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +8 -0
  72. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  73. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +18 -0
  74. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/kitchen.yml.erb +26 -0
  75. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +33 -0
  76. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/metadata.rb.erb +20 -0
  77. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/provider.rb.erb +0 -0
  78. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/recipe.rb.erb +5 -0
  79. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/recipe_spec.rb.erb +22 -0
  80. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -0
  81. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/resource.rb.erb +0 -0
  82. data/lib/idlc-sdk-pfm/command/generator_commands/skeletons/code_generator/templates/default/template.erb +0 -0
  83. data/lib/idlc-sdk-pfm/command/generator_commands.rb +34 -0
  84. data/lib/idlc-sdk-pfm/command/plan.rb +80 -0
  85. data/lib/idlc-sdk-pfm/command/templates/app/files/config/client.rb.template +9 -0
  86. data/lib/idlc-sdk-pfm/command/templates/app/files/config/init.ps1.userdata +16 -0
  87. data/lib/idlc-sdk-pfm/command/templates/base/files/config/client.rb.template +6 -0
  88. data/lib/idlc-sdk-pfm/command/templates/base/files/config/init.ps1.userdata +219 -0
  89. data/lib/idlc-sdk-pfm/command/validate.rb +85 -0
  90. data/lib/idlc-sdk-pfm/command/validator_commands/base.rb +65 -0
  91. data/lib/idlc-sdk-pfm/command/validator_commands/infrastructure.rb +46 -0
  92. data/lib/idlc-sdk-pfm/command/validator_commands/server_build.rb +135 -0
  93. data/lib/idlc-sdk-pfm/command/validator_commands.rb +32 -0
  94. data/lib/idlc-sdk-pfm/commands_map.rb +61 -0
  95. data/lib/idlc-sdk-pfm/generator.rb +52 -0
  96. data/lib/idlc-sdk-pfm/helpers.rb +49 -0
  97. data/lib/idlc-sdk-pfm/settings.rb +205 -0
  98. data/lib/idlc-sdk-pfm/validator.rb +52 -0
  99. data/lib/idlc-sdk-pfm/version.rb +3 -0
  100. data/lib/idlc-sdk-pfm.rb +24 -0
  101. metadata +342 -0
@@ -0,0 +1,195 @@
1
+ require 'mixlib/cli'
2
+ require 'idlc-sdk-pfm/helpers'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Base
7
+ include Mixlib::CLI
8
+ include Pfm::Helpers
9
+
10
+ class InvalidRepository < StandardError; end
11
+ class BuildFailure < StandardError; end
12
+ class DeploymentFailure < StandardError; end
13
+
14
+ option :help,
15
+ short: '-h',
16
+ long: '--help',
17
+ description: 'Show this message',
18
+ boolean: true
19
+
20
+ option :version,
21
+ short: '-v',
22
+ long: '--version',
23
+ description: 'Show pfm version',
24
+ boolean: true
25
+
26
+ option :verbose,
27
+ short: '-V',
28
+ long: '--verbose',
29
+ description: 'Show detailed output',
30
+ boolean: true,
31
+ default: false
32
+
33
+ def initialize
34
+ super
35
+
36
+ @workspace = Idlc::Workspace.new
37
+ end
38
+
39
+ #
40
+ # optparser overwrites -h / --help options with its own.
41
+ # In order to control this behavior, make sure the default options are
42
+ # handled here.
43
+ #
44
+ def run_with_default_options(params = [])
45
+ if needs_help?(params)
46
+ msg(opt_parser.to_s)
47
+ 0
48
+ elsif needs_version?(params)
49
+ msg("Pfm Version: #{Pfm::VERSION}")
50
+ 0
51
+ else
52
+ ENV['DEBUG'] = 'true' if verbose?(params)
53
+ run(params)
54
+ end
55
+ rescue NameError => e
56
+ err("ERROR: #{e.message}\n")
57
+ 1
58
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
59
+ err("ERROR: #{e.message}\n")
60
+ msg(opt_parser)
61
+ 1
62
+ rescue Idlc::Build::MissingMetadataFile, Idlc::Build::MissingRequiredMetadataAttribute, InvalidRepository => e
63
+ err("ERROR: #{e.message}\n")
64
+ 1
65
+ ensure
66
+ @workspace.cleanup unless @workspace.empty?
67
+ end
68
+
69
+ def build_setup
70
+ Packer::Binary.configure do |config|
71
+ config.version = SETTINGS['PACKER_VERSION']
72
+ end
73
+
74
+ @build_config = Idlc::Build::Config.new(SETTINGS['AWS_REGION'])
75
+ @workspace.add(build_base_dir)
76
+
77
+ build_dir = "#{@workspace.tmp_dir}/#{build_base_dir}".freeze
78
+
79
+ msg("Using build template: Build::#{@params.first}::#{@config[:build_template]}::#{@config[:build_metadata]}")
80
+
81
+ # Include build metadata
82
+ @build_metadata = Idlc::Build::Metadata.new(@params.first, @config[:build_metadata])
83
+
84
+ # load the rest of the metadata
85
+ @build_metadata.load
86
+
87
+ # load version from command line if specified
88
+ @build_metadata.attributes['version'] = Idlc::Build::Metadata::MetadataAttribute.new(@config[:build_version], true) unless @config[:build_version].nil?
89
+
90
+ # check metadata requirements
91
+ @build_metadata.requirements_satisfied?
92
+
93
+ msg("Template Version: #{@build_metadata.attributes['version'].value}")
94
+
95
+ @build_metadata.attributes.each do |key, att|
96
+ # load metadata file as packer user vars
97
+ @build_config.add_build_var_v2(key, att.value)
98
+ end
99
+
100
+ # Copy over the base template and auxillary files for Packer
101
+ tpl = Idlc::Build::Template.new(
102
+ @build_metadata.attributes,
103
+ "#{build_dir}/build.json"
104
+ )
105
+ tpl.write
106
+
107
+ # copy auxiliary files
108
+ system("cp -a #{templates_dir}/files #{build_dir}")
109
+
110
+ Dir.chdir(build_dir)
111
+ end
112
+
113
+ def deploy_setup
114
+ Terraform::Binary.configure do |config|
115
+ config.version = SETTINGS['TERRAFORM_VERSION']
116
+ end
117
+
118
+ raise InvalidRepository, 'This doesn\'t look like a valid infrastructure repository' unless File.directory? "#{inf_base_dir}/tf"
119
+ config = Idlc::Deploy::Config.new(SETTINGS['AWS_REGION'])
120
+
121
+ config.parse("#{inf_base_dir}/env/config/default.yml") if File.exist? "#{inf_base_dir}/env/config/default.yml"
122
+
123
+ if ENV['PROD'] == 'true' || ENV['PROD'] == '1'
124
+ config.parse("#{inf_base_dir}/env/config/prod.yml")
125
+ else
126
+ config.parse("#{inf_base_dir}/env/config/devtest.yml")
127
+ end
128
+
129
+ config.parse("#{inf_base_dir}/env/size/#{ENV['SIZE']}.yml") if File.exist? "#{inf_base_dir}/env/size/#{ENV['SIZE']}.yml"
130
+
131
+ inf_conf_file = 'inf.config.yml'
132
+
133
+ # For unit tests
134
+ inf_conf_file = 'inf.config.example.yml' unless File.exist? inf_conf_file
135
+ config.parse(inf_conf_file)
136
+
137
+ bucket_name = Idlc::Deploy::Config.get_deployment_var('tfstate_bucket')
138
+ sub_bucket = "#{Idlc::Deploy::Config.get_deployment_var('job_code')}"\
139
+ "#{Idlc::Deploy::Config.get_deployment_var('job')}"\
140
+ "-#{Idlc::Deploy::Config.get_deployment_var('env')}".freeze
141
+
142
+ # Pass some ENV vars for Terraform
143
+ Idlc::Deploy::Config.add_deployment_var('environment_key', sub_bucket)
144
+ Idlc::Deploy::Config.add_deployment_var('version', REPO_VERSION)
145
+ Idlc::Deploy::Config.add_deployment_var('major_minor', Idlc::Utility.major_minor(REPO_VERSION))
146
+ Idlc::Deploy::Config.add_deployment_var('major_minor_patch', Idlc::Utility.major_minor_patch(REPO_VERSION))
147
+ Idlc::Deploy::Config.add_deployment_var('build', @config[:server_build])
148
+ Idlc::Deploy::Config.add_deployment_var('app_release', @config[:app_release])
149
+
150
+ config.configure_state(bucket_name, sub_bucket)
151
+
152
+ Idlc::Deploy::Keypair.generate("#{inf_base_dir}/env/kp")
153
+ @workspace.flatten("#{inf_base_dir}/tf", 'tf')
154
+ @workspace.add("#{inf_base_dir}/env/kp")
155
+ @workspace.add('lib/tf/modules')
156
+ end
157
+
158
+ def templates_dir
159
+ "#{__dir__}/templates/#{@build_metadata.attributes['build_stage'].value}"
160
+ end
161
+
162
+ def build_base_dir
163
+ "#{SETTINGS['BUILD_BASE_DIR']}/#{@params.first}"
164
+ end
165
+
166
+ def inf_base_dir
167
+ SETTINGS['INF_BASE_DIR']
168
+ end
169
+
170
+ def build_dir
171
+ "#{@workspace.tmp_dir}/#{build_base_dir}".freeze
172
+ end
173
+
174
+ def build_exists?
175
+ return true if Dir.exist? build_base_dir
176
+
177
+ # doesn't exist
178
+ @errors.push("Build::#{@params.first} doesnt exist")
179
+ false
180
+ end
181
+
182
+ def needs_help?(params)
183
+ params.include?('-h') || params.include?('--help')
184
+ end
185
+
186
+ def needs_version?(params)
187
+ params.include?('-v') || params.include?('--version')
188
+ end
189
+
190
+ def verbose?(params)
191
+ params.include?('-V') || params.include?('--verbose')
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,120 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'mixlib/shellout'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Build < Base
7
+ banner 'Usage: pfm build BUILD_NAME [options]'
8
+
9
+ option :app_release,
10
+ short: '-a VERSION',
11
+ long: '--app-release VERSION',
12
+ description: 'Application Version Number to build',
13
+ default: ''
14
+
15
+ option :build_version,
16
+ short: '-b VERSION',
17
+ long: '--build-version VERSION',
18
+ description: 'override version number of build',
19
+ default: nil
20
+
21
+ option :build_template,
22
+ short: '-t TEMPLATE',
23
+ long: '--build-template TEMPLATE',
24
+ description: 'The Build Template to use. Defaults to build.json',
25
+ default: 'build.json'
26
+
27
+ option :build_metadata,
28
+ short: '-m METADATA_FILE',
29
+ long: '--build-metadata METADATA_FILE',
30
+ description: 'The build metadata file to use. Defaults to \'metadata\'',
31
+ default: 'metadata'
32
+
33
+ option :build_number,
34
+ short: '-n NUMBER',
35
+ long: '--build-number NUMBER',
36
+ description: 'Override the build number. Default is ENV::BUILD_NUMBER',
37
+ default: ENV['BUILD_NUMBER']
38
+
39
+ def initialize
40
+ super
41
+ @params_valid = true
42
+ @errors = []
43
+ end
44
+
45
+ def run(params)
46
+ @params = params
47
+ read_and_validate_params
48
+
49
+ if params_valid?
50
+ build_setup
51
+ build
52
+ # @workspace.cleanup causing bundler issues
53
+ 0
54
+ else
55
+ @errors.each { |error| err("Error: #{error}") }
56
+ parse_options(params)
57
+ msg(opt_parser)
58
+ 1
59
+ end
60
+ rescue BuildFailure => e
61
+ err("ERROR: #{e.message}\n")
62
+ 1
63
+ end
64
+
65
+ def build
66
+ # Zip the cookbooks for transfer
67
+ Idlc::Workspace.zip_folder('./chef', "#{@workspace.tmp_dir}/cookbooks.zip")
68
+
69
+ # Start the HTTP server to facilitate file transfers. This is to replace
70
+ # WINRM for file transfers in Packer due to slowness. This function returns
71
+ # the process id of the server instance.
72
+ pid = Idlc::Build::Httpd.start(@workspace.tmp_dir)
73
+
74
+ # #start will return twice when forking the HTTP server off, once for the
75
+ # parent and once for the child. When the child return, the pid is nil. We want
76
+ # to skip that run.
77
+ unless pid.nil?
78
+ # Pass some ENV vars for Packer
79
+ @build_config.add_build_var_v2('aws_region', SETTINGS['AWS_REGION'])
80
+ @build_config.add_build_var_v2('app_release', @config[:app_release])
81
+ @build_config.add_build_var_v2('build_uuid', SecureRandom.uuid.to_s)
82
+ @build_config.add_build_var_v2('build_number', @config[:build_number])
83
+ @build_config.add_build_var_v2('httpd_server', Idlc::Build::Httpd.private_ip.to_s)
84
+ @build_config.add_build_var_v2('httpd_port', ENV['HTTPD_PORT'])
85
+
86
+ begin
87
+ Packer::Binary.build("#{@build_config.dump_build_vars} #{@config[:build_template]}")
88
+ Idlc::Build::Httpd.stop(pid)
89
+ Dir.chdir(build_base_dir)
90
+ rescue
91
+ Idlc::Build::Httpd.stop(pid)
92
+ Dir.chdir(build_base_dir)
93
+ raise BuildFailure, 'The build finished with errors'
94
+ end
95
+
96
+ end
97
+
98
+ Dir.chdir(build_base_dir)
99
+ end
100
+
101
+ def read_and_validate_params
102
+ arguments = parse_options(@params)
103
+
104
+ case arguments.size
105
+ when 1
106
+ @params_valid = build_exists?
107
+
108
+ when 2
109
+
110
+ else
111
+ @params_valid = false
112
+ end
113
+ end
114
+
115
+ def params_valid?
116
+ @params_valid
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,41 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'mixlib/shellout'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Configure < Pfm::Command::Base
7
+ banner 'Usage: pfm configure SYSTEM_COMMAND'
8
+
9
+ def run(params)
10
+ current_set = Pfm::Settings.new
11
+ new_settings = {}
12
+
13
+ current_set.settings.each do |key, setting|
14
+ print("#{key} [#{setting.value}]: ")
15
+ stdin = STDIN.gets.chomp.strip
16
+
17
+ required = setting.required?
18
+ new_value = setting.value
19
+ new_value = stdin unless null?(stdin)
20
+
21
+ new_settings[key] = Pfm::Settings::Setting.new(new_value, required)
22
+ end
23
+
24
+ current_set.save_config(new_settings)
25
+ end
26
+
27
+ def needs_version?(_params)
28
+ # Force version to get passed down to command
29
+ false
30
+ end
31
+
32
+ def null?(value)
33
+ value.nil? || value == ''
34
+ end
35
+
36
+ def needs_help?(params)
37
+ ['-h', '--help'].include? params[0]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'mixlib/shellout'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Destroy < Base
7
+ banner 'Usage: pfm destroy [options]'
8
+
9
+ def initialize
10
+ super
11
+ @params_valid = true
12
+ @errors = []
13
+ end
14
+
15
+ def run(params)
16
+ @params = params
17
+ read_and_validate_params
18
+
19
+ if params_valid?
20
+ deploy_setup
21
+ destroy
22
+ # @workspace.cleanup causing bundler issues
23
+ 0
24
+ else
25
+ @errors.each { |error| err("Error: #{error}") }
26
+ parse_options(params)
27
+ msg(opt_parser)
28
+ 1
29
+ end
30
+ rescue DeploymentFailure => e
31
+ err("ERROR: #{e.message}\n")
32
+ 1
33
+ end
34
+
35
+ def destroy
36
+ Idlc::Deploy::Config.add_deployment_var('build', 'null')
37
+ Idlc::Deploy::Config.add_deployment_var('app_release', 'null')
38
+
39
+ Terraform::Binary.get("-update #{@workspace.tmp_dir}")
40
+ Terraform::Binary.destroy("-refresh=false #{@workspace.tmp_dir}")
41
+ rescue
42
+ raise DeploymentFailure, 'Finished with errors'
43
+ end
44
+
45
+ def read_and_validate_params
46
+ arguments = parse_options(@params)
47
+
48
+ @params_valid = case arguments.size
49
+ when 0
50
+ true
51
+ else
52
+ false
53
+ end
54
+ end
55
+
56
+ def params_valid?
57
+ @params_valid
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,24 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'mixlib/shellout'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Exec < Pfm::Command::Base
7
+ banner 'Usage: pfm exec SYSTEM_COMMAND'
8
+
9
+ def run(params)
10
+ exec(*params)
11
+ raise 'Exec failed without an exception, your ruby is buggy' # should never get here
12
+ end
13
+
14
+ def needs_version?(_params)
15
+ # Force version to get passed down to command
16
+ false
17
+ end
18
+
19
+ def needs_help?(params)
20
+ ['-h', '--help'].include? params[0]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,64 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'mixlib/shellout'
3
+
4
+ module Pfm
5
+ module Command
6
+ class Format < Base
7
+ banner 'Usage: pfm format [options]'
8
+
9
+ def initialize
10
+ super
11
+ @params_valid = true
12
+ @errors = []
13
+ end
14
+
15
+ def run(params)
16
+ @params = params
17
+ read_and_validate_params
18
+
19
+ if params_valid?
20
+ fmt
21
+ # @workspace.cleanup causing bundler issues
22
+ 0
23
+ else
24
+ @errors.each { |error| err("Error: #{error}") }
25
+ parse_options(params)
26
+ msg(opt_parser)
27
+ 1
28
+ end
29
+ rescue DeploymentFailure => e
30
+ err("ERROR: #{e.message}\n")
31
+ 1
32
+ end
33
+
34
+ def fmt
35
+ raise InvalidRepository, 'This doesn\'t look like a valid infrastructure repository' unless File.directory? "#{inf_base_dir}/tf"
36
+ tf_paths = %W[#{inf_base_dir}/tf lib/tf/modules]
37
+
38
+ begin
39
+ tf_paths.each do |path|
40
+ # Format the file to a canonical syntax
41
+ Terraform::Binary.fmt(path)
42
+ end
43
+ rescue
44
+ raise DeploymentFailure, 'Finished with errors'
45
+ end
46
+ end
47
+
48
+ def read_and_validate_params
49
+ arguments = parse_options(@params)
50
+
51
+ case arguments.size
52
+ when 0
53
+ @params_valid = true
54
+ else
55
+ @params_valid = false
56
+ end
57
+ end
58
+
59
+ def params_valid?
60
+ @params_valid
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,83 @@
1
+ require 'idlc-sdk-pfm/command/base'
2
+ require 'idlc-sdk-pfm/command/generator_commands'
3
+ require 'idlc-sdk-pfm/command/generator_commands/base'
4
+ require 'idlc-sdk-pfm/command/generator_commands/server_build'
5
+
6
+ module Pfm
7
+ module Command
8
+ class Generate < Base
9
+
10
+ GeneratorCommand = Struct.new(:name, :class_name, :description)
11
+
12
+ def self.generators
13
+ @generators ||= []
14
+ end
15
+
16
+ def self.generator(name, class_name, description)
17
+ generators << GeneratorCommand.new(name, class_name, description)
18
+ end
19
+
20
+ generator('server-build', :ServerBuild, 'Generate a server build repo')
21
+
22
+ def self.banner_headline
23
+ <<-E
24
+ Usage: pfm generate GENERATOR [options]
25
+ Available generators:
26
+ E
27
+ end
28
+
29
+ def self.generator_list
30
+ justify_size = generators.map { |g| g.name.size }.max + 2
31
+ generators.map { |g| " #{g.name.to_s.ljust(justify_size)}#{g.description}" }.join("\n")
32
+ end
33
+
34
+ def self.banner
35
+ banner_headline + generator_list + "\n"
36
+ end
37
+
38
+ # pfm generate app path/to/basename --skel=path/to/skeleton --example
39
+ # pfm generate file name [path/to/cookbook_root] (inferred from cwd) --from=source_file
40
+
41
+ def initialize(*args)
42
+ super
43
+ end
44
+
45
+ def run(params)
46
+ if generator_spec = generator_for(params[0])
47
+ params.shift
48
+ generator = GeneratorCommands.build(generator_spec.class_name, params)
49
+ generator.run
50
+ else
51
+ msg(banner)
52
+ 1
53
+ end
54
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
55
+ # Pfm::Command::Base also handles this error in the same way, but it
56
+ # does not have access to the correct option parser, so it cannot print
57
+ # the usage correctly. Therefore, invalid CLI usage needs to be handled
58
+ # here.
59
+ err("ERROR: #{e.message}\n")
60
+ msg(generator.opt_parser)
61
+ 1
62
+ end
63
+
64
+ def generator_for(arg)
65
+ self.class.generators.find { |g| g.name.to_s == arg }
66
+ end
67
+
68
+ # In the Base class, this is defined to be true if any args match "-h" or
69
+ # "--help". Here we override that behavior such that if the first
70
+ # argument is a valid generator name, like `pfm generate cookbook -h`,
71
+ # we delegate the request to the specified generator.
72
+ def needs_help?(params)
73
+ return false if have_generator?(params[0])
74
+ super
75
+ end
76
+
77
+ def have_generator?(name)
78
+ self.class.generators.map { |g| g.name.to_s }.include?(name)
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,50 @@
1
+ require "idlc-sdk-pfm/command/generator_commands"
2
+
3
+ module Pfm
4
+ module Command
5
+ module GeneratorCommands
6
+ # ## Base
7
+ #
8
+ # Base class for `chef generate` subcommands. Contains basic behaviors
9
+ # for setting up the generator context, detecting git, and launching a
10
+ # chef converge.
11
+ #
12
+ # The behavior of the generators is largely delegated to a chef cookbook.
13
+ # The default implementation is the `code_generator` cookbook in
14
+ # pfm/skeletons/code_generator.
15
+ class Base < Command::Base
16
+
17
+ attr_reader :params
18
+ attr_reader :errors
19
+
20
+ options.merge!(SharedGeneratorOptions.options)
21
+
22
+ def initialize(params)
23
+ super()
24
+ @params_valid = true
25
+ @errors = []
26
+ @params = params
27
+ end
28
+
29
+ def setup_context
30
+ end
31
+
32
+ def read_and_validate_params
33
+ arguments = parse_options(params)
34
+ case arguments.size
35
+ when 1
36
+
37
+ when 2
38
+
39
+ else
40
+ @params_valid = false
41
+ end
42
+ end
43
+
44
+ def params_valid?
45
+ @params_valid
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,58 @@
1
+ module Pfm
2
+ module Command
3
+ module GeneratorCommands
4
+ class ServerBuild < Base
5
+ banner 'Usage: pfm generate server-build NAME [options]'
6
+
7
+ options.merge!(SharedGeneratorOptions.options)
8
+
9
+ def run
10
+ read_and_validate_params
11
+ if params_valid?
12
+ setup_context
13
+
14
+ mk_build_dirs
15
+ default_build_files
16
+ default_cookbooks
17
+ else
18
+ errors.each { |error| err("Error: #{error}") }
19
+ parse_options(params)
20
+ msg(opt_parser)
21
+ 1
22
+ end
23
+ end
24
+
25
+ def mk_build_dirs
26
+ %w(
27
+ chef/bake/cookbooks
28
+ chef/fry/cookbooks
29
+ chef/vendor/cookbooks
30
+ ).each do |path|
31
+ FileUtils.mkdir_p("#{base_dir}/#{path}", verbose: verbose?(params))
32
+ end
33
+ end
34
+
35
+ def default_build_files
36
+ %w(
37
+ metadata
38
+ ).each do |file|
39
+ FileUtils.touch("#{base_dir}/#{file}", verbose: verbose?(params))
40
+ end
41
+ end
42
+
43
+ def default_cookbooks
44
+ %w(
45
+ chef/bake/cookbooks/bake
46
+ chef/fry/cookbooks/fry
47
+ ).each do |cookbook|
48
+ system("chef generate cookbook #{base_dir}/#{cookbook} -g #{__dir__}/skeletons/code_generator")
49
+ end
50
+ end
51
+
52
+ def base_dir
53
+ "builds/#{@params.first}"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ source 'https://supermarket.chef.io'
2
+
3
+ metadata