cfndk 0.1.1.2 → 0.1.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 (45) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/.rspec +2 -0
  5. data/Gemfile.lock +9 -5
  6. data/README.md +124 -10
  7. data/cfndk.gemspec +3 -0
  8. data/docker/Dockerfile +8 -0
  9. data/docker/build.sh +3 -0
  10. data/docker/cfndk.sh +14 -0
  11. data/lib/cfndk.rb +9 -0
  12. data/lib/cfndk/change_set_command.rb +14 -8
  13. data/lib/cfndk/command.rb +14 -6
  14. data/lib/cfndk/credential_provider_chain.rb +12 -42
  15. data/lib/cfndk/credential_resolvable.rb +10 -0
  16. data/lib/cfndk/diff.rb +38 -0
  17. data/lib/cfndk/global_config.rb +32 -2
  18. data/lib/cfndk/key_pair.rb +33 -1
  19. data/lib/cfndk/key_pair_command.rb +10 -3
  20. data/lib/cfndk/key_pairs.rb +12 -0
  21. data/lib/cfndk/stack.rb +58 -59
  22. data/lib/cfndk/stack_command.rb +26 -8
  23. data/lib/cfndk/stacks.rb +16 -0
  24. data/lib/cfndk/template_packager.rb +210 -0
  25. data/lib/cfndk/uuid.rb +10 -0
  26. data/lib/cfndk/version.rb +1 -1
  27. data/spec/cfndk_spec.rb +1 -1
  28. data/spec/cfndk_stack_create_spec.rb +365 -5
  29. data/spec/cfndk_stack_destroy_spec.rb +64 -0
  30. data/spec/cfndk_stack_update_spec.rb +86 -0
  31. data/spec/fixtures/big_vpc.yaml +533 -0
  32. data/spec/fixtures/lambda_function/index.js +4 -0
  33. data/spec/fixtures/lambda_function/lambda_function.json +4 -0
  34. data/spec/fixtures/lambda_function/lambda_function.yaml +28 -0
  35. data/spec/fixtures/nested_stack.json +35 -0
  36. data/spec/fixtures/nested_stack.yaml +20 -0
  37. data/spec/fixtures/serverless_function/index.js +4 -0
  38. data/spec/fixtures/serverless_function/serverless_function.json +4 -0
  39. data/spec/fixtures/serverless_function/serverless_function.yaml +21 -0
  40. data/spec/fixtures/stack.json +8 -0
  41. data/spec/fixtures/stack.template.json +39 -0
  42. data/spec/fixtures/stack.yaml +22 -0
  43. data/spec/fixtures/vpc.template.json +40 -0
  44. data/vagrant/Vagrantfile +89 -0
  45. metadata +80 -4
@@ -2,6 +2,8 @@ module CFnDK
2
2
  class Command < Thor
3
3
  include Thor::Actions
4
4
  include ConfigFileLoadable
5
+ include CredentialResolvable
6
+
5
7
  class << self
6
8
  def exit_on_failure?
7
9
  true
@@ -44,19 +46,25 @@ module CFnDK
44
46
  option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
45
47
  option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
46
48
  option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
47
- option :stack_names, type: :array, desc: 'Target stack names'
49
+ option :stack_names, type: :array, aliases: 's', desc: 'Target stack names'
48
50
  option :keypair_names, type: :array, desc: 'Target keypair names'
49
51
  def create
50
52
  CFnDK.logger.info 'create...'.color(:green)
51
53
  data = load_config_data(options)
52
-
53
- credentials = CFnDK::CredentialProviderChain.new.resolve
54
+ credentials = resolve_credential(data, options)
55
+ global_config = CFnDK::GlobalConfig.new(data, options)
54
56
  stacks = CFnDK::Stacks.new(data, options, credentials)
55
57
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
56
58
 
59
+ global_config.pre_command_execute
60
+ stacks.pre_command_execute
57
61
  stacks.validate
62
+ keypairs.pre_command_execute
58
63
  keypairs.create
64
+ keypairs.post_command_execute
59
65
  stacks.create
