cfndk 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8bc91fcc47784316274ae3615941dcf15bdacd29
4
- data.tar.gz: 5bca96e74b5166f921b8d8c0a24dec0024d99f90
3
+ metadata.gz: 566120c36a4fa9b6267bdf60fa537cc542246b34
4
+ data.tar.gz: 1ba3f83d708122867135ba13bcd5fa5dab3be1a3
5
5
  SHA512:
6
- metadata.gz: 760f92e0e910445531c334e368932e6f0a96711c76bf5ffd63ff60f926bb50d6ba28ad418daf41ba5af4ac7790e1e932728038d17a2ac95cb4120d1e02abd063
7
- data.tar.gz: e58c1ab2a5a18cb27ae1a5a857ccccf095f5fc8168055ff3bd8be26e62f0a181540a85dfddca15eb6c632014637ab40062bbccdf658c338c2e5def1e404d6542
6
+ metadata.gz: 3971374374b13a9834974dc6f68221d7b42bfa9cd77d8efcfca557ad02c1c29c1644b2235fe47176c10b5ba6b351e77d9883036a2b7f45b242af657d17a31808
7
+ data.tar.gz: de54298f5cc8ca0b591709ab100c3749a036d6dab5ec80382aeaad1c66166f0fbacdaf6d2ae71fc162341035bd82e4751c1d79ee3ec85ca533a023fbda34074d
@@ -0,0 +1,68 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ test:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.4.1-node-browsers
11
+
12
+ # Specify service dependencies here if necessary
13
+ # CircleCI maintains a library of pre-built images
14
+ # documented at https://circleci.com/docs/2.0/circleci-images/
15
+ # - image: circleci/postgres:9.4
16
+ parallelism: 1
17
+ working_directory: ~/repo
18
+
19
+ steps:
20
+ - checkout
21
+
22
+ # Download and cache dependencies
23
+ - restore_cache:
24
+ keys:
25
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
26
+ # fallback to using the latest cache if no exact match is found
27
+ - v1-dependencies-
28
+
29
+ - run:
30
+ name: install dependencies
31
+ command: |
32
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
33
+
34
+ - save_cache:
35
+ paths:
36
+ - ./vendor/bundle
37
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
38
+
39
+ # run tests!
40
+ - run:
41
+ name: run tests
42
+ command: |
43
+ export AWS_REGION=ap-northeast-1
44
+ CFNDK_COVERAGE=1 bundle exec rspec \
45
+ --format p \
46
+ --format html \
47
+ --out /tmp/test-results/rspec.html
48
+
49
+ # collect reports
50
+ - store_test_results:
51
+ path: /tmp/test-results
52
+ - store_artifacts:
53
+ path: /tmp/test-results
54
+ destination: test-results
55
+ - store_test_results:
56
+ path: ~/repo/coverage
57
+ - store_artifacts:
58
+ path: ~/repo/coverage
59
+ destination: test-coverage
60
+ workflows:
61
+ version: 2
62
+ my_workflow:
63
+ jobs:
64
+ - HOLD-TEST:
65
+ type: approval
66
+ - test:
67
+ requires:
68
+ - HOLD-TEST
@@ -0,0 +1,9 @@
1
+ SimpleCov.merge_timeout 7200
2
+ SimpleCov.command_name "rspec_#{Process.pid.to_s}"
3
+
4
+ SimpleCov.start do
5
+ add_filter 'spec'
6
+ add_filter '.simplecov'
7
+
8
+ add_group 'Libraries', 'lib'
9
+ end
data/Gemfile CHANGED
@@ -1,4 +1,13 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in xpub.gemspec
4
3
  gemspec
4
+
5
+ group :development, :test do
6
+ gem 'rake'
7
+ # Code Coverage
8
+ gem 'simplecov'
9
+ # Test api
10
+ gem 'rspec'
11
+ gem 'aruba'
12
+ gem 'awspec'
13
+ end
data/README.md CHANGED
@@ -6,8 +6,8 @@ This is easy operation/integration support tool for AWS CloudFormation.
6
6
 
7
7
  kumogata, SparkleFormation, CoffeeFormation など、CloudFormationのテンプレートを書かずにDSLで表現するツールには様々な物があります。
8
8
  しかし、これらのツールはサードパーティツールであるため、CloudFormationの対応への追従に不安がのこります。
9
- 本ツールは、標準のCloudFromationテンプレートの枠組みを変えずに、その利用を支援するツールとなっています。
10
- 最悪このツールが使えなくなっても僅かなコストで標準のAWS CLIを使ってオペレーションを続行することが可能です。
9
+ 本ツールは、標準のCloudFromationテンプレートの枠組みを変えずに、その利用を支援するツールをを目指しています。
10
+ 最悪の場合、このツールが使えなくなっても僅かなコストで標準のAWS CLIを使いオペレーションを続行することが可能です
11
11
 
12
12
  ## ハイライト
13
13
 
@@ -15,6 +15,7 @@ kumogata, SparkleFormation, CoffeeFormation など、CloudFormationのテンプ
15
15
  * 複数のスタックの依存関係を考慮した操作
16
16
  * CloudFormationでバージョンコントロールシステムと連動した継続的インテグレーションのための基盤対応
17
17
  * Keypairの作成/削除
18
+ * コマンド、サブコマンド、冪統性を考慮したコマンドライン体系、オプションの整理、ヘルプの追加
18
19
 
19
20
  ## インストール
20
21
 
@@ -31,7 +32,7 @@ $ cfndk init
31
32
  $ export AWS_REGION=ap-northeast-1
32
33
  $ export AWS_PROFILE=default
33
34
  $ cfndk create
34
- $ cfndk report-event
35
+ $ cfndk report
35
36
  $ cfndk destroy -f
36
37
  ```
37
38
 
@@ -52,55 +53,30 @@ $ cfndk destroy -f
52
53
 
53
54
  ## コマンド
54
55
 
55
- ```
56
- cfndk [cmd] [options]
57
- ```
58
-
59
- ### [cmd]
60
-
61
- #### ```init```
62
-
63
- カレントディレクトリにcfndk.yamlのひな形を作成します。
56
+ ### ```init```
64
57
 
65
- ```
66
- cfndk init [option]
67
- ```
68
-
69
- #### ```create```
70
-
71
- cfndk.yamlで定義されているスタックを作成します。
58
+ カレントディレクトリにcfndk.ymlのひな形を作成します。
72
59
 
73
60
  ```
74
- cfndk create [option]
61
+ cfndk init
75
62
  ```
76
63
 
77
- #### ```update```
78
-
79
- cfndk.yamlで定義されているスタックを更新します。
64
+ ### ```create```
80
65
 
81
- ```
82
- cfndk update [option]
83
- ```
84
-
85
- #### ```create-or-changeset```
66
+ cfndk.ymlで定義されているスタックを作成します。
86
67
 
87
- cfndk.yamlで定義されているスタックが存在しない場合は作成を、存在する場合はチェンジセットを作成します。
88
- チェンジセットの実行は行いません。
89
- コマンドを実行後に手動で実行する必要があります。
68
+ ```cfndk create [option]```
90
69
 
91
- ```
92
- cfndk create-or-changeset [option]
93
- ```
94
70
 
95
- #### ```destroy```
71
+ ### ```destroy```
96
72
 
97
- cfndk.yamlで定義されているスタックを削除します。
73
+ cfndk.ymlで定義されているスタックを削除します。
98
74
 
99
75
  ```
100
76
  cfndk destroy [option]
101
77
  ```
102
78
 
103
- #### ```generate-uuid```
79
+ ### ```generate-uuid```
104
80
 
105
81
  UUIDを生成して標準出力に出力します。
106
82
 
@@ -117,32 +93,12 @@ cfndk destroy
117
93
  unset CFNDK_UUID
118
94
  ```
119
95
 
