itamae-mitsurin 0.50 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/itamae-mitsurin/cli.rb +0 -2
- data/lib/itamae-mitsurin/logger.rb +74 -20
- data/lib/itamae-mitsurin/mitsurin/base.rb +109 -0
- data/lib/itamae-mitsurin/mitsurin/base_task.rb +147 -0
- data/lib/itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/recipes/default.rb +0 -11
- data/lib/itamae-mitsurin/mitsurin/itamae_task.rb +44 -130
- data/lib/itamae-mitsurin/mitsurin/itamae_with_target_task.rb +64 -157
- data/lib/itamae-mitsurin/mitsurin/local_task.rb +57 -131
- data/lib/itamae-mitsurin/mitsurin/serverspec_task.rb +56 -81
- data/lib/itamae-mitsurin/mitsurin/serverspec_with_target_task.rb +80 -143
- data/lib/itamae-mitsurin/node.rb +0 -1
- data/lib/itamae-mitsurin/notification.rb +0 -1
- data/lib/itamae-mitsurin/recipe.rb +2 -5
- data/lib/itamae-mitsurin/resource.rb +1 -1
- data/lib/itamae-mitsurin/resource/base.rb +0 -12
- data/lib/itamae-mitsurin/resource/http_request.rb +23 -8
- data/lib/itamae-mitsurin/resource/s3_file.rb +33 -0
- data/lib/itamae-mitsurin/runner.rb +4 -5
- data/lib/itamae-mitsurin/version.txt +1 -1
- metadata +6 -221
- data/lib/itamae-mitsurin/mitsurin/itamae_with_git_task.rb +0 -159
- data/lib/itamae-mitsurin/mitsurin/task_base.rb +0 -100
- data/test/test_itamae-mitsurin.rb +0 -18
- data/test/test_itamae-mitsurin/ext/test_specinfra.rb +0 -39
- data/test/test_itamae-mitsurin/handler/test_base.rb +0 -40
- data/test/test_itamae-mitsurin/handler/test_debug.rb +0 -10
- data/test/test_itamae-mitsurin/handler/test_fluentd.rb +0 -44
- data/test/test_itamae-mitsurin/handler/test_json.rb +0 -22
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/.rspec +0 -2
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/Gemfile +0 -3
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/Rakefile +0 -2
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/environments/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/environments/sample.json +0 -7
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/keys/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/nodes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/nodes/sample01.json +0 -9
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/roles/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/attributes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/files/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/recipes/default.rb +0 -1
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/spec/default_spec.rb +0 -1
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/templates/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/spec/spec_helper.rb +0 -33
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/tmp-nodes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/attributes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/files/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/recipes/default.rb +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/spec/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/templates/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/test_cookbook.rb +0 -24
- data/test/test_itamae-mitsurin/mitsurin/creators/test_project.rb +0 -24
- data/test/test_itamae-mitsurin/mitsurin/test_cli.rb +0 -56
- data/test/test_itamae-mitsurin/mitsurin/test_creators.rb +0 -19
- data/test/test_itamae-mitsurin/mitsurin/test_itamae_task.rb +0 -197
- data/test/test_itamae-mitsurin/mitsurin/test_itamae_with_git_task.rb +0 -213
- data/test/test_itamae-mitsurin/mitsurin/test_serverspec_task.rb +0 -123
- data/test/test_itamae-mitsurin/resource/test_aws_ebs_volume.rb +0 -84
- data/test/test_itamae-mitsurin/resource/test_base.rb +0 -374
- data/test/test_itamae-mitsurin/resource/test_directory.rb +0 -63
- data/test/test_itamae-mitsurin/resource/test_execute.rb +0 -26
- data/test/test_itamae-mitsurin/resource/test_file.rb +0 -176
- data/test/test_itamae-mitsurin/resource/test_gem_package.rb +0 -81
- data/test/test_itamae-mitsurin/resource/test_git.rb +0 -94
- data/test/test_itamae-mitsurin/resource/test_group.rb +0 -42
- data/test/test_itamae-mitsurin/resource/test_http_request.rb +0 -71
- data/test/test_itamae-mitsurin/resource/test_link.rb +0 -33
- data/test/test_itamae-mitsurin/resource/test_local_ruby_block.rb +0 -15
- data/test/test_itamae-mitsurin/resource/test_package.rb +0 -44
- data/test/test_itamae-mitsurin/resource/test_remote_directory.rb +0 -84
- data/test/test_itamae-mitsurin/resource/test_remote_file.rb +0 -54
- data/test/test_itamae-mitsurin/resource/test_service.rb +0 -69
- data/test/test_itamae-mitsurin/resource/test_template.rb +0 -53
- data/test/test_itamae-mitsurin/resource/test_user.rb +0 -93
- data/test/test_itamae-mitsurin/test_backend.rb +0 -297
- data/test/test_itamae-mitsurin/test_cli.rb +0 -88
- data/test/test_itamae-mitsurin/test_definition.rb +0 -40
- data/test/test_itamae-mitsurin/test_ext.rb +0 -1
- data/test/test_itamae-mitsurin/test_handler.rb +0 -21
- data/test/test_itamae-mitsurin/test_handler_proxy.rb +0 -38
- data/test/test_itamae-mitsurin/test_logger.rb +0 -124
- data/test/test_itamae-mitsurin/test_mitsurin.rb +0 -14
- data/test/test_itamae-mitsurin/test_node.rb +0 -74
- data/test/test_itamae-mitsurin/test_notification.rb +0 -46
- data/test/test_itamae-mitsurin/test_recipe.rb +0 -171
- data/test/test_itamae-mitsurin/test_recipe_children.rb +0 -86
- data/test/test_itamae-mitsurin/test_resource.rb +0 -73
- data/test/test_itamae-mitsurin/test_runner.rb +0 -124
- data/test/test_itamae-mitsurin/test_version.rb +0 -3
- data/test/test_itamae-mitsurin/version.txt +0 -1
- data/test_project/.rspec +0 -2
- data/test_project/Gemfile +0 -4
- data/test_project/Rakefile +0 -3
- data/test_project/environments/.keep +0 -0
- data/test_project/keys/.keep +0 -0
- data/test_project/nodes/.keep +0 -0
- data/test_project/nodes/test.json +0 -9
- data/test_project/roles/.keep +0 -0
- data/test_project/roles/test.json +0 -14
- data/test_project/site-cookbooks/_base/_base/attributes/.keep +0 -0
- data/test_project/site-cookbooks/_base/_base/files/.keep +0 -0
- data/test_project/site-cookbooks/_base/_base/recipes/default.rb +0 -1
- data/test_project/site-cookbooks/_base/_base/spec/default_spec.rb +0 -1
- data/test_project/site-cookbooks/_base/_base/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/recipes/default.rb +0 -8
- data/test_project/site-cookbooks/a_test/directory/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/spec/default_spec.rb +0 -4
- data/test_project/site-cookbooks/a_test/directory/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/recipes/default.rb +0 -2
- data/test_project/site-cookbooks/a_test/package/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/spec/default_spec.rb +0 -4
- data/test_project/site-cookbooks/a_test/package/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/a_test/service/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/spec/default_spec.rb +0 -6
- data/test_project/site-cookbooks/a_test/service/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/git/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/spec/default_spec.rb +0 -5
- data/test_project/site-cookbooks/b_test/git/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/link/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/spec/default_spec.rb +0 -5
- data/test_project/site-cookbooks/b_test/link/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/files/remote_file.sh +0 -1
- data/test_project/site-cookbooks/b_test/remote_file/recipes/default.rb +0 -9
- data/test_project/site-cookbooks/b_test/remote_file/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/spec/default_spec.rb +0 -7
- data/test_project/site-cookbooks/b_test/remote_file/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/template/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/spec/default_spec.rb +0 -7
- data/test_project/site-cookbooks/b_test/template/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/templates/template.erb +0 -2
- data/test_project/site-cookbooks/c_test/execute/attributes/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/files/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/recipes/default.rb +0 -6
- data/test_project/site-cookbooks/c_test/execute/spec/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/spec/default_spec.rb +0 -6
- data/test_project/site-cookbooks/c_test/execute/templates/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/attributes/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/files/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/recipes/default.rb +0 -10
- data/test_project/site-cookbooks/c_test/remote_directory/spec/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/spec/default_spec.rb +0 -20
- data/test_project/site-cookbooks/c_test/remote_directory/templates/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/a.txt +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/b.txt +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/c.txt +0 -0
- data/test_project/site-cookbooks/d_spec/air/attributes/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/files/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/recipes/default.rb +0 -0
- data/test_project/site-cookbooks/d_spec/air/spec/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/spec/default_spec.rb +0 -0
- data/test_project/site-cookbooks/d_spec/air/templates/.keep +0 -0
- data/test_project/spec/spec_helper.rb +0 -33
- data/test_project/tmp-nodes/.keep +0 -0
- data/test_project/tmp-nodes/test.json +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 820a66a01e1d3908d4c24206171897a2931cc7063a141fad22959206ce507909
|
4
|
+
data.tar.gz: 374e9edf28cf7a2024383045cea7cc016cb00c43e4e5bd0513d3fe8a510165b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90925c472f20db377cc5b1831f2495ea1499c6a4362c43cb8b39dde4271ae3db1eb13eac9baf088e0116a4d52fce952eefe907d21447e3c556a84d3ed97f054a
|
7
|
+
data.tar.gz: 4f853e11a25179818bd250884b6f0c1ce275c42b5a0a0f53afe2821e4348048911efc3d16aa34e737eba502d8c8461961b9a26703ef2d323728fb0b212c09144
|
data/lib/itamae-mitsurin/cli.rb
CHANGED
@@ -12,9 +12,7 @@ module ItamaeMitsurin
|
|
12
12
|
super
|
13
13
|
|
14
14
|
ItamaeMitsurin.logger.level = ::Logger.const_get(options[:log_level].upcase)
|
15
|
-
ItamaeMitsurin.file_logger.level = ::Logger.const_get(options[:log_level].upcase)
|
16
15
|
ItamaeMitsurin.logger.formatter.colored = options[:color]
|
17
|
-
ItamaeMitsurin.file_logger.formatter.colored = options[:color]
|
18
16
|
end
|
19
17
|
|
20
18
|
def self.define_exec_options
|
@@ -118,26 +118,88 @@ module ItamaeMitsurin
|
|
118
118
|
ANSI.public_send(color_code) { str }
|
119
119
|
end
|
120
120
|
end
|
121
|
-
end
|
122
121
|
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
class FileFormatter < Formatter
|
123
|
+
def call(severity, datetime, progname, msg)
|
124
|
+
log = "%s : %s" % ["%5s" % severity, msg2str(msg)]
|
125
|
+
Time.now.strftime('%F %T %z').to_s + log + "\n"
|
126
|
+
end
|
126
127
|
|
127
|
-
|
128
|
-
|
129
|
-
|
128
|
+
# def colorize(str, severity)
|
129
|
+
# Time.now.strftime('%F %T %z').to_s + str
|
130
|
+
# end
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.broadcast(logger)
|
134
|
+
Module.new do
|
135
|
+
define_method(:add) do |*args, &block|
|
136
|
+
logger.add(*args, &block)
|
137
|
+
super(*args, &block)
|
138
|
+
end
|
139
|
+
|
140
|
+
define_method(:<<) do |x|
|
141
|
+
logger << x
|
142
|
+
super(x)
|
143
|
+
end
|
144
|
+
|
145
|
+
define_method(:close) do
|
146
|
+
logger.close
|
147
|
+
super()
|
148
|
+
end
|
149
|
+
|
150
|
+
define_method(:progname=) do |name|
|
151
|
+
logger.progname = name
|
152
|
+
super(name)
|
153
|
+
end
|
154
|
+
|
155
|
+
define_method(:formatter=) do |formatter|
|
156
|
+
logger.formatter = formatter
|
157
|
+
super(formatter)
|
158
|
+
end
|
159
|
+
|
160
|
+
define_method(:level=) do |level|
|
161
|
+
logger.level = level
|
162
|
+
super(level)
|
163
|
+
end
|
164
|
+
|
165
|
+
define_method(:local_level=) do |level|
|
166
|
+
logger.local_level = level if logger.respond_to?(:local_level=)
|
167
|
+
super(level) if respond_to?(:local_level=)
|
168
|
+
end
|
130
169
|
|
131
|
-
|
132
|
-
|
133
|
-
|
170
|
+
define_method(:silence) do |level = Logger::ERROR, &block|
|
171
|
+
if logger.respond_to?(:silence)
|
172
|
+
logger.silence(level) do
|
173
|
+
if defined?(super)
|
174
|
+
super(level, &block)
|
175
|
+
else
|
176
|
+
block.call(self)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
else
|
180
|
+
if defined?(super)
|
181
|
+
super(level, &block)
|
182
|
+
else
|
183
|
+
block.call(self)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
134
188
|
end
|
135
189
|
end
|
136
190
|
|
137
|
-
@
|
138
|
-
l.formatter = ItamaeMitsurin::Logger::
|
191
|
+
@logger = ::Logger.new($stdout).tap do |l|
|
192
|
+
l.formatter = ItamaeMitsurin::Logger::Formatter.new
|
139
193
|
end.extend(ItamaeMitsurin::Logger::Helper)
|
140
194
|
|
195
|
+
if Dir.exist?('logs')
|
196
|
+
@file_logger = ::Logger.new('logs/itamae.log', 'daily').tap do |l|
|
197
|
+
l.formatter = ItamaeMitsurin::Logger::FileFormatter.new
|
198
|
+
end.extend(ItamaeMitsurin::Logger::Helper)
|
199
|
+
|
200
|
+
@logger.extend ItamaeMitsurin::Logger.broadcast(@file_logger)
|
201
|
+
end
|
202
|
+
|
141
203
|
class << self
|
142
204
|
def logger
|
143
205
|
@logger
|
@@ -146,13 +208,5 @@ module ItamaeMitsurin
|
|
146
208
|
def logger=(l)
|
147
209
|
@logger = l.extend(ItamaeMitsurin::Logger::Helper)
|
148
210
|
end
|
149
|
-
|
150
|
-
def file_logger
|
151
|
-
@file_logger
|
152
|
-
end
|
153
|
-
|
154
|
-
def file_logger=(l)
|
155
|
-
@file_logger = l.extend(ItamaeMitsurin::Logger::Helper)
|
156
|
-
end
|
157
211
|
end
|
158
212
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'itamae-mitsurin'
|
2
|
+
require 'json'
|
3
|
+
require 'highline'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
module ItamaeMitsurin
|
8
|
+
module Mitsurin
|
9
|
+
module Base
|
10
|
+
RoleLoadError = Class.new(StandardError)
|
11
|
+
|
12
|
+
class ::Hash
|
13
|
+
def deep_merge(other_hash, &block)
|
14
|
+
dup.deep_merge!(other_hash, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def deep_merge!(other_hash, &block)
|
18
|
+
merge!(other_hash) do |key, this_val, other_val|
|
19
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
20
|
+
this_val.deep_merge(other_val, &block)
|
21
|
+
elsif block_given?
|
22
|
+
yield(key, this_val, other_val)
|
23
|
+
else
|
24
|
+
other_val
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
# def get_roles(node_file)
|
32
|
+
# roles = []
|
33
|
+
# JSON.parse(File.read(node_file))['run_list'].each do |role|
|
34
|
+
# roles << role.gsub(/role\[(.+)\]/, '\1') if /role\[(.+)\]/.match?(role)
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# roles
|
38
|
+
# end
|
39
|
+
|
40
|
+
def get_role_recipes(role)
|
41
|
+
recipes = []
|
42
|
+
JSON.parse(File.read("roles/#{role}.json"))['run_list'].each do |recipe|
|
43
|
+
if /recipe\[(.+)::(.+)\]/.match?(recipe)
|
44
|
+
recipes << { recipe.gsub(/recipe\[(.+)::(.+)\]/, '\1') => recipe.gsub(/recipe\[(.+)::(.+)\]/, '\2') }
|
45
|
+
elsif /recipe\[(.+)\]/.match?(recipe)
|
46
|
+
recipes << { recipe.gsub(/recipe\[(.+)\]/, '\1') => 'default' }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue JSON::ParserError
|
50
|
+
raise RoleLoadError, "JSON Parser Faild. - roles/#{role}.json"
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
raise RoleLoadError, "No such role file or directory - roles/#{role}.json"
|
53
|
+
else
|
54
|
+
recipes
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_node_recipes(node_file)
|
58
|
+
recipes = []
|
59
|
+
JSON.parse(File.read(node_file))['run_list'].each do |recipe|
|
60
|
+
if /recipe\[(.+)::(.+)\]/.match?(recipe)
|
61
|
+
recipes << { recipe.gsub(/recipe\[(.+)::(.+)\]/, '\1') => recipe.gsub(/recipe\[(.+)::(.+)\]/, '\2') }
|
62
|
+
elsif /recipe\[(.+)\]/.match?(recipe)
|
63
|
+
recipes << { recipe.gsub(/recipe\[(.+)\]/, '\1') => 'default' }
|
64
|
+
elsif /role\[(.+)\]/.match?(recipe)
|
65
|
+
recipes << get_role_recipes(recipe.gsub(/role\[(.+)\]/, '\1'))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue JSON::ParserError
|
69
|
+
raise RoleLoadError, "JSON Parser Faild. - #{node_file}"
|
70
|
+
rescue Errno::ENOENT
|
71
|
+
raise RoleLoadError, "No such node file or directory - #{node_fie}"
|
72
|
+
else
|
73
|
+
recipes
|
74
|
+
end
|
75
|
+
|
76
|
+
def jq(*objs)
|
77
|
+
par = nil
|
78
|
+
objs.each {|obj| par = JSON.pretty_generate(obj, allow_nan: true, max_nesting: false) }
|
79
|
+
par
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_tmp_nodes(filename)
|
83
|
+
ItamaeMitsurin.logger.info "Output attributes log file to: tmp-nodes/#{filename}.json"
|
84
|
+
|
85
|
+
File.open "tmp-nodes/#{filename}.json", 'w' do |f|
|
86
|
+
f.flock File::LOCK_EX
|
87
|
+
yield f
|
88
|
+
f.flock File::LOCK_UN
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def write_tmp_json(filename)
|
93
|
+
path = Dir.mktmpdir('mitsurin-')
|
94
|
+
open("#{path}/#{filename}.json", 'w') do |f|
|
95
|
+
f.flock File::LOCK_EX
|
96
|
+
yield f
|
97
|
+
f.flock File::LOCK_UN
|
98
|
+
end
|
99
|
+
|
100
|
+
path
|
101
|
+
end
|
102
|
+
|
103
|
+
def handler_logger
|
104
|
+
default = {"handlers"=>[{"type"=>"json", "path"=>"itamae-log.json"}]}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'itamae-mitsurin/mitsurin/base'
|
2
|
+
|
3
|
+
module ItamaeMitsurin
|
4
|
+
module Mitsurin
|
5
|
+
class BaseTask
|
6
|
+
extend Rake::DSL if defined? Rake::DSL
|
7
|
+
EnvironmentsSetError = Class.new(StandardError)
|
8
|
+
LoadRecipeError = Class.new(StandardError)
|
9
|
+
LoadAttributeError = Class.new(StandardError)
|
10
|
+
|
11
|
+
def load_node_attributes(node_file)
|
12
|
+
JSON.parse(File.read(node_file), symbolize_names: true)
|
13
|
+
rescue JSON::ParserError
|
14
|
+
raise LoadAttributeError, "JSON Parser Failed. - #{node_file}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_run_list(node_file)
|
18
|
+
run_list = []
|
19
|
+
run_list << { '_base' => 'default' }
|
20
|
+
# Base.get_roles(node_file).each {|role| run_list << Base.get_role_recipes(role) }
|
21
|
+
Base.get_node_recipes(node_file).each {|recipe| run_list << recipe }
|
22
|
+
run_list.flatten
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_environments(hash)
|
26
|
+
set = hash[:environments][:set]
|
27
|
+
raise EnvironmentsSetError, 'Environments Set is not specified in nodefile' if set.nil?
|
28
|
+
JSON.parse(File.read("environments/#{set}.json"), symbolize_names: true)
|
29
|
+
rescue JSON::ParserError
|
30
|
+
raise LoadAttributeError, "JSON Parser Failed. - environments/#{set}.json"
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_recipe_attributes(run_list)
|
34
|
+
recipe_files = run_list.map do |recipe|
|
35
|
+
Dir.glob("site-cookbooks/**/#{recipe.keys.join}/attributes/#{recipe.values.join}.json")
|
36
|
+
end.flatten
|
37
|
+
|
38
|
+
recipe_files.map do |f|
|
39
|
+
begin
|
40
|
+
JSON.parse(File.read(f), symbolize_names: true)
|
41
|
+
rescue JSON::ParserError
|
42
|
+
raise LoadAttributeError, "JSON Parser Failed. - #{f}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def merge_attributes(source, other = nil)
|
48
|
+
if source.class == Hash
|
49
|
+
merged = source.deep_merge(other)
|
50
|
+
elsif source.class == Array
|
51
|
+
if source.empty?
|
52
|
+
merged = {}
|
53
|
+
else
|
54
|
+
merged = source[0]
|
55
|
+
source.each {|s| merged.deep_merge!(s) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
merged
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_tmp_nodes(filename, hash)
|
63
|
+
json = Base.jq(hash)
|
64
|
+
Base.write_tmp_nodes(filename) {|f| f.puts json }
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_itamae_command(node_name, hash)
|
68
|
+
command = 'bundle exec itamae ssh'
|
69
|
+
command << if hash[:environments][:local_ipv4]
|
70
|
+
" -h #{hash[:environments][:local_ipv4]}"
|
71
|
+
else
|
72
|
+
" -h #{hash[:environments][:hostname]}"
|
73
|
+
end
|
74
|
+
|
75
|
+
command << " -u #{hash[:environments][:ssh_user]}"
|
76
|
+
command << " -p #{hash[:environments][:ssh_port]}"
|
77
|
+
command << " -i keys/#{hash[:environments][:ssh_key]}" unless hash[:environments][:ssh_key].nil?
|
78
|
+
command << " -j tmp-nodes/#{node_name}.json"
|
79
|
+
|
80
|
+
hash[:environments][:shell] = ENV['shell'] if ENV['shell']
|
81
|
+
command << if hash[:environments][:shell]
|
82
|
+
" --shell=#{hash[:environments][:shell]}"
|
83
|
+
else
|
84
|
+
' --shell=bash'
|
85
|
+
end
|
86
|
+
|
87
|
+
command << ' --ask-password' unless hash[:environments][:ssh_password].nil?
|
88
|
+
command << ' --dry-run' if ENV['dry-run'] == 'true'
|
89
|
+
command << ' --log-level=debug' if ENV['debug'] == 'true'
|
90
|
+
command << ' --vagrant' if ENV['vagrant'] == 'true'
|
91
|
+
command
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_spec_command(node_name, hash)
|
95
|
+
ENV['TARGET_HOST'] = if hash[:environments][:local_ipv4].nil?
|
96
|
+
hash[:environments][:hostname]
|
97
|
+
else
|
98
|
+
hash[:environments][:local_ipv4]
|
99
|
+
end
|
100
|
+
|
101
|
+
ENV['NODE_FILE'] = "tmp-nodes/#{node_name}.json"
|
102
|
+
ENV['SSH_PASSWORD'] = hash[:environments][:ssh_password]
|
103
|
+
ENV['SUDO_PASSWORD'] = hash[:environments][:sudo_password]
|
104
|
+
ENV['SSH_KEY'] = "keys/#{hash[:environments][:ssh_key]}"
|
105
|
+
ENV['SSH_USER'] = hash[:environments][:ssh_user]
|
106
|
+
ENV['SSH_PORT'] = hash[:environments][:ssh_port]
|
107
|
+
|
108
|
+
command = 'bundle exec rspec'
|
109
|
+
# ENV['vagrant'] TODO
|
110
|
+
end
|
111
|
+
|
112
|
+
def list_recipe_filepath(run_list)
|
113
|
+
recipes = []
|
114
|
+
run_list.each do |recipe|
|
115
|
+
target_list = Dir.glob("site-cookbooks/**/#{recipe.keys.join}/recipes/#{recipe.values.join}.rb")
|
116
|
+
|
117
|
+
raise LoadRecipeError, "#{recipe.to_a.join('::')} cookbook or recipe does not exist." if target_list.empty?
|
118
|
+
|
119
|
+
target_list.each do |target|
|
120
|
+
recipes << " #{target}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
recipes
|
125
|
+
end
|
126
|
+
|
127
|
+
def runner_display(raw_run_list, run_list, command)
|
128
|
+
run_list_str = run_list.map do |recipe|
|
129
|
+
if recipe.values.join == 'default'
|
130
|
+
recipe.keys.join
|
131
|
+
else
|
132
|
+
"#{recipe.keys.join}::#{recipe.values.join}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
ItamaeMitsurin.logger.color(:green) do
|
137
|
+
ItamaeMitsurin.logger.info "Run List is [#{raw_run_list.join(', ')}]"
|
138
|
+
ItamaeMitsurin.logger.info "Run List expands to [#{run_list_str.join(', ')}]"
|
139
|
+
end
|
140
|
+
|
141
|
+
ItamaeMitsurin.logger.color(:white) do
|
142
|
+
ItamaeMitsurin.logger.info command
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
ItamaeMitsurin.logger.color(:green) do
|
2
|
-
ItamaeMitsurin.logger.info "Environment: #{node[:environments][:set]}"
|
3
|
-
ItamaeMitsurin.file_logger.info "Environment: #{node[:environments][:set]}"
|
4
|
-
end
|
5
|
-
|
6
|
-
#Aws.config.update({
|
7
|
-
# region: "ap-northeast-1",
|
8
|
-
# credentials: Aws::Credentials.new(
|
9
|
-
# 'key',
|
10
|
-
# 'secret'
|
11
|
-
#)})
|
@@ -1,150 +1,64 @@
|
|
1
|
-
require 'itamae-mitsurin/mitsurin/
|
2
|
-
include Rake::DSL if defined? Rake::DSL
|
1
|
+
require 'itamae-mitsurin/mitsurin/base_task'
|
3
2
|
|
4
3
|
module ItamaeMitsurin
|
5
4
|
module Mitsurin
|
6
|
-
class ItamaeTask
|
5
|
+
class ItamaeTask < BaseTask
|
6
|
+
ItamaeMitsurin.logger.formatter.colored = true
|
7
|
+
task = ItamaeTask.new
|
7
8
|
|
8
9
|
namespace :itamae do
|
9
|
-
|
10
|
-
bname = File.basename(node_file, '.json')
|
10
|
+
all = []
|
11
11
|
|
12
|
+
Dir.glob('nodes/**/*.json').each do |node_file|
|
12
13
|
begin
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
node_name = File.basename(node_file, '.json')
|
15
|
+
node = task.load_node_attributes(node_file)
|
16
|
+
node_short = node[:environments][:hostname].split('.')[0]
|
17
|
+
rescue => e
|
18
|
+
ItamaeMitsurin.logger.error e.inspect
|
19
|
+
ItamaeMitsurin.logger.info "From node file: #{node_file}"
|
20
|
+
exit 2
|
17
21
|
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
recipes = []
|
23
|
-
TaskBase.get_roles(node_file).each do |role|
|
24
|
-
recipes << TaskBase.get_recipes(role)
|
25
|
-
end
|
26
|
-
TaskBase.get_node_recipes(node_file).each do |recipe|
|
27
|
-
recipes << recipe
|
28
|
-
end
|
29
|
-
rescue Exception => e
|
30
|
-
puts e.class.to_s + ", " + e.backtrace[0].to_s
|
31
|
-
puts "Node or role error, nodefile:#{node_file}, reason:#{e.message}"
|
32
|
-
else
|
33
|
-
recipes.flatten!
|
34
|
-
end
|
23
|
+
all << node_short
|
24
|
+
desc 'Itamae to all nodes'
|
25
|
+
task 'all' => all
|
35
26
|
|
36
|
-
|
27
|
+
desc "Itamae to #{node_name}"
|
28
|
+
task node_short do
|
37
29
|
begin
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
recipe_attr_file.flatten!
|
59
|
-
|
60
|
-
# recipes attr other=env
|
61
|
-
recipe_env_h_a = []
|
62
|
-
recipe_attr_file.each do |file|
|
63
|
-
recipe_h = JSON.parse(File.read(file), symbolize_names: true)
|
64
|
-
recipe_env_h_a << recipe_h.deep_merge(env_h)
|
65
|
-
end
|
66
|
-
|
67
|
-
# recipe attr other=recipes_env
|
68
|
-
moto = recipe_env_h_a[0]
|
69
|
-
recipe_env_h_a.each {|hash| moto.deep_merge!(hash)}
|
70
|
-
recipe_env_h = moto
|
71
|
-
|
72
|
-
if recipe_env_h.nil?
|
73
|
-
# env attr other=node
|
74
|
-
node_env_h = env_h.deep_merge(node_h)
|
75
|
-
node_env_j = TaskBase.jq node_env_h
|
76
|
-
TaskBase.write_json(bname) {|file| file.puts node_env_j}
|
77
|
-
else
|
78
|
-
# recipe_env attr other=node
|
79
|
-
recipe_env_node_h = recipe_env_h.deep_merge(node_h)
|
80
|
-
recipe_env_node_j = TaskBase.jq recipe_env_node_h
|
81
|
-
TaskBase.write_json(bname) {|file| file.puts recipe_env_node_j}
|
82
|
-
end
|
83
|
-
|
84
|
-
recipes << {'_base' => 'default'}
|
85
|
-
node_property = JSON.parse(File.read("tmp-nodes/#{bname}.json"), symbolize_names: true)
|
86
|
-
node = node_property[:environments][:hostname]
|
87
|
-
ssh_user = node_property[:environments][:ssh_user]
|
88
|
-
ssh_password = node_property[:environments][:ssh_password]
|
89
|
-
sudo_password = node_property[:environments][:sudo_password]
|
90
|
-
ssh_port = node_property[:environments][:ssh_port]
|
91
|
-
ssh_key = node_property[:environments][:ssh_key]
|
92
|
-
|
93
|
-
ENV['TARGET_HOST'] = node
|
94
|
-
ENV['NODE_FILE'] = node_file
|
95
|
-
ENV['SSH_PASSWORD'] = ssh_password
|
96
|
-
ENV['SUDO_PASSWORD'] = sudo_password
|
97
|
-
|
98
|
-
command = "bundle exec itamae ssh"
|
99
|
-
command << " -h #{node}"
|
100
|
-
command << " -u #{ssh_user}"
|
101
|
-
command << " -p #{ssh_port}"
|
102
|
-
command << " -i keys/#{ssh_key}" unless ssh_key.nil?
|
103
|
-
command << " -j tmp-nodes/#{bname}.json"
|
104
|
-
command << " --shell=bash"
|
105
|
-
command << " --ask-password" unless ssh_password.nil?
|
106
|
-
command << " --dry-run" if ENV['dry-run'] == "true"
|
107
|
-
command << " -l debug" if ENV['debug'] == "true"
|
108
|
-
command << " -c logs/config/itamae_task.config"
|
109
|
-
|
110
|
-
# Pass to read the recipe command
|
111
|
-
command_recipe = []
|
112
|
-
recipes.each do |recipe_h|
|
113
|
-
target_recipe = "site-cookbooks/**/#{recipe_h.keys.join}/recipes/#{recipe_h[recipe_h.keys.join]}.rb"
|
114
|
-
if Dir.glob(target_recipe).empty?
|
115
|
-
raise "Recipe load error, nodefile: #{node_file}, reason: Does not exist " +
|
116
|
-
recipe_h.keys.join + '::' +recipe_h.values.join
|
117
|
-
end
|
118
|
-
Dir.glob(target_recipe).join("\s").split.each do |target|
|
119
|
-
unless File.exists?(target)
|
120
|
-
ex_recipe = recipe_h.to_s.gsub('=>', '::').gsub('"', '')
|
121
|
-
raise "Recipe load error, nodefile:#{node_file}, reason: Does not exist #{ex_recipe}"
|
30
|
+
run_list = task.load_run_list(node_file)
|
31
|
+
environments = task.load_environments(node)
|
32
|
+
recipe_attributes_list = task.load_recipe_attributes(run_list)
|
33
|
+
|
34
|
+
merged_recipe = task.merge_attributes(recipe_attributes_list)
|
35
|
+
merged_environments = task.merge_attributes(merged_recipe, environments)
|
36
|
+
attributes = task.merge_attributes(merged_environments, node)
|
37
|
+
task.create_tmp_nodes(node_name, attributes)
|
38
|
+
|
39
|
+
command = task.create_itamae_command(node_name, attributes)
|
40
|
+
command_recipe = task.list_recipe_filepath(run_list)
|
41
|
+
command_recipe.sort_by! {|item| File.dirname(item) }
|
42
|
+
command << command_recipe.join
|
43
|
+
|
44
|
+
task.runner_display(attributes[:run_list], run_list, command)
|
45
|
+
st = system command
|
46
|
+
if st
|
47
|
+
ItamaeMitsurin.logger.color(:green) do
|
48
|
+
ItamaeMitsurin.logger.info 'itamae_task is completed.'
|
122
49
|
end
|
123
|
-
command_recipe << " #{target}"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
command_recipe.sort_by! {|item| File.dirname(item) }
|
128
|
-
command << command_recipe.join
|
129
|
-
|
130
|
-
puts TaskBase.hl.color(%!Run Itamae to "#{bname}"!, :red)
|
131
|
-
run_list_noti = []
|
132
|
-
command_recipe.each { |c_recipe|
|
133
|
-
unless c_recipe.split("/")[4].split(".")[0] == 'default'
|
134
|
-
run_list_noti << c_recipe.split("/")[2] + "::#{c_recipe.split("/")[4].split(".")[0]}"
|
135
50
|
else
|
136
|
-
|
51
|
+
ItamaeMitsurin.logger.error 'itamae_task is failed.'
|
52
|
+
exit 1
|
137
53
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
exit 1 unless st
|
54
|
+
rescue => e
|
55
|
+
ItamaeMitsurin.logger.error e.inspect
|
56
|
+
ItamaeMitsurin.logger.info "From node file: #{node_file}"
|
57
|
+
exit 2
|
58
|
+
end
|
144
59
|
end
|
145
60
|
end
|
146
61
|
end
|
147
|
-
|
148
62
|
end
|
149
63
|
end
|
150
64
|
end
|