66
+ stacks.post_command_execute
67
+ global_config.post_command_execute
60
68
  return 0
61
69
  rescue => e
62
70
  CFnDK.logger.error "#{e.class}: #{e.message}".color(:red)
@@ -73,8 +81,8 @@ module CFnDK
73
81
  def destroy
74
82
  CFnDK.logger.info 'destroy...'.color(:green)
75
83
  data = load_config_data(options)
84
+ credentials = resolve_credential(data, options)
76
85
 
77
- credentials = CFnDK::CredentialProviderChain.new.resolve
78
86
  stacks = CFnDK::Stacks.new(data, options, credentials)
79
87
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
80
88
 
@@ -97,14 +105,14 @@ module CFnDK
97
105
  desc 'report', 'Report stack'
98
106
  option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
99
107
  option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
100
- option :stack_names, type: :array, desc: 'Target stack names'
108
+ option :stack_names, type: :array, aliases: 's', desc: 'Target stack names'
101
109
  option :types, type: :array, default: %w(tag output parameter resource event), desc: 'Report type'
102
110
  def report
103
111
  CFnDK.logger.info 'report...'.color(:green)
104
112
 
105
113
  data = load_config_data(options)
114
+ credentials = resolve_credential(data, options)
106
115
 
107
- credentials = CFnDK::CredentialProviderChain.new.resolve
108
116
  stacks = CFnDK::Stacks.new(data, options, credentials)
109
117
  stacks.report
110
118
  return 0
@@ -1,12 +1,14 @@
1
1
  module CFnDK
2
2
  class CredentialProviderChain
3
- def initialize(config = nil)
4
- @config = config
3
+ def initialize(profile = nil)
4
+ @profile = profile
5
5
  end
6
6
 
7
7
  def resolve
8
8
  providers.each do |method_name, options|
9
- provider = send(method_name, options.merge(config: @config))
9
+ CFnDK.logger.debug "resolving: #{method_name}"
10
+ provider = send(method_name, options)
11
+ CFnDK.logger.debug "resolved: #{method_name}" if provider && provider.set?
10
12
  return provider if provider && provider.set?
11
13
  end
12
14
  nil
@@ -16,30 +18,17 @@ module CFnDK
16
18
 
17
19
  def providers
18
20
  [
19
- [:static_credentials, {}],
20
21
  [:env_credentials, {}],
21
22
  [:assume_role_credentials, {}],
22
- [:shared_credentials, {}],
23
- [:process_credentials, {}],
23
+ [:shared_credentials, {profile: @profile}],
24
24
  [:instance_profile_credentials, {
25
- retries: @config ? @config.instance_profile_credentials_retries : 0,
26
- http_open_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
27
- http_read_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
25
+ retries: 0,
26
+ http_open_timeout: 1,
27
+ http_read_timeout: 1,
28
28
  }],
29
29
  ]
30
30
  end
31
31
 
32
- def static_credentials(options)
33
- if options[:config]
34
- ::Aws::Credentials.new(
35
- options[:config].access_key_id,
36
- options[:config].secret_access_key,
37
- options[:config].session_token)
38
- else
39
- nil
40
- end
41
- end
42
-
43
32
  def env_credentials(options)
44
33
  key = %w(AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY)
45
34
  secret = %w(AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY)
@@ -55,8 +44,8 @@ module CFnDK
55
44
  end
56
45
 
57
46
  def shared_credentials(options)
58
- if options[:config]
59
- ::Aws::SharedCredentials.new(profile_name: options[:config].profile)
47
+ if options[:profile]
48
+ ::Aws::SharedCredentials.new(profile_name: options[:profile])
60
49
  else
61
50
  ::Aws::SharedCredentials.new(
62
51
  profile_name: ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE'])
@@ -65,29 +54,10 @@ module CFnDK
65
54
  nil
66
55
  end
67
56
 
68
- def process_credentials(options)
69
- profile_name = options[:config].profile if options[:config]
70
- profile_name ||= ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE']
71
-
72
- config = ::Aws.shared_config
73
- if config.config_enabled? && process_provider = config.credentials_process(profile_name)
74
- ::Aws::ProcessCredentials.new(process_provider)
75
- else
76
- nil
77
- end
78
- rescue ::Aws::Errors::NoSuchProfileError
79
- nil
80
- end
81
-
82
57
  def assume_role_credentials(options)
83
58
  if ::Aws.shared_config.config_enabled?
84
59
  profile = nil
85
60
  region = nil
86
- if options[:config]
87
- profile = options[:config].profile
88
- region = options[:config].region
89
- assume_role_with_profile(options[:config].profile, options[:config].region)
90
- end
91
61
  assume_role_with_profile(profile, region)
92
62
  else
93
63
  nil
@@ -106,7 +76,7 @@ module CFnDK
106
76
  ::Aws.shared_config.assume_role_credentials_from_config(
107
77
  profile: prof,
108
78
  region: region,
109
- chain_config: @config
79
+ chain_config: nil
110
80
  )
111
81
  end
112
82
  end
@@ -0,0 +1,10 @@
1
+ module CFnDK
2
+ module CredentialResolvable
3
+ private
4
+
5
+ def resolve_credential(data, option)
6
+ global_config = CFnDK::GlobalConfig.new(data, option)
7
+ CFnDK::CredentialProviderChain.new(global_config.profile).resolve
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,38 @@
1
+ module CFnDK
2
+ FORMAT = :unified
3
+ LINES = 3
4
+
5
+ def self.diff(data_old, data_new)
6
+ result = ''
7
+
8
+ file_length_difference = 0
9
+
10
+ data_old = data_old.split($/).map { |e| e.chomp }
11
+ data_new = data_new.split($/).map { |e| e.chomp }
12
+
13
+ diffs = Diff::LCS.diff(data_old, data_new)
14
+ diffs = nil if diffs.empty?
15
+
16
+ return '' unless diffs
17
+
18
+ oldhunk = hunk = nil
19
+
20
+ diffs.each do |piece|
21
+ begin
22
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, LINES, file_length_difference)
23
+ file_length_difference = hunk.file_length_difference
24
+
25
+ next unless oldhunk
26
+ next if LINES.positive? and hunk.merge(oldhunk)
27
+
28
+ result << oldhunk.diff(FORMAT) << "\n"
29
+ ensure
30
+ oldhunk = hunk
31
+ end
32
+ end
33
+
34
+ last = oldhunk.diff(FORMAT)
35
+ last << "\n" if last.respond_to?(:end_with?) && !last.end_with?("\n")
36
+ result << last
37
+ end
38
+ end
@@ -1,16 +1,46 @@
1
1
  module CFnDK
2
2
  class GlobalConfig
3
- attr_reader :timeout_in_minutes, :s3_template_bucket, :s3_template_hash, :region, :role_arn
3
+ attr_reader :timeout_in_minutes, :s3_template_bucket, :s3_template_hash, :region, :role_arn, :package, :profile, :pre_command, :post_command
4
4
  def initialize(data, option)
5
5
  @timeout_in_minutes = 1
6
6
  @s3_template_bucket = 'cfndk-templates'
7
- @s3_template_hash = SecureRandom.uuid
7
+ @s3_template_hash = Uuid.instance.uuid
8
8
  @region = ENV['AWS_REGION'] || 'us-east-1'
9
+ @package = false
10
+ @profile = ENV['AWS_PROFILE'] || nil
9
11
  return unless data['global'].is_a?(Hash)
10
12
  @timeout_in_minutes = data['global']['timeout_in_minutes'] || 1
11
13
  @s3_template_bucket = data['global']['s3_template_bucket'] || 'cfndk-templates'
12
14
  @region = data['global']['region'] || ENV['AWS_REGION'] || 'us-east-1'
15
+ @package = data['global']['package'] === 'true' ? true : false
13
16
  @role_arn = data['global']['role_arn'] || nil
17
+ @profile = ENV['AWS_PROFILE'] || data['global']['default_profile'] || nil
18
+ @pre_command = data['global']['pre_command'] || nil
19
+ @post_command = data['global']['post_command'] || nil
20
+ end
21
+
22
+ def pre_command_execute
23
+ if @pre_command
24
+ CFnDK.logger.info(('execute global pre command: ' + @pre_command).color(:green))
25
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
26
+ io.each_line do |line|
27
+ CFnDK.logger.info((line).color(:green))
28
+ end
29
+ end
30
+ raise 'global pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
31
+ end
32
+ end
33
+
34
+ def post_command_execute
35
+ if @post_command
36
+ CFnDK.logger.info(('execute global post command: ' + @post_command).color(:green))
37
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
38
+ io.each_line do |line|
39
+ CFnDK.logger.info((line).color(:green))
40
+ end
41
+ end
42
+ raise 'global post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
43
+ end
14
44
  end
15
45
  end
16
46
  end
@@ -1,17 +1,22 @@
1
1
  module CFnDK
2
2
  class KeyPair
3
- attr_reader :key_file
3
+ attr_reader :key_file, :enabled, :pre_command, :post_command
4
4
  def initialize(name, data, option, global_config, credentials)
5
5
  @global_config = global_config
6
6
  @name = name
7
7
  data = {} unless data
8
8
  @key_file = data['key_file'] || nil
9
9
  @region = data['region'] || @global_config.region
10
+ @pre_command = data['pre_command'] || nil
11
+ @post_command = data['post_command'] || nil
12
+ @enabled = true
13
+ @enabled = false if data['enabled'] === false
10
14
  @option = option
11
15
  @client = Aws::EC2::Client.new(credentials: credentials, region: @region)
12
16
  end
13
17
 
14
18
  def create
19
+ return unless @enabled
15
20
  CFnDK.logger.info(('creating keypair: ' + name).color(:green))
16
21
  key_pair = @client.create_key_pair(
17
22
  key_name: name
@@ -22,6 +27,7 @@ module CFnDK
22
27
  end
23
28
 
24
29
  def destroy
30
+ return unless @enabled
25
31
  if exists?
26
32
  CFnDK.logger.info(('deleting keypair: ' + name).color(:green))
27
33
  @client.delete_key_pair(
@@ -51,6 +57,32 @@ module CFnDK
51
57
  @name
52
58
  end
53
59
 
60
+ def pre_command_execute
61
+ return unless @enabled
62
+ if @pre_command
63
+ CFnDK.logger.info(('execute pre command: ' + @pre_command).color(:green))
64
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
65
+ io.each_line do |line|
66
+ CFnDK.logger.info((line).color(:green))
67
+ end
68
+ end
69
+ raise 'pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
70
+ end
71
+ end
72
+
73
+ def post_command_execute
74
+ return unless @enabled
75
+ if @post_command
76
+ CFnDK.logger.info(('execute post command: ' + @post_command).color(:green))
77
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
78
+ io.each_line do |line|
79
+ CFnDK.logger.info((line).color(:green))
80
+ end
81
+ end
82
+ raise 'post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
83
+ end
84
+ end
85
+
54
86
  private
55
87
 
56
88
  def create_key_file(key_pair)
@@ -2,6 +2,8 @@ module CFnDK
2
2
  class KeyPairCommand < Thor
3
3
  include SubcommandHelpReturnable
4
4
  include ConfigFileLoadable
5
+ include CredentialResolvable
6
+
5
7
  class_option :verbose, type: :boolean, aliases: 'v', desc: 'More verbose output.'
6
8
  class_option :color, type: :boolean, default: true, desc: 'Use colored output'
7
9
  class_option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
@@ -13,10 +15,15 @@ module CFnDK
13
15
  def create
14
16
  CFnDK.logger.info 'create...'.color(:green)
15
17
  data = load_config_data(options)
16
-
17
- credentials = CFnDK::CredentialProviderChain.new.resolve
18
+ credentials = resolve_credential(data, options)
19
+ global_config = CFnDK::GlobalConfig.new(data, options)
18
20
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
21
+
22
+ global_config.pre_command_execute
23
+ keypairs.pre_command_execute
19
24
  keypairs.create
25
+ keypairs.post_command_execute
26
+ global_config.post_command_execute
20
27
  return 0
21
28
  rescue => e
22
29
  CFnDK.logger.error "#{e.class}: #{e.message}".color(:red)
@@ -31,8 +38,8 @@ module CFnDK
31
38
  def destroy
32
39
  CFnDK.logger.info 'destroy...'.color(:green)
33
40
  data = load_config_data(options)
41
+ credentials = resolve_credential(data, options)
34
42
 
35
- credentials = CFnDK::CredentialProviderChain.new.resolve
36
43
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
37
44
 
38
45
  if options[:force] || yes?('Are you sure you want to destroy? (y/n)', :yellow)
@@ -21,6 +21,18 @@ module CFnDK
21
21
  end
22
22
  end
23
23
 
24
+ def pre_command_execute
25
+ @keypairs.each_value do |keypair|
26
+ keypair.pre_command_execute
27
+ end
28
+ end
29
+
30
+ def post_command_execute
31
+ @keypairs.each_value do |keypair|
32
+ keypair.post_command_execute
33
+ end
34
+ end
35
+
24
36
  private
25
37
 
26
38
  def prepare_keypairs(data)
@@ -1,6 +1,6 @@
1
1
  module CFnDK
2
2
  class Stack
3
- attr_reader :template_file, :parameter_input, :capabilities, :depends, :timeout_in_minutes, :region, :role_arn
3
+ attr_reader :template_file, :parameter_input, :capabilities, :depends, :timeout_in_minutes, :region, :role_arn, :package, :enabled, :pre_command, :post_command
4
4
  def initialize(name, data, option, global_config, credentials)
5
5
  @global_config = global_config
6
6
  @name = name
@@ -10,16 +10,23 @@ module CFnDK
10
10
  @depends = data['depends'] || []
11
11
  @region = data['region'] || @global_config.region
12
12
  @role_arn = @global_config.role_arn
13
+ @package = data['package'] || @global_config.package
14
+ @pre_command = data['pre_command'] || nil
15
+ @post_command = data['post_command'] || nil
16
+ @enabled = true
17
+ @enabled = false if data['enabled'] === false
13
18
  @timeout_in_minutes = data['timeout_in_minutes'] || @global_config.timeout_in_minutes
14
19
  @override_parameters = data['parameters'] || {}
15
20
  @option = option
16
21
  @client = Aws::CloudFormation::Client.new(credentials: credentials, region: @region)
17
22
  @s3_client = Aws::S3::Client.new(credentials: credentials, region: @region)
18
23
  @sts_client = Aws::STS::Client.new(credentials: credentials, region: @region)
24
+ @tp = CFnDK::TemplatePackager.new(@template_file, @region, @package, @global_config, @s3_client, @sts_client)
19
25
  end
20
26
 
21
27
  def create
22
28
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
29
+ return unless @enabled
23
30
  CFnDK.logger.info(('creating stack: ' + name).color(:green))
24
31
  CFnDK.logger.debug('Name :' + name)
25
32
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
@@ -44,10 +51,11 @@ module CFnDK
44
51
  tags: tags,
45
52
  }
46
53
  hash[:role_arn] = @role_arn if @role_arn
47
- if large_template?
48
- hash[:template_url] = upload_template_file()
54
+
55
+ if @tp.large_template?
56
+ hash[:template_url] = @tp.upload_template_file()
49
57
  else
50
- hash[:template_body] = template_body()
58
+ hash[:template_body] = @tp.template_body()
51
59
  end
52
60
  @client.create_stack(
53
61
  hash
@@ -56,6 +64,7 @@ module CFnDK
56
64
 
57
65
  def wait_until_create
58
66
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
67
+ return unless @enabled
59
68
  CFnDK.logger.info(('waiting create stack: ' + name).color(:green))
60
69
  begin
61
70
  @client.wait_until(
@@ -76,6 +85,7 @@ module CFnDK
76
85
 
77
86
  def update
78
87
  return false if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
88
+ return unless @enabled
79
89
  CFnDK.logger.info(('updating stack: ' + name).color(:green))
80
90
  CFnDK.logger.debug('Name :' + name)
81
91
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
@@ -89,10 +99,10 @@ module CFnDK
89
99
  capabilities: capabilities,
90
100
  }
91
101
  hash[:role_arn] = @role_arn if @role_arn
92
- if large_template?
93
- hash[:template_url] = upload_template_file()
102
+ if @tp.large_template?
103
+ hash[:template_url] = @tp.upload_template_file()
94
104
  else
95
- hash[:template_body] = template_body()
105
+ hash[:template_body] = @tp.template_body()
96
106
  end
97
107
  @client.update_stack(
98
108
  hash
@@ -111,6 +121,7 @@ module CFnDK
111
121
 
112
122
  def wait_until_update
113
123
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
124
+ return unless @enabled
114
125
  CFnDK.logger.info(('waiting update stack: ' + name).color(:green))
115
126
  @client.wait_until(
116
127
  :stack_update_complete,
@@ -124,6 +135,7 @@ module CFnDK
124
135
 
125
136
  def destroy
126
137
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
138
+ return unless @enabled
127
139
  if exits?
128
140
  CFnDK.logger.info(('deleting stack: ' + name).color(:green))
129
141
  CFnDK.logger.debug('Name :' + name)
@@ -142,6 +154,7 @@ module CFnDK
142
154
 
143
155
  def wait_until_destroy
144
156
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
157
+ return unless @enabled
145
158
  return unless exits?
146
159
  CFnDK.logger.info(('waiting delete stack: ' + name).color(:green))
147
160
  @client.wait_until(
@@ -156,6 +169,7 @@ module CFnDK
156
169
 
157
170
  def create_change_set
158
171
  return nil if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
172
+ return unless @enabled
159
173
  CFnDK.logger.info(('creating change set: ' + change_set_name).color(:green))
160
174
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
161
175
  CFnDK.logger.debug('Capabilities:' + capabilities.inspect)
@@ -183,10 +197,10 @@ module CFnDK
183
197
  tags: tags,
184
198
  }
185
199
  hash[:role_arn] = @role_arn if @role_arn
186
- if large_template?
187
- hash[:template_url] = upload_template_file()
200
+ if @tp.large_template?
201
+ hash[:template_url] = @tp.upload_template_file()
188
202
  else
189
- hash[:template_body] = template_body()
203
+ hash[:template_body] = @tp.template_body()
190
204
  end
191
205
  @client.create_change_set(
192
206
  hash
@@ -204,6 +218,7 @@ module CFnDK
204
218
 
205
219
  def wait_until_create_change_set
206
220
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
221
+ return unless @enabled
207
222
  return unless exits?
208
223
  CFnDK.logger.info(('waiting create change set: ' + change_set_name).color(:green))
209
224
  @client.wait_until(
@@ -229,6 +244,7 @@ module CFnDK
229
244
 
230
245
  def execute_change_set
231
246
  return nil if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
247
+ return unless @enabled
232
248
  if available_change_set?
233
249
  CFnDK.logger.info(('executing change set: ' + change_set_name).color(:green))
234
250
  @client.execute_change_set(
@@ -245,6 +261,7 @@ module CFnDK
245
261
 
246
262
  def delete_change_set
247
263
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
264
+ return unless @enabled
248
265
  CFnDK.logger.info(('deleting change set: ' + change_set_name).color(:green))
249
266
  @client.delete_change_set(
250
267
  stack_name: name,
@@ -255,6 +272,7 @@ module CFnDK
255
272
 
256
273
  def report_change_set
257
274
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
275
+ return unless @enabled
258
276
  CFnDK.logger.info('*****************************************************'.color(:green))
259
277
  CFnDK.logger.info(('change set: ' + change_set_name).color(:green))
260
278
  CFnDK.logger.info('*****************************************************'.color(:green))
@@ -318,13 +336,14 @@ module CFnDK
318
336
 
319
337
  def validate
320
338
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
339
+ return unless @enabled
321
340
  CFnDK.logger.info(('validate stack: ' + name).color(:green))
322
341
  CFnDK.logger.debug('Name :' + @name)
323
342
  hash = {}
324
- if large_template?
325
- hash[:template_url] = upload_template_file()
343
+ if @tp.large_template?
344
+ hash[:template_url] = @tp.upload_template_file()
326
345
  else
327
- hash[:template_body] = template_body()
346
+ hash[:template_body] = @tp.template_body()
328
347
  end
329
348
  @client.validate_template(
330
349
  hash
@@ -373,6 +392,7 @@ module CFnDK
373
392
 
374
393
  def report
375
394
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
395
+ return unless @enabled
376
396
  CFnDK.logger.info('*****************************************************'.color(:green))
377
397
  CFnDK.logger.info(('stack: ' + name).color(:green))
378
398
  CFnDK.logger.info('*****************************************************'.color(:green))
@@ -484,14 +504,6 @@ module CFnDK
484
504
  [@name, @option[:change_set_uuid]].compact.join('-')
485
505
  end
486
506
 
487
- def template_body
488
- File.open(@template_file, 'r').read
489
- end
490
-
491
- def large_template?
492
- File.size(@template_file) > 51200
493
- end
494
-
495
507
  def parameters
496
508
  json = JSON.load(open(@parameter_input).read)
497
509
  json['Parameters'].map do |item|
@@ -503,49 +515,36 @@ module CFnDK
503
515
  end.compact
504
516
  end
505
517
 
506
- private
507
-
508
- def upload_template_file
509
- begin
510
- @s3_client.head_bucket(bucket: bucket_name)
511
- rescue Aws::S3::Errors::NotFound, Aws::S3::Errors::Forbidden
512
- @s3_client.create_bucket(bucket: bucket_name)
513
- CFnDK.logger.info('Creatt S3 bucket: ' + bucket_name)
514
- @s3_client.put_bucket_lifecycle_configuration(
515
- bucket: bucket_name,
516
- lifecycle_configuration: {
517
- rules: [
518
- {
519
- expiration: {
520
- days: 1,
521
- },
522
- status: 'Enabled',
523
- id: 'Delete Old Files',
524
- prefix: '',
525
- abort_incomplete_multipart_upload: {
526
- days_after_initiation: 1,
527
- },
528
- },
529
- ],
530
- }
531
- )
518
+ def pre_command_execute
519
+ return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
520
+ return unless @enabled
521
+ if @pre_command
522
+ CFnDK.logger.info(('execute pre command: ' + @pre_command).color(:green))
523
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
524
+ io.each_line do |line|
525
+ CFnDK.logger.info((line).color(:green))
526
+ end
527
+ end
528
+ raise 'pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
532
529
  end
533
- key = [@global_config.s3_template_hash, @template_file].compact.join('/')
534
- @s3_client.put_object(
535
- body: template_body,
536
- bucket: bucket_name,
537
- key: key
538
- )
539
- url = "https://s3.amazonaws.com/#{bucket_name}/#{key}"
540
- CFnDK.logger.info('Put S3 object: ' + url)
541
- url
542
530
  end
543
531
 
544
- def bucket_name
545
- resp = @sts_client.get_caller_identity({})
546
- resp.account + '-' + @region + '-' + @global_config.s3_template_bucket
532
+ def post_command_execute
533
+ return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
534
+ return unless @enabled
535
+ if @post_command
536
+ CFnDK.logger.info(('execute post command: ' + @post_command).color(:green))
537
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
538
+ io.each_line do |line|
539
+ CFnDK.logger.info((line).color(:green))
540
+ end
541
+ end
542
+ raise 'post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
543
+ end
547
544
  end
548
545
 
546
+ private
547
+
549
548
  def colored_status(str)
550
549
  case str
551
550
  when 'CREATE_FAILED' then