120
- #### ```validate```
121
-
122
- cfndk.yamlで定義されているスタックのテンプレートをvalidationします。
123
-
124
- #### ```report-event```
125
-
126
- cfndk.yamlで定義されているスタックのイベント情報をレポートします。
127
-
128
- ```
129
- cfndk report-event [option]
130
- ```
131
-
132
- #### ```report-stack```
133
-
134
- cfndk.yamlで定義されているスタックの情報をレポートします。
135
-
136
- ```
137
- cfndk report-stack [option]
138
- ```
139
-
140
- #### ```report-stack-resource```
96
+ ### ```report```
141
97
 
142
- cfndk.yamlで定義されているスタックのリソース情報をレポートします。
98
+ cfndk.ymlで定義されているスタックについてレポートします。
143
99
 
144
100
  ```
145
- cfndk report-stack-resource [option]
101
+ cfndk report [option]
146
102
  ```
147
103
 
148
104
  ### [option]
@@ -151,33 +107,31 @@ cfndk report-stack-resource [option]
151
107
 
152
108
  実行時に詳細な情報を表示します。
153
109
 
154
- #### ```-c, --config_path cfndi.yml```
110
+ #### ```-c, --config-path=cfndk.yml```
155
111
 
156
112
  カレントディレクトリのcfndi.ymlの代わりに、ファイルを指定します。
157
113
 
158
- #### ```-p, --properties name=value```
114
+ #### ```-p, --properties=name:value```
159
115
 
160
116
  プロパティを追加します。
161
117
  cfndi.ymlのparametersのerb内で値で参照することができます。
162
118
 
163
- #### ```-a, --auto-uuid```
164
-
165
- UUIDを自動生成し使用します。
166
- UUIDが指定されるとスタック名に付加されます。
167
- またcfndi.ymlのparametersの値で参照することができます。
168
- ```-a```と```-u```は最後に指定されたものが有効になります。
169
-
170
119
  #### ```-u, --uuid uuid```
171
120
 
172
121
  指定されたUUIDを使用します。
173
122
  UUIDが指定されるとスタック名に付加されます。
174
123
  またcfndi.ymlのparametersの値で参照することができます。
175
- ```-a```と```-u```は最後に指定されたものが有効になります。
124
+ ```-u```は最後に指定されたものが有効になります。
176
125
 
177
- #### ```-s, --stack-names name1,name2```
126
+ #### ```--stack-names=name1 name2```
178
127
 
179
128
  指定されたスタック名のみを操作します。
180
129
 
130
+ #### ```--keypair-names=name1 name2```
131
+
132
+ 指定されたキーペア名のみを操作します。
133
+
134
+
181
135
  #### ```--no-color```
182
136
 
183
137
  メッセージ出力でカラーを抑制します。
@@ -191,10 +145,10 @@ UUIDが指定されるとスタック名に付加されます。
191
145
  ### ```CFNDK_UUID```
192
146
 
193
147
  この環境変数が指定されている場合、```--uuid $CFNDK_UUID```が指定されたものとして動作します。
194
- ```-a```や```-u```のほうが優先されます。
148
+ ```-u```のほうが優先されます。
195
149
 
196
150
 
197
- ## cfndk.yaml
151
+ ## cfndk.yml
198
152
 
199
153
  * example
200
154
 
@@ -280,11 +234,11 @@ UUIDを利用すると、```[Stack Original Name]-[UUID]```のような形式の
280
234
 
281
235
  #### template_file
282
236
 
283
- 必須。CloudFormationテンプレートファイルのパスをcfndk.yamlからの相対パスで指定します。
237
+ 必須。CloudFormationテンプレートファイルのパスをcfndk.ymlからの相対パスで指定します。
284
238
 
285
239
  #### parameter_input
286
240
 
287
- 必須。CloudFormationのパラメータJSONファイルをcfndk.yamlからの相対パスで指定します。
241
+ 必須。CloudFormationのパラメータJSONファイルをcfndk.ymlからの相対パスで指定します。
288
242
 
289
243
  #### parameters
290
244
 
@@ -327,7 +281,7 @@ Parameter Valueではerbの記法が利用できます。
327
281
  スタックに依存している別のスタックを指定します。
328
282
  複数指定することができます。
329
283
  dependsを指定すると、create,update,create-or-changeset,destoryのコマンドを実行する際に、依存関係に従ってスタックを処理します。
330
- dependsが循環するような指定をすることはできません。
284
+ 存在しないタスタックやdependsが循環するような指定をすることはできません。
331
285
 
332
286
  ```
333
287
  depends:
@@ -360,3 +314,16 @@ dependsが循環するような指定をすることはできません。
360
314
  * ```properties(key)```
361
315
 
362
316
  オプション```--properties```で指定したキーに対応する値を参照することができます。
317
+
318
+
319
+ ## テスト
320
+
321
+ cfndkコマンドのテストを行うことができます。
322
+ CFNDK_COVERAGE環境変数に1を設定することで、カバレッジを取ることができます。
323
+
324
+ ```
325
+ export AWS_REGION=ap-northeast-1
326
+ export AWS_PROFILE=default
327
+ export CFNDK_COVERAGE=1
328
+ bundle exec rspec
329
+ ```
data/bin/cfndk CHANGED
@@ -1,22 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler/setup'
4
-
5
- require 'rainbow/ext/string'
6
- require 'optparse'
7
- require 'fileutils'
8
- require 'pathname'
9
- require 'erb'
10
- require 'yaml'
11
- require 'json'
12
- require 'aws-sdk'
13
- require 'terminal-table'
14
- require 'securerandom'
15
- require 'logger'
16
-
17
- require 'cfndk.rb'
18
-
19
3
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
20
4
 
21
- c = CFnDK::Command.new
22
- exit c.execute
5
+ require 'cfndk'
6
+
7
+ exit CFnDK::Command.start(ARGV)
@@ -18,11 +18,16 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency 'bundler', '~> 1.7'
22
- spec.add_development_dependency 'rake', '~> 11.1.2'
21
+ spec.add_development_dependency 'bundler'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'aruba'
25
+ spec.add_development_dependency 'simplecov'
26
+ spec.add_development_dependency 'awspec'
23
27
 
24
- spec.add_dependency 'rainbow', '~> 3.0.0'
25
- spec.add_dependency 'aws-sdk', '~> 3'
26
- spec.add_dependency 'camelizable', '~> 0.0.3'
27
- spec.add_dependency 'terminal-table', '~> 1'
28
+ spec.add_dependency 'thor'
29
+ spec.add_dependency 'rainbow'
30
+ spec.add_dependency 'aws-sdk'
31
+ spec.add_dependency 'camelizable'
32
+ spec.add_dependency 'terminal-table'
28
33
  end
@@ -1,3 +1,24 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'rainbow/ext/string'
4
+ require 'camelizable'
5
+ require 'fileutils'
6
+ require 'pathname'
7
+ require 'erb'
8
+ require 'yaml'
9
+ require 'json'
10
+ require 'aws-sdk'
11
+ require 'terminal-table'
12
+ require 'securerandom'
13
+ require 'logger'
14
+ require 'thor'
15
+
16
+ if ENV['CFNDK_COVERAGE']
17
+ require 'simplecov'
18
+ root = File.expand_path('../../', __FILE__)
19
+ SimpleCov.root(root)
20
+ end
21
+
1
22
  require 'cfndk/version'
2
23
  require 'cfndk/stack'
3
24
  require 'cfndk/stacks'
@@ -1,136 +1,300 @@
1
1
  module CFnDK
2
- class Command
3
- def initialize
4
- @cur_dir = Dir.getwd
5
- @option = {
6
- config_path: "#{@cur_dir}/cfndk.yml",
7
- uuid: ENV['CFNDK_UUID'] || nil,
8
- properties: {},
9
- stack_names: nil,
10
- force: false,
11
- }
12
-
13
- @opt = OptionParser.new do |o|
14
- o.version = CFnDK::VERSION
15
- o.summary_indent = ' ' * 4
16
- o.banner = "Version: #{CFnDK::VERSION} \nUsage: cfndk [cmd] [options]"
17
- o.on_head('[cmd]',
18
- ' init create config YAML file',
19
- ' create create stacks',
20
- ' update update stacks',
21
- ' create-or-changeset create stacks or create changeset',
22
- ' destroy destroy stacks',
23
- ' generate-uuid generate UUID',
24
- ' report-event report stack event',
25
- ' report-stack report stack',
26
- ' report-stack-resource report stack resource',
27
- '[enviroment variables]',
28
- " AWS_PROFILE: #{ENV['AWS_PROFILE']}",
29
- " AWS_DEFAULT_REGION: #{ENV['AWS_DEFAULT_REGION']}",
30
- " AWS_REGION: #{ENV['AWS_REGION']}",
31
- " AWS_ACCESS_KEY_ID: #{ENV['AWS_ACCESS_KEY_ID']}",
32
- " AWS_SECRET_ACCESS_KEY: #{ENV['AWS_SECRET_ACCESS_KEY']}",
33
- " AWS_SESSION_TOKEN: #{ENV['AWS_SECRET_ACCESS_KEY']}",
34
- " AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: #{ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI']}",
35
- '[options]')
36
- o.on('-v', '--verbose', 'verbose mode') { |v| @option[:v] = v }
37
- o.on('-c', '--config_path cfndi.yml', "config path (default: #{@option[:config_path]})") { |v| @option[:config_path] = v }
38
- o.on('-p', '--properties name=value', 'properties') do |v|
39
- md = v.match(/^([a-zA-Z_]+[a-zA-Z0-9_]*)=(.*)$/)
40
- if md
41
- @option[:properties][md[0]] = md[1]
42
- else
43
- raise "invalid properties: '#{v}'" unless md
44
- end
45
- end
46
- o.on('-a', '--auto-uuid') { @option[:uuid] = SecureRandom.uuid }
47
- o.on('-u', '--uuid uuid') { |v| @option[:uuid] = v }
48
- o.on('-n', '--stack-names name1,name2') { |v| @option[:stack_names] = v.split(/\s*,\s*/) }
49
- o.on('--no-color') { |b| Rainbow.enabled = false }
50
- o.on('-f', '--force') { |b| @option[:force] = true }
51
- o.permute!(ARGV)
2
+ module SubcommandHelpReternable
3
+ module ClassMethods
4
+ def subcommand_help(cmd)
5
+ desc 'help [COMMAND]', 'Describe subcommands or one specific subcommand'
6
+ class_eval "
7
+ def help(command = nil, subcommand = true); super; return 2; end
8
+ "
52
9
  end
53
- @logger = CFnDK::Logger.new(@option)
54
10
  end
11
+ extend ClassMethods
12
+ def self.included(klass)
13
+ klass.extend ClassMethods
14
+ end
15
+ end
55
16
 
56
- def execute
57
- if ARGV.length != 1
58
- puts @opt.help
59
- return 2
60
- elsif ARGV[0] == 'generate-uuid'
61
- puts SecureRandom.uuid
17
+ module ConfigFileLoadable
18
+ private
19
+
20
+ def load_config_data(options)
21
+ raise "File does not exist. #{options[:config_path]}" unless File.file?(options[:config_path])
22
+ data = open(options[:config_path], 'r') { |f| YAML.load(f) }
23
+ return data if data
24
+ CFnDK.logger.error "File is empty. #{options[:config_path]}".color(:red)
25
+ nil
26
+ end
27
+ end
28
+
29
+ class KeyPairCommand < Thor
30
+ include SubcommandHelpReternable
31
+ include ConfigFileLoadable
32
+ class_option :verbose, type: :boolean, aliases: 'v', desc: 'More verbose output.'
33
+ class_option :color, type: :boolean, default: true, desc: 'Use colored output'
34
+ class_option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
35
+ class_option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
36
+ class_option :keypair_names, type: :array, desc: 'Target keypair names'
37
+
38
+ desc 'create', 'Create keypair'
39
+ option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
40
+ def create
41
+ CFnDK.logger.info 'create...'.color(:green)
42
+ data = load_config_data(options)
43
+
44
+ credentials = CFnDK::CredentialProviderChain.new.resolve
45
+ keypairs = CFnDK::KeyPairs.new(data, options, credentials)
46
+ keypairs.create
47
+ return 0
48
+ rescue => e
49
+ CFnDK.logger.error e.message.color(:red)
50
+ CFnDK.logger.debug e.backtrace
51
+ return 1
52
+ end
53
+
54
+ desc 'destroy', 'Destroy keypair'
55
+ option :force, type: :boolean, aliases: 'f', default: false, desc: 'Say yes to all prompts for confirmation'
56
+ def destroy
57
+ CFnDK.logger.info 'destroy...'.color(:green)
58
+ data = load_config_data(options)
59
+
60
+ credentials = CFnDK::CredentialProviderChain.new.resolve
61
+ keypairs = CFnDK::KeyPairs.new(data, options, credentials)
62
+
63
+ if options[:force] || yes?('Are you sure you want to destroy? (y/n)', :yellow)
64
+ keypairs.destroy
62
65
  return 0
63
- elsif ARGV[0] == 'init'
64
- if File.file?(@option[:config_path])
65
- @logger.error "File exist. #{@option[:config_path]}".color(:red)
66
- return 1
67
- end
68
- @logger.info 'init...'.color(:green)
69
- FileUtils.cp_r(Dir.glob(File.dirname(__FILE__) + '/../../skel/*'), './')
70
- @logger.info "create #{@option[:config_path]}".color(:green)
66
+ else
67
+ CFnDK.logger.info 'destroy command was canceled'.color(:green)
68
+ return 2
69
+ end
70
+ rescue => e
71
+ CFnDK.logger.error e.message.color(:red)
72
+ CFnDK.logger.debug e.backtrace
73
+ return 1
74
+ end
75
+ end
76
+
77
+ class StackCommand < Thor
78
+ include SubcommandHelpReternable
79
+ include ConfigFileLoadable
80
+
81
+ class_option :verbose, type: :boolean, aliases: 'v', desc: 'More verbose output.'
82
+ class_option :color, type: :boolean, default: true, desc: 'Use colored output'
83
+ class_option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
84
+ class_option :stack_names, type: :array, desc: 'Target stack names'
85
+
86
+ desc 'create', 'Create stack'
87
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
88
+ option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
89
+ def create
90
+ CFnDK.logger.info 'create...'.color(:green)
91
+ data = load_config_data(options)
92
+
93
+ credentials = CFnDK::CredentialProviderChain.new.resolve
94
+ stacks = CFnDK::Stacks.new(data, options, credentials)
95
+ stacks.validate
96
+ stacks.create
97
+ return 0
98
+ rescue => e
99
+ CFnDK.logger.error e.message.color(:red)
100
+ CFnDK.logger.debug e.backtrace
101
+ return 1
102
+ end
103
+
104
+ desc 'update', 'Update stack'
105
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
106
+ option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
107
+ def update
108
+ CFnDK.logger.info 'update...'.color(:green)
109
+ data = load_config_data(options)
110
+
111
+ credentials = CFnDK::CredentialProviderChain.new.resolve
112
+ stacks = CFnDK::Stacks.new(data, options, credentials)
113
+ stacks.validate
114
+ stacks.update
115
+ return 0
116
+ rescue => e
117
+ CFnDK.logger.error e.message.color(:red)
118
+ CFnDK.logger.debug e.backtrace
119
+ return 1
120
+ end
121
+
122
+ desc 'destroy', 'Destroy stack'
123
+ option :force, type: :boolean, aliases: 'f', default: false, desc: 'Say yes to all prompts for confirmation'
124
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
125
+ def destroy
126
+ CFnDK.logger.info 'destroy...'.color(:green)
127
+ data = load_config_data(options)
128
+
129
+ credentials = CFnDK::CredentialProviderChain.new.resolve
130
+ stacks = CFnDK::Stacks.new(data, options, credentials)
131
+
132
+ if options[:force] || yes?('Are you sure you want to destroy? (y/n)', :yellow)
133
+ stacks.destroy
71
134
  return 0
135
+ else
136
+ CFnDK.logger.info 'destroy command was canceled'.color(:green)
137
+ return 2
72
138
  end
139
+ rescue => e
140
+ CFnDK.logger.error e.message.color(:red)
141
+ CFnDK.logger.debug e.backtrace
142
+ return 1
143
+ end
144
+
145
+ desc 'validate', 'Validate stack'
146
+ def validate
147
+ CFnDK.logger.info 'validate...'.color(:green)
148
+ data = load_config_data(options)
149
+ credentials = CFnDK::CredentialProviderChain.new.resolve
150
+ stacks = CFnDK::Stacks.new(data, options, credentials)
151
+ stacks.validate
152
+ return 0
153
+ rescue => e
154
+ CFnDK.logger.error e.message.color(:red)
155
+ CFnDK.logger.debug e.backtrace
156
+ return 1
157
+ end
158
+
159
+ desc 'report', 'Report stack'
160
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
161
+ def report
162
+ CFnDK.logger.info 'report...'.color(:green)
163
+ data = load_config_data(options)
164
+ credentials = CFnDK::CredentialProviderChain.new.resolve
165
+ stacks = CFnDK::Stacks.new(data, options, credentials)
166
+ stacks.report
167
+ return 0
168
+ rescue => e
169
+ CFnDK.logger.error e.message.color(:red)
170
+ CFnDK.logger.debug e.backtrace
171
+ return 1
172
+ end
173
+ end
174
+
175
+ class Command < Thor
176
+ include Thor::Actions
177
+ include ConfigFileLoadable
178
+ class << self
179
+ def exit_on_failure?
180
+ true
181
+ end
182
+ end
183
+
184
+ def help(command = nil, subcommand = false)
185
+ super(command, subcommand)
186
+ 2
187
+ end
188
+
189
+ class_option :verbose, type: :boolean, aliases: 'v', desc: 'More verbose output.'
190
+ class_option :color, type: :boolean, default: true, desc: 'Use colored output'
191
+
192
+ desc 'generate-uuid', 'Print UUID'
193
+ def generate_uuid
194
+ puts SecureRandom.uuid
195
+ 0
196
+ end
197
+
198
+ desc 'version', 'Print version'
199
+ def version
200
+ puts CFnDK::VERSION
201
+ 0
202
+ end
73
203
 
74
- unless File.file?(@option[:config_path])
75
- @logger.error "File does not exist. #{@option[:config_path]}".color(:red)
204
+ desc 'init', 'Craete sample cfndk.yml & CloudFormation yaml & json files.'
205
+ def init
206
+ config_path = "#{Dir.getwd}/cfndk.yml"
207
+ if File.file?(config_path)
208
+ CFnDK.logger.error "File exist. #{config_path}".color(:red)
76
209
  return 1
77
210
  end
211
+ CFnDK.logger.info 'init...'.color(:green)
212
+ FileUtils.cp_r(Dir.glob(File.dirname(__FILE__) + '/../../skel/*'), './')
213
+ CFnDK.logger.info "create #{config_path}".color(:green)
214
+ end
215
+
216
+ desc 'create', 'Create keypair & stack'
217
+ option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
218
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
219
+ option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
220
+ option :stack_names, type: :array, desc: 'Target stack names'
221
+ option :keypair_names, type: :array, desc: 'Target keypair names'
222
+ def create
223
+ CFnDK.logger.info 'create...'.color(:green)
224
+ data = load_config_data(options)
225
+
226
+ credentials = CFnDK::CredentialProviderChain.new.resolve
227
+ stacks = CFnDK::Stacks.new(data, options, credentials)
228
+ keypairs = CFnDK::KeyPairs.new(data, options, credentials)
229
+
230
+ stacks.validate
231
+ keypairs.create
232
+ stacks.create
233
+ return 0
234
+ rescue => e
235
+ CFnDK.logger.error e.message.color(:red)
236
+ CFnDK.logger.debug e.backtrace
237
+ return 1
238
+ end
239
+
240
+ desc 'destroy', 'Destroy keypair & stack'
241
+ option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
242
+ option :force, type: :boolean, aliases: 'f', default: false, desc: 'Say yes to all prompts for confirmation'
243
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
244
+ option :stack_names, type: :array, desc: 'Target stack names'
245
+ option :keypair_names, type: :array, desc: 'Target keypair names'
246
+ def destroy
247
+ CFnDK.logger.info 'destroy...'.color(:green)
248
+ data = load_config_data(options)
78
249
 
79
- data = open(@option[:config_path], 'r') { |f| YAML.load(f) } if File.file?(@option[:config_path])
80
250
  credentials = CFnDK::CredentialProviderChain.new.resolve
81
- stacks = CFnDK::Stacks.new(data, @option, credentials)
82
- keypairs = CFnDK::KeyPairs.new(data, @option, credentials)
83
-
84
- if ARGV[0] == 'create'
85
- @logger.info 'create...'.color(:green)
86
- stacks.validate
87
- keypairs.create
88
- stacks.create
89
- elsif ARGV[0] == 'update'
90
- @logger.info 'update...'.color(:green)
91
- stacks.validate
92
- stacks.update
93
- elsif ARGV[0] == 'create-or-changeset'
94
- @logger.info 'create or changeset...'.color(:green)
95
- stacks.validate
96
- stacks.create_or_changeset
97
- elsif ARGV[0] == 'destroy'
98
- @logger.info 'destroy...'.color(:green)
99
- if destroy?
100
- stacks.destroy
101
- keypairs.destroy
102
- end
103
- elsif ARGV[0] == 'validate'
104
- @logger.info 'validate...'.color(:green)
105
- stacks.validate
106
- elsif ARGV[0] == 'report-event'
107
- @logger.info 'report event...'.color(:green)
108
- stacks.report_event
109
- elsif ARGV[0] == 'report-stack'
110
- @logger.info 'report stack...'.color(:green)
111
- stacks.report_stack
112
- elsif ARGV[0] == 'report-stack-resource'
113
- @logger.info 'report stack resource...'.color(:green)
114
- stacks.report_stack_resource
251
+ stacks = CFnDK::Stacks.new(data, options, credentials)
252
+ keypairs = CFnDK::KeyPairs.new(data, options, credentials)
253
+
254
+ if options[:force] || yes?('Are you sure you want to destroy? (y/n)', :yellow)
255
+ stacks.destroy
256
+ keypairs.destroy
257
+ return 0
115
258
  else
116
- puts @opt.help
259
+ CFnDK.logger.info 'destroy command was canceled'.color(:green)
117
260
  return 2
118
261
  end
119
- 0
262
+ rescue => e
263
+ CFnDK.logger.error "(#{e.class}) #{e.message}".color(:red)
264
+ CFnDK.logger.debug e.backtrace
265
+ return 1
120
266
  end
121
267
 
122
- def destroy?
123
- return true if @option[:force]
124
- loop do
125
- print 'destroy? [yes|no]:'
126
- res = STDIN.gets
127
- case res
128
- when /^yes/
129
- return true
130
- when /^no/, /^$/
131
- return false
132
- end
268
+ desc 'report', 'Report stack'
269
+ option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
270
+ option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
271
+ option :stack_names, type: :array, desc: 'Target stack names'
272
+ def report
273
+ CFnDK.logger.info 'report...'.color(:green)
274
+
275
+ data = load_config_data(options)
276
+
277
+ credentials = CFnDK::CredentialProviderChain.new.resolve
278
+ stacks = CFnDK::Stacks.new(data, options, credentials)
279
+ stacks.report
280
+ return 0
281
+ rescue => e
282
+ CFnDK.logger.error e.message.color(:red)
283
+ CFnDK.logger.debug e.backtrace
284
+ return 1
285
+ end
286
+
287
+ no_commands do
288
+ def invoke_command(command, *args)
289
+ CFnDK.logger = CFnDKLogger.new(options)
290
+ Rainbow.enabled = false unless options[:color]
291
+ super
133
292
  end
134
293
  end
294
+
295
+ desc 'keypair SUBCOMMAND ...ARGS', 'Manage keypair'
296
+ subcommand 'keypair', KeyPairCommand
297
+ desc 'stack SUBCOMMAND ...ARGS', 'Manage stack'
298
+ subcommand 'stack', StackCommand
135
299
  end
136
300
  end