serverkit 0.3.4 → 0.3.5

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: f40c38c419fd96b3e97a018266dccf0e33b61840
4
- data.tar.gz: 88d12492f9067a4b315659ede04688121467a050
3
+ metadata.gz: 1a4d86f76bbf1a6d2d6bec6525dc21c83c6589b4
4
+ data.tar.gz: 1d830d60b2cfda0a6fb116bc9655c27cf7918037
5
5
  SHA512:
6
- metadata.gz: f05703924e9cb0f31d9930b90562805c8eabff0f8bf84485aaf910d602985bac4bf3bd46173f4d2e585fa8998c8e1285659da7dcc17ac078b4a831277bd08ab1
7
- data.tar.gz: 9094021c5a28689cc70cafcbaac895486a2fd44a4fbc447a6d61d29a55b66dfe5c6ec9506f8cc14161adf16046de0329cacc3bfb4e8ca4a5b85839aaf38497da
6
+ metadata.gz: a7b0c470e401472711cfa0806c26d4d9b33fc1fd6c685b74e5adf6b3c4363f6cc7e17ebb8c9c95813cc1249da8b64bf57259de722f70793c0a0c216a41b4137a
7
+ data.tar.gz: a1aa16f2bacb3c84ca27a59541b06ce6e133a0bac4638ab88183437484edaafd4773156c303f1130da893b8f13337a9abee4cb50edd192a5868d5c4d40750f76
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  Lint/HandleExceptions:
2
2
  Enabled: false
3
3
 
4
+ Lint/UnderscorePrefixedVariableName:
5
+ Enabled: false
6
+
4
7
  Lint/UnusedBlockArgument:
5
8
  Enabled: false
6
9
 
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.3.5
2
+ - Add logger with `--log-level=` and `--no-color` options
3
+
1
4
  ## 0.3.4
2
5
  - Add -f option on symlink resource
3
6
  - Change attributes naming rule: status -> state
data/README.md CHANGED
@@ -7,6 +7,7 @@ Configuration management toolkit for IT automation.
7
7
  - [serverkit check](#serverkit-check)
8
8
  - [serverkit apply](#serverkit-apply)
9
9
  - [SSH support](#ssh-support)
10
+ - [Log](#log)
10
11
  - [Recipe](#recipe)
11
12
  - [Format](#format)
12
13
  - [Variables](#variables)
@@ -107,6 +108,17 @@ $ serverkit apply recipe.yml --hosts=alpha.example.com
107
108
  $ serverkit apply recipe.yml --hosts=alpha.example.com,bravo.example.com
108
109
  ```
109
110
 
111
+ ### Log
112
+ You can change serverkit log level by passing `--log-level=` command line option.
113
+ Available values are `DEBUG`, `ERROR`, `FATAL`, `WARN`, OR `INFO` (default).
114
+ General result lines like `[SKIP] ...` and `[ OK ] ...` are logged with FATAL level,
115
+ and all shell commands executed on hosts are logged with DEBUG level.
116
+ Pass `--no-color` option if you would like to disable colored log outputs.
117
+
118
+ ```
119
+ $ serverkit apply recipe.yml --hosts=alpha.example.com --log-level=debug --no-color
120
+ ```
121
+
110
122
  ## Recipe
111
123
  A recipe describes the desired state of your server.
112
124
  It is mostly a collection of resources, defined using certain patterns.
@@ -12,7 +12,7 @@ resources:
12
12
  notify:
13
13
  - handler_test
14
14
  - type: command
15
- check_script: "false"
15
+ check_script: foo
16
16
  script: echo test
17
17
  recheck_script: "true"
18
18
  handlers:
@@ -4,29 +4,35 @@ require "thread"
4
4
  module Serverkit
5
5
  module Actions
6
6
  class Apply < Base
7
+ # Apply recipe so that all backends have ideal states, then exit with 0 or 1
7
8
  def run
8
- successful = backends.map do |backend|
9
+ if apply_resources
10
+ exit
11
+ else
12
+ exit(1)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ # @return [true, false] True if all backends have ideal states
19
+ def apply_resources
20
+ backends.map do |backend|
9
21
  Thread.new do
10
22
  resources = recipe.resources.map(&:clone).map do |resource|
11
23
  resource.backend = backend
12
24
  resource.run_apply
13
- puts resource.inspect_apply_result
25
+ backend.logger.report_apply_result_of(resource)
14
26
  resource
15
27
  end
16
- handlers = resources.select(&:notifiable?).flat_map(&:handlers).uniq.map(&:clone).map do |handler|
28
+ handlers = resources.select(&:notifiable?).flat_map(&:handlers).uniq.map(&:clone).each do |handler|
17
29
  handler.backend = backend
18
30
  handler.run_apply
19
- puts handler.inspect_apply_result
20
- handler
31
+ backend.logger.report_apply_result_of(handler)
21
32
  end
22
33
  resources + handlers
23
34
  end
24
35
  end.map(&:value).flatten.all?(&:successful?)
25
- if successful
26
- exit
27
- else
28
- exit(1)
29
- end
30
36
  end
31
37
  end
32
38
  end
@@ -1,6 +1,7 @@
1
1
  require "bundler"
2
- require "etc"
3
- require "net/ssh"
2
+ require "logger"
3
+ require "serverkit/backends/local_backend"
4
+ require "serverkit/backends/ssh_backend"
4
5
  require "serverkit/loaders/recipe_loader"
5
6
  require "serverkit/recipe"
6
7
  require "slop"
@@ -9,12 +10,16 @@ require "specinfra"
9
10
  module Serverkit
10
11
  module Actions
11
12
  class Base
13
+ DEFAULT_LOG_LEVEL = ::Logger::INFO
14
+
12
15
  # @param [String, nil] hosts
16
+ # @param [Fixnum] log_level
13
17
  # @param [String] recipe_path
14
18
  # @param [Hash, nil] ssh_options For override default ssh options
15
19
  # @param [Stirng, nil] variables_path
16
- def initialize(hosts: nil, recipe_path: nil, ssh_options: nil, variables_path: nil)
20
+ def initialize(hosts: nil, log_level: nil, recipe_path: nil, ssh_options: nil, variables_path: nil)
17
21
  @hosts = hosts
22
+ @log_level = log_level
18
23
  @recipe_path = recipe_path
19
24
  @ssh_options = ssh_options
20
25
  @variables_path = variables_path
@@ -31,27 +36,18 @@ module Serverkit
31
36
  abort recipe.errors.map { |error| "Error: #{error}" }.join("\n")
32
37
  end
33
38
 
34
- # @return [Array<Specinfra::Backend::Base>]
39
+ # @return [Array<Serverkit::Backends::Base>]
35
40
  def backends
36
41
  if has_hosts?
37
42
  hosts.map do |host|
38
- backend_class.new(
43
+ Backends::SshBackend.new(
39
44
  host: host,
40
- ssh_options: {
41
- user: ssh_user_for(host),
42
- }.merge(ssh_options),
45
+ log_level: @log_level,
46
+ ssh_options: @ssh_options,
43
47
  )
44
48
  end
45
49
  else
46
- [backend_class.new]
47
- end
48
- end
49
-
50
- def backend_class
51
- if has_hosts?
52
- Specinfra::Backend::Ssh
53
- else
54
- Specinfra::Backend::Exec
50
+ [Backends::LocalBackend.new(log_level: @log_level)]
55
51
  end
56
52
  end
57
53
 
@@ -76,21 +72,10 @@ module Serverkit
76
72
  abort_with_errors unless recipe.valid?
77
73
  end
78
74
 
79
- # @return [Hash]
80
- def ssh_options
81
- @ssh_options || {}
82
- end
83
-
84
75
  # @return [Serverkit::Recipe]
85
76
  def recipe
86
77
  @recipe ||= Loaders::RecipeLoader.new(@recipe_path, variables_path: @variables_path).load
87
78
  end
88
-
89
- # @param [String] host
90
- # @return [String] User name used on SSH
91
- def ssh_user_for(host)
92
- Net::SSH::Config.for(host)[:user] || Etc.getlogin
93
- end
94
79
  end
95
80
  end
96
81
  end
@@ -4,22 +4,29 @@ require "thread"
4
4
  module Serverkit
5
5
  module Actions
6
6
  class Check < Base
7
+ # Check if all backends have ideal states, then exit with exit-code 0 or 1
7
8
  def run
8
- successful = backends.map do |backend|
9
+ if check_resources
10
+ exit
11
+ else
12
+ exit(1)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ # @return [true, false] True if all backends have ideal states
19
+ def check_resources
20
+ backends.map do |backend|
9
21
  Thread.new do
10
22
  recipe.resources.map(&:clone).map do |resource|
11
23
  resource.backend = backend
12
24
  resource.run_check
13
- puts resource.inspect_check_result
25
+ backend.logger.report_check_result_of(resource)
14
26
  resource
15
27
  end
16
28
  end
17
29
  end.map(&:value).flatten.all?(&:successful?)
18
- if successful
19
- exit
20
- else
21
- exit(1)
22
- end
23
30
  end
24
31
  end
25
32
  end
@@ -0,0 +1,69 @@
1
+ require "active_support/core_ext/module/delegation"
2
+ require "serverkit/logger"
3
+
4
+ module Serverkit
5
+ module Backends
6
+ class BaseBackend
7
+ delegate(
8
+ :send_file,
9
+ to: :specinfra_backend,
10
+ )
11
+
12
+ def initialize(log_level: nil)
13
+ @log_level = log_level
14
+ end
15
+
16
+ # @return [true, false]
17
+ def check_command(*args)
18
+ run_command(*args).success?
19
+ end
20
+
21
+ # @return [true, false]
22
+ def check_command_from_identifier(*args)
23
+ run_command_from_identifier(*args).success?
24
+ end
25
+
26
+ # @return [String]
27
+ def get_command_from_identifier(*args)
28
+ specinfra_backend.command.get(*args)
29
+ end
30
+
31
+ # @note Override me
32
+ # @return [String]
33
+ # @example "localhost"
34
+ def host
35
+ raise NotImplementedError
36
+ end
37
+
38
+ # @return [Serverkit::Logger]
39
+ def logger
40
+ @logger ||= Serverkit::Logger.new($stdout).tap do |_logger|
41
+ _logger.level = @log_level
42
+ end
43
+ end
44
+
45
+ # @return [Specinfra::CommandResult]
46
+ def run_command(*args)
47
+ logger.debug("Running #{args.first.inspect} on #{host}")
48
+ specinfra_backend.run_command(*args).tap do |result|
49
+ logger.debug(result.stdout) unless result.stdout.empty?
50
+ logger.debug(result.stderr) unless result.stderr.empty?
51
+ logger.debug("Finished with #{result.exit_status} on #{host}")
52
+ end
53
+ end
54
+
55
+ # @return [Specinfra::CommandResult]
56
+ def run_command_from_identifier(*args)
57
+ run_command(get_command_from_identifier(*args))
58
+ end
59
+
60
+ private
61
+
62
+ # @note Override me
63
+ # @return [Specinfra::Backend::Base]
64
+ def specinfra_backend
65
+ raise NotImplementedError
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,22 @@
1
+ require "serverkit/backends/base_backend"
2
+ require "specinfra"
3
+
4
+ module Serverkit
5
+ module Backends
6
+ class LocalBackend < BaseBackend
7
+ HOST = "localhost"
8
+
9
+ # @note Override
10
+ def host
11
+ HOST
12
+ end
13
+
14
+ private
15
+
16
+ # @return [Specinfra::Backend::Exec]
17
+ def specinfra_backend
18
+ @specinfra_backend ||= Specinfra::Backend::Exec.new
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require "etc"
2
+ require "net/ssh"
3
+ require "serverkit/backends/base_backend"
4
+ require "specinfra"
5
+
6
+ module Serverkit
7
+ module Backends
8
+ class SshBackend < BaseBackend
9
+ DEFAULT_SSH_OPTIONS = {}
10
+
11
+ attr_reader :host
12
+
13
+ # @param [String] host
14
+ # @param [Hash] ssh_options
15
+ def initialize(host: nil, ssh_options: nil, **args)
16
+ super(**args)
17
+ @host = host
18
+ @ssh_options = ssh_options
19
+ end
20
+
21
+ private
22
+
23
+ # @return [Specinfra::Backend::Ssh]
24
+ def specinfra_backend
25
+ @specinfra_backend ||= ::Specinfra::Backend::Ssh.new(
26
+ host: host,
27
+ ssh_options: ssh_options,
28
+ )
29
+ end
30
+
31
+ # @return [Hash]
32
+ def ssh_options
33
+ { user: user }.merge(@ssh_options || DEFAULT_SSH_OPTIONS)
34
+ end
35
+
36
+ # @return [String]
37
+ def user
38
+ ::Net::SSH::Config.for(@host)[:user] || ::Etc.getlogin
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,4 @@
1
+ require "rainbow"
1
2
  require "serverkit/actions/apply"
2
3
  require "serverkit/actions/check"
3
4
  require "serverkit/actions/inspect"
@@ -10,12 +11,22 @@ module Serverkit
10
11
  # Command clsas takes care of command line interface.
11
12
  # It builds and runs an Action object from given command line arguements.
12
13
  class Command
14
+ LOG_LEVELS_TABLE = {
15
+ nil => Logger::INFO,
16
+ "DEBUG" => Logger::DEBUG,
17
+ "ERROR" => Logger::ERROR,
18
+ "FATAL" => Logger::FATAL,
19
+ "INFO" => Logger::INFO,
20
+ "WARN" => Logger::WARN,
21
+ }
22
+
13
23
  # @param [Array<String>] argv
14
24
  def initialize(argv)
15
25
  @argv = argv
16
26
  end
17
27
 
18
28
  def call
29
+ setup
19
30
  case action_name
20
31
  when nil
21
32
  raise Errors::MissingActionNameArgumentError
@@ -50,6 +61,7 @@ module Serverkit
50
61
  def action_options
51
62
  {
52
63
  hosts: hosts,
64
+ log_level: log_level,
53
65
  recipe_path: recipe_path,
54
66
  variables_path: variables_path,
55
67
  }.reject do |key, value|
@@ -71,14 +83,21 @@ module Serverkit
71
83
  def command_line_options
72
84
  @command_line_options ||= Slop.parse!(@argv, help: true) do
73
85
  banner "Usage: serverkit ACTION [options]"
74
- on "--hosts=", "Pass hostname to execute command over SSH"
86
+ on "--hosts=", "Hostname to execute command over SSH"
87
+ on "--log-level=", "Log level (DEBUG, INFO, WARN, ERROR, FATAL)"
88
+ on "--no-color", "Disable coloring"
75
89
  on "--variables=", "Path to variables file for ERB recipe"
76
90
  end
77
91
  end
78
92
 
79
93
  # @return [String, nil]
80
94
  def hosts
81
- command_line_options[:hosts]
95
+ command_line_options["hosts"]
96
+ end
97
+
98
+ # @return [Fixnum]
99
+ def log_level
100
+ LOG_LEVELS_TABLE[command_line_options["log-level"]] || ::Logger::UNKNOWN
82
101
  end
83
102
 
84
103
  # @return [String]
@@ -86,12 +105,16 @@ module Serverkit
86
105
  @argv[1] or raise Errors::MissingRecipePathArgumentError
87
106
  end
88
107
 
108
+ def setup
109
+ ::Rainbow.enabled = !command_line_options["no-color"]
110
+ end
111
+
89
112
  def validate
90
113
  Actions::Validate.new(action_options).call
91
114
  end
92
115
 
93
116
  def variables_path
94
- command_line_options[:variables]
117
+ command_line_options["variables"]
95
118
  end
96
119
  end
97
120
  end
@@ -0,0 +1,77 @@
1
+ require "logger"
2
+ require "rainbow"
3
+
4
+ module Serverkit
5
+ # A logger class that has a simple formatter by default.
6
+ class Logger < ::Logger
7
+ def initialize(*)
8
+ super
9
+ self.formatter = Formatter.new
10
+ end
11
+
12
+ # @param [Serverkit::Resources::Base]
13
+ def report_apply_result_of(resource)
14
+ message = ResourceApplyStateView.new(resource).to_s
15
+ fatal(message)
16
+ end
17
+
18
+ # @param [Serverkit::Resources::Base]
19
+ def report_check_result_of(resource)
20
+ message = ResourceCheckStateView.new(resource).to_s
21
+ fatal(message)
22
+ end
23
+
24
+ class Formatter
25
+ def call(severity, time, program_name, message)
26
+ message = message.to_s.gsub(/\n\z/, "") + "\n"
27
+ message = Rainbow(message).black.bright if severity == "DEBUG"
28
+ message
29
+ end
30
+ end
31
+
32
+ class ResourceStateView
33
+ def initialize(resource)
34
+ @resource = resource
35
+ end
36
+
37
+ def to_s
38
+ "[#{result_tag}] #{@resource.type} #{@resource.id} on #{backend_host}"
39
+ end
40
+
41
+ private
42
+
43
+ def backend_host
44
+ @resource.backend.host
45
+ end
46
+ end
47
+
48
+ class ResourceApplyStateView < ResourceStateView
49
+ private
50
+
51
+ # @return [String]
52
+ def result_tag
53
+ case @resource.recheck_result
54
+ when nil
55
+ "SKIP"
56
+ when false
57
+ "FAIL"
58
+ else
59
+ "DONE"
60
+ end
61
+ end
62
+ end
63
+
64
+ class ResourceCheckStateView < ResourceStateView
65
+ private
66
+
67
+ # @return [String]
68
+ def result_tag
69
+ if @resource.check_result
70
+ " OK "
71
+ else
72
+ " NG "
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,4 +1,5 @@
1
1
  require "active_model"
2
+ require "active_support/core_ext/module/delegation"
2
3
  require "readable_validator"
3
4
  require "required_validator"
4
5
  require "serverkit/errors/attribute_validation_error"
@@ -22,12 +23,22 @@ module Serverkit
22
23
 
23
24
  attr_accessor :backend
24
25
 
25
- attr_reader :attributes, :recipe
26
+ attr_reader :attributes, :check_result, :recheck_result, :recipe
26
27
 
27
28
  attribute :id, type: String
28
29
  attribute :notify, type: Array
29
30
  attribute :type, type: String
30
31
 
32
+ delegate(
33
+ :check_command,
34
+ :check_command_from_identifier,
35
+ :get_command_from_identifier,
36
+ :run_command,
37
+ :run_command_from_identifier,
38
+ :send_file,
39
+ to: :backend,
40
+ )
41
+
31
42
  # @param [Serverkit::Recipe] recipe
32
43
  # @param [Hash] attributes
33
44
  def initialize(recipe, attributes)
@@ -56,27 +67,6 @@ module Serverkit
56
67
  @attributes["id"] || default_id
57
68
  end
58
69
 
59
- # @return [String]
60
- def inspect_apply_result
61
- case @recheck_result
62
- when nil
63
- "[SKIP] #{result_inspection_suffix}"
64
- when false
65
- "[FAIL] #{result_inspection_suffix}"
66
- else
67
- "[DONE] #{result_inspection_suffix}"
68
- end
69
- end
70
-
71
- # @return [String]
72
- def inspect_check_result
73
- if @check_result
74
- "[ OK ] #{result_inspection_suffix}"
75
- else
76
- "[ NG ] #{result_inspection_suffix}"
77
- end
78
- end
79
-
80
70
  # @return [true, false] True if this resource should call any handler
81
71
  def notifiable?
82
72
  @recheck_result == true && !handlers.nil?
@@ -96,9 +86,16 @@ module Serverkit
96
86
  @check_result = !!check
97
87
  end
98
88
 
99
- # @return [true, false]
100
89
  def successful?
101
- @check_result == true || @recheck_result == true
90
+ successful_on_check? || successful_on_recheck?
91
+ end
92
+
93
+ def successful_on_check?
94
+ @check_result == true
95
+ end
96
+
97
+ def successful_on_recheck?
98
+ @check_result == true
102
99
  end
103
100
 
104
101
  # @note recipe resource will override to replace itself with multiple resources
@@ -117,21 +114,6 @@ module Serverkit
117
114
  end
118
115
  end
119
116
 
120
- # @return [String]
121
- def backend_host
122
- backend.get_config(:host) || "localhost"
123
- end
124
-
125
- # @return [true, false]
126
- def check_command(*args)
127
- run_command(*args).success?
128
- end
129
-
130
- # @return [true, false]
131
- def check_command_from_identifier(*args)
132
- run_command_from_identifier(*args).success?
133
- end
134
-
135
117
  # @note For override
136
118
  # @return [String]
137
119
  def default_id
@@ -144,21 +126,6 @@ module Serverkit
144
126
  check
145
127
  end
146
128
 
147
- # @return [String]
148
- def result_inspection_suffix
149
- "#{type} #{id} on #{backend_host}"
150
- end
151
-
152
- # @return [Specinfra::CommandResult]
153
- def run_command(*args)
154
- backend.run_command(*args)
155
- end
156
-
157
- # @return [Specinfra::CommandResult]
158
- def run_command_from_identifier(*args)
159
- run_command(backend.command.get(*args))
160
- end
161
-
162
129
  # @return [Array<Symbol>]
163
130
  def required_attribute_names
164
131
  _validators.select do |key, validators|
@@ -1,3 +1,3 @@
1
1
  module Serverkit
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
data/serverkit.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_runtime_dependency "bundler"
22
22
  spec.add_runtime_dependency "hashie"
23
23
  spec.add_runtime_dependency "highline"
24
+ spec.add_runtime_dependency "rainbow"
24
25
  spec.add_runtime_dependency "slop", "~> 3.4"
25
26
  spec.add_runtime_dependency "specinfra"
26
27
  spec.add_development_dependency "pry", "0.10.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serverkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2015-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rainbow
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: slop
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -197,6 +211,9 @@ files:
197
211
  - lib/serverkit/actions/check.rb
198
212
  - lib/serverkit/actions/inspect.rb
199
213
  - lib/serverkit/actions/validate.rb
214
+ - lib/serverkit/backends/base_backend.rb
215
+ - lib/serverkit/backends/local_backend.rb
216
+ - lib/serverkit/backends/ssh_backend.rb
200
217
  - lib/serverkit/command.rb
201
218
  - lib/serverkit/errors/attribute_validation_error.rb
202
219
  - lib/serverkit/errors/base.rb
@@ -211,6 +228,7 @@ files:
211
228
  - lib/serverkit/loaders/base_loader.rb
212
229
  - lib/serverkit/loaders/recipe_loader.rb
213
230
  - lib/serverkit/loaders/variables_loader.rb
231
+ - lib/serverkit/logger.rb
214
232
  - lib/serverkit/recipe.rb
215
233
  - lib/serverkit/resource_builder.rb
216
234
  - lib/serverkit/resources/base.rb
@@ -255,3 +273,4 @@ signing_key:
255
273
  specification_version: 4
256
274
  summary: Configuration management toolkit for IT automation.
257
275
  test_files: []
276
+ has_rdoc: