ridley 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rbenv-version +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +46 -1
- data/Guardfile +0 -1
- data/README.md +15 -0
- data/Thorfile +18 -15
- data/bootstrappers/omnibus.erb +73 -0
- data/lib/ridley/bootstrapper/context.rb +172 -0
- data/lib/ridley/bootstrapper.rb +99 -0
- data/lib/ridley/chain_link.rb +25 -0
- data/lib/ridley/connection.rb +27 -5
- data/lib/ridley/errors.rb +6 -1
- data/lib/ridley/logging.rb +30 -0
- data/lib/ridley/resources/client.rb +3 -3
- data/lib/ridley/resources/cookbook.rb +3 -3
- data/lib/ridley/resources/data_bag.rb +8 -8
- data/lib/ridley/resources/environment.rb +3 -3
- data/lib/ridley/resources/node.rb +57 -3
- data/lib/ridley/resources/role.rb +3 -3
- data/lib/ridley/resources/sandbox.rb +3 -3
- data/lib/ridley/ssh/response.rb +13 -0
- data/lib/ridley/ssh/response_set.rb +51 -0
- data/lib/ridley/ssh/worker.rb +71 -0
- data/lib/ridley/ssh.rb +74 -0
- data/lib/ridley/version.rb +1 -1
- data/lib/ridley.rb +42 -17
- data/ridley.gemspec +6 -17
- data/spec/acceptance/bootstrapping_spec.rb +29 -0
- data/spec/spec_helper.rb +19 -3
- data/spec/unit/ridley/bootstrapper/context_spec.rb +119 -0
- data/spec/unit/ridley/bootstrapper_spec.rb +86 -0
- data/spec/unit/ridley/resources/node_spec.rb +41 -1
- data/spec/unit/ridley/ssh_spec.rb +31 -0
- data/spec/unit/ridley_spec.rb +0 -6
- metadata +42 -185
- data/lib/ridley/context.rb +0 -25
data/.rbenv-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p286
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,3 +1,48 @@
|
|
1
|
-
source
|
1
|
+
source :rubygems
|
2
2
|
|
3
3
|
gemspec
|
4
|
+
|
5
|
+
platforms :jruby do
|
6
|
+
gem 'jruby-openssl'
|
7
|
+
end
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem 'yard'
|
11
|
+
gem 'spork'
|
12
|
+
gem 'guard', '>= 1.5.0'
|
13
|
+
gem 'guard-yard'
|
14
|
+
gem 'guard-rspec'
|
15
|
+
gem 'guard-spork', platforms: :ruby
|
16
|
+
gem 'coolline'
|
17
|
+
gem 'redcarpet', platforms: :ruby
|
18
|
+
gem 'kramdown', platforms: :jruby
|
19
|
+
|
20
|
+
require 'rbconfig'
|
21
|
+
|
22
|
+
if RbConfig::CONFIG['target_os'] =~ /darwin/i
|
23
|
+
gem 'growl', require: false
|
24
|
+
gem 'rb-fsevent', require: false
|
25
|
+
|
26
|
+
if `uname`.strip == 'Darwin' && `sw_vers -productVersion`.strip >= '10.8'
|
27
|
+
gem 'terminal-notifier-guard', '~> 1.5.3', require: false
|
28
|
+
end rescue Errno::ENOENT
|
29
|
+
|
30
|
+
elsif RbConfig::CONFIG['target_os'] =~ /linux/i
|
31
|
+
gem 'libnotify', '~> 0.8.0', require: false
|
32
|
+
gem 'rb-inotify', require: false
|
33
|
+
|
34
|
+
elsif RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
|
35
|
+
gem 'win32console', require: false
|
36
|
+
gem 'rb-notifu', '>= 0.0.4', require: false
|
37
|
+
gem 'wdm', require: false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
group :test do
|
42
|
+
gem 'thor'
|
43
|
+
gem 'rake', '>= 0.9.2.2'
|
44
|
+
gem 'rspec'
|
45
|
+
gem 'fuubar'
|
46
|
+
gem 'json_spec'
|
47
|
+
gem 'webmock'
|
48
|
+
end
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -345,6 +345,21 @@ And the same goes for setting an environment level override attribute
|
|
345
345
|
obj.save
|
346
346
|
end
|
347
347
|
|
348
|
+
## Bootstrapping nodes
|
349
|
+
|
350
|
+
conn = Ridley.connection(
|
351
|
+
server_url: "https://api.opscode.com",
|
352
|
+
organization: "vialstudios",
|
353
|
+
validator_client: "vialstudios-validator",
|
354
|
+
validator_path: "/Users/reset/.chef/vialstudios-validator.pem",
|
355
|
+
ssh: {
|
356
|
+
user: "vagrant",
|
357
|
+
password: "vagrant"
|
358
|
+
}
|
359
|
+
)
|
360
|
+
|
361
|
+
conn.node.bootstrap("33.33.33.10", "33.33.33.11")
|
362
|
+
|
348
363
|
# Authors and Contributors
|
349
364
|
|
350
365
|
* Jamie Winsor (<jamie@vialstudios.com>)
|
data/Thorfile
CHANGED
@@ -5,25 +5,28 @@ require 'bundler'
|
|
5
5
|
require 'bundler/setup'
|
6
6
|
|
7
7
|
require 'ridley'
|
8
|
-
require 'thor/rake_compat'
|
9
8
|
|
10
9
|
class Default < Thor
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
unless jruby?
|
11
|
+
require 'thor/rake_compat'
|
12
|
+
|
13
|
+
include Thor::RakeCompat
|
14
|
+
Bundler::GemHelper.install_tasks
|
15
|
+
|
16
|
+
desc "build", "Build ridley-#{Ridley::VERSION}.gem into the pkg directory"
|
17
|
+
def build
|
18
|
+
Rake::Task["build"].execute
|
19
|
+
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
desc "install", "Build and install ridley-#{Ridley::VERSION}.gem into system gems"
|
22
|
+
def install
|
23
|
+
Rake::Task["install"].execute
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
desc "release", "Create tag v#{Ridley::VERSION} and build and push ridley-#{Ridley::VERSION}.gem to Rubygems"
|
27
|
+
def release
|
28
|
+
Rake::Task["release"].execute
|
29
|
+
end
|
27
30
|
end
|
28
31
|
|
29
32
|
class Spec < Thor
|
@@ -0,0 +1,73 @@
|
|
1
|
+
bash -c '
|
2
|
+
<%= "export http_proxy=\"#{bootstrap_proxy}\"" if bootstrap_proxy -%>
|
3
|
+
|
4
|
+
exists() {
|
5
|
+
if command -v $1 &>/dev/null
|
6
|
+
then
|
7
|
+
return 0
|
8
|
+
else
|
9
|
+
return 1
|
10
|
+
fi
|
11
|
+
}
|
12
|
+
|
13
|
+
install_sh="http://opscode.com/chef/install.sh"
|
14
|
+
version_string="-v <%= chef_version %>"
|
15
|
+
|
16
|
+
if ! exists /usr/bin/chef-client; then
|
17
|
+
if exists wget; then
|
18
|
+
bash <(wget <%= "--proxy=on " if bootstrap_proxy %> ${install_sh} -O -) ${version_string}
|
19
|
+
else
|
20
|
+
if exists curl; then
|
21
|
+
bash <(curl -L <%= "--proxy=on " if bootstrap_proxy %> ${install_sh}) ${version_string}
|
22
|
+
fi
|
23
|
+
fi
|
24
|
+
fi
|
25
|
+
|
26
|
+
mkdir -p /etc/chef
|
27
|
+
|
28
|
+
(
|
29
|
+
cat <<'EOP'
|
30
|
+
<%= validation_key %>
|
31
|
+
EOP
|
32
|
+
) > /tmp/validation.pem
|
33
|
+
awk NF /tmp/validation.pem > /etc/chef/validation.pem
|
34
|
+
rm /tmp/validation.pem
|
35
|
+
chmod 0600 /etc/chef/validation.pem
|
36
|
+
|
37
|
+
<% if encrypted_data_bag_secret -%>
|
38
|
+
(
|
39
|
+
cat <<'EOP'
|
40
|
+
<%= encrypted_data_bag_secret %>
|
41
|
+
EOP
|
42
|
+
) > /tmp/encrypted_data_bag_secret
|
43
|
+
awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret
|
44
|
+
rm /tmp/encrypted_data_bag_secret
|
45
|
+
chmod 0600 /etc/chef/encrypted_data_bag_secret
|
46
|
+
<% end -%>
|
47
|
+
|
48
|
+
<%# Generate Ohai Hints -%>
|
49
|
+
<% unless hints.empty? -%>
|
50
|
+
mkdir -p /etc/chef/ohai/hints
|
51
|
+
|
52
|
+
<% hints.each do |name, hash| -%>
|
53
|
+
(
|
54
|
+
cat <<'EOP'
|
55
|
+
<%= hash.to_json %>
|
56
|
+
EOP
|
57
|
+
) > /etc/chef/ohai/hints/<%= name %>.json
|
58
|
+
<% end -%>
|
59
|
+
<% end -%>
|
60
|
+
|
61
|
+
(
|
62
|
+
cat <<'EOP'
|
63
|
+
<%= chef_config %>
|
64
|
+
EOP
|
65
|
+
) > /etc/chef/client.rb
|
66
|
+
|
67
|
+
(
|
68
|
+
cat <<'EOP'
|
69
|
+
<%= first_boot %>
|
70
|
+
EOP
|
71
|
+
) > /etc/chef/first-boot.json
|
72
|
+
|
73
|
+
<%= chef_run %>'
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
|
3
|
+
module Ridley
|
4
|
+
class Bootstrapper
|
5
|
+
# @author Jamie Winsor <jamie@vialstudios.com>
|
6
|
+
class Context
|
7
|
+
class << self
|
8
|
+
def validate_options(options = {})
|
9
|
+
if options[:server_url].nil?
|
10
|
+
raise Errors::ArgumentError, "A server_url is required for bootstrapping"
|
11
|
+
end
|
12
|
+
|
13
|
+
if options[:validator_path].nil?
|
14
|
+
raise Errors::ArgumentError, "A path to a validator is required for bootstrapping"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
attr_reader :host
|
21
|
+
# @return [String]
|
22
|
+
attr_reader :node_name
|
23
|
+
# @return [String]
|
24
|
+
attr_reader :server_url
|
25
|
+
# @return [String]
|
26
|
+
attr_reader :validator_client
|
27
|
+
# @return [String]
|
28
|
+
attr_reader :validator_path
|
29
|
+
# @return [String]
|
30
|
+
attr_reader :bootstrap_proxy
|
31
|
+
# @return [Hash]
|
32
|
+
attr_reader :hints
|
33
|
+
# @return [String]
|
34
|
+
attr_reader :chef_version
|
35
|
+
# @return [String]
|
36
|
+
attr_reader :environment
|
37
|
+
|
38
|
+
# @param [String] host
|
39
|
+
# name of the node as identified in Chef
|
40
|
+
# @option options [String] :validator_path
|
41
|
+
# filepath to the validator used to bootstrap the node (required)
|
42
|
+
# @option options [String] :node_name
|
43
|
+
# @option options [String] :server_url
|
44
|
+
# @option options [String] :validator_client
|
45
|
+
# @option options [String] :bootstrap_proxy
|
46
|
+
# URL to a proxy server to bootstrap through (default: nil)
|
47
|
+
# @option options [String] :encrypted_data_bag_secret_path
|
48
|
+
# filepath on your host machine to your organizations encrypted data bag secret (default: nil)
|
49
|
+
# @option options [Hash] :hints
|
50
|
+
# a hash of Ohai hints to place on the bootstrapped node (default: Hash.new)
|
51
|
+
# @option options [Hash] :attributes
|
52
|
+
# a hash of attributes to use in the first Chef run (default: Hash.new)
|
53
|
+
# @option options [Array] :run_list
|
54
|
+
# an initial run list to bootstrap with (default: Array.new)
|
55
|
+
# @option options [String] :chef_version
|
56
|
+
# version of Chef to install on the node (default: {Ridley::CHEF_VERSION})
|
57
|
+
# @option options [String] :environment
|
58
|
+
# environment to join the node to (default: '_default')
|
59
|
+
# @option options [Boolean] :sudo
|
60
|
+
# bootstrap with sudo (default: true)
|
61
|
+
# @option options [String] :template
|
62
|
+
# bootstrap template to use (default: omnibus)
|
63
|
+
def initialize(host, options = {})
|
64
|
+
self.class.validate_options(options)
|
65
|
+
|
66
|
+
@host = host
|
67
|
+
@server_url = options[:server_url]
|
68
|
+
@validator_path = options[:validator_path]
|
69
|
+
@node_name = options[:node_name]
|
70
|
+
@validator_client = options[:validator_client] || "chef-validator"
|
71
|
+
@bootstrap_proxy = options[:bootstrap_proxy]
|
72
|
+
@encrypted_data_bag_secret_path = options[:encrypted_data_bag_secret_path]
|
73
|
+
@hints = options[:hints] || Hash.new
|
74
|
+
@attributes = options[:attributes] || Hash.new
|
75
|
+
@run_list = options[:run_list] || Array.new
|
76
|
+
@chef_version = options[:chef_version] || Ridley::CHEF_VERSION
|
77
|
+
@environment = options[:environment] || "_default"
|
78
|
+
@sudo = options[:sudo] || true
|
79
|
+
@template_file = options[:template] || Bootstrapper.default_template
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [String]
|
83
|
+
def boot_command
|
84
|
+
cmd = template.evaluate(self)
|
85
|
+
|
86
|
+
if sudo
|
87
|
+
cmd = "sudo #{cmd}"
|
88
|
+
end
|
89
|
+
|
90
|
+
cmd
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [String]
|
94
|
+
def clean_command
|
95
|
+
"rm /etc/chef/first-boot.json; rm /etc/chef/validation.pem"
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [String]
|
99
|
+
def chef_run
|
100
|
+
"chef-client -j /etc/chef/first-boot.json -E #{environment}"
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [String]
|
104
|
+
def chef_config
|
105
|
+
body = <<-CONFIG
|
106
|
+
log_level :info
|
107
|
+
log_location STDOUT
|
108
|
+
chef_server_url "#{server_url}"
|
109
|
+
validation_client_name "#{validator_client}"
|
110
|
+
CONFIG
|
111
|
+
|
112
|
+
if node_name.present?
|
113
|
+
body << %Q{node_name "#{node_name}"\n}
|
114
|
+
else
|
115
|
+
body << "# Using default node name (fqdn)\n"
|
116
|
+
end
|
117
|
+
|
118
|
+
if bootstrap_proxy.present?
|
119
|
+
body << %Q{http_proxy "#{bootstrap_proxy}"\n}
|
120
|
+
body << %Q{https_proxy "#{bootstrap_proxy}"\n}
|
121
|
+
end
|
122
|
+
|
123
|
+
if encrypted_data_bag_secret.present?
|
124
|
+
body << %Q{encrypted_data_bag_secret "/etc/chef/encrypted_data_bag_secret"\n}
|
125
|
+
end
|
126
|
+
|
127
|
+
body
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [String]
|
131
|
+
def first_boot
|
132
|
+
attributes.merge(run_list: run_list).to_json
|
133
|
+
end
|
134
|
+
|
135
|
+
# The validation key to create a new client for the node
|
136
|
+
#
|
137
|
+
# @raise [Ridley::Errors::ValidatorNotFound]
|
138
|
+
#
|
139
|
+
# @return [String]
|
140
|
+
def validation_key
|
141
|
+
IO.read(validator_path).chomp
|
142
|
+
rescue Errno::ENOENT
|
143
|
+
raise Errors::ValidatorNotFound, "Error bootstrapping: Validator not found at '#{validator_path}'"
|
144
|
+
end
|
145
|
+
|
146
|
+
# @raise [Ridley::Errors::EncryptedDataBagSecretNotFound]
|
147
|
+
#
|
148
|
+
# @return [String, nil]
|
149
|
+
def encrypted_data_bag_secret
|
150
|
+
return nil if encrypted_data_bag_secret_path.nil?
|
151
|
+
|
152
|
+
IO.read(encrypted_data_bag_secret_path).chomp
|
153
|
+
rescue Errno::ENOENT => encrypted_data_bag_secret
|
154
|
+
raise Errors::EncryptedDataBagSecretNotFound, "Error bootstrapping: Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}"
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
attr_reader :sudo
|
160
|
+
attr_reader :template_file
|
161
|
+
attr_reader :encrypted_data_bag_secret_path
|
162
|
+
attr_reader :validator_path
|
163
|
+
attr_reader :run_list
|
164
|
+
attr_reader :attributes
|
165
|
+
|
166
|
+
# @return [Erubis::Eruby]
|
167
|
+
def template
|
168
|
+
Erubis::Eruby.new(IO.read(template_file).chomp)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Ridley
|
2
|
+
# @author Jamie Winsor <jamie@vialstudios.com>
|
3
|
+
class Bootstrapper
|
4
|
+
autoload :Context, 'ridley/bootstrapper/context'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# @return [Pathname]
|
8
|
+
def templates_path
|
9
|
+
Ridley.root.join('bootstrappers')
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
def default_template
|
14
|
+
templates_path.join('omnibus.erb').to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
include Celluloid
|
19
|
+
include Celluloid::Logger
|
20
|
+
|
21
|
+
# @return [Array<String>]
|
22
|
+
attr_reader :hosts
|
23
|
+
|
24
|
+
# @return [Array<Bootstrapper::Context>]
|
25
|
+
attr_reader :contexts
|
26
|
+
|
27
|
+
# @return [Hash]
|
28
|
+
attr_reader :ssh_config
|
29
|
+
|
30
|
+
# @param [Array<#to_s>] hosts
|
31
|
+
# @option options [String] :ssh_user
|
32
|
+
# @option options [String] :ssh_password
|
33
|
+
# @option options [Array<String>, String] :ssh_keys
|
34
|
+
# @option options [Float] :ssh_timeout
|
35
|
+
# timeout value for SSH bootstrap (default: 1.5)
|
36
|
+
# @option options [String] :validator_client
|
37
|
+
# @option options [String] :validator_path
|
38
|
+
# filepath to the validator used to bootstrap the node (required)
|
39
|
+
# @option options [String] :bootstrap_proxy
|
40
|
+
# URL to a proxy server to bootstrap through (default: nil)
|
41
|
+
# @option options [String] :encrypted_data_bag_secret_path
|
42
|
+
# filepath on your host machine to your organizations encrypted data bag secret (default: nil)
|
43
|
+
# @option options [Hash] :hints
|
44
|
+
# a hash of Ohai hints to place on the bootstrapped node (default: Hash.new)
|
45
|
+
# @option options [Hash] :attributes
|
46
|
+
# a hash of attributes to use in the first Chef run (default: Hash.new)
|
47
|
+
# @option options [Array] :run_list
|
48
|
+
# an initial run list to bootstrap with (default: Array.new)
|
49
|
+
# @option options [String] :chef_version
|
50
|
+
# version of Chef to install on the node (default: {Ridley::CHEF_VERSION})
|
51
|
+
# @option options [String] :environment
|
52
|
+
# environment to join the node to (default: '_default')
|
53
|
+
# @option options [Boolean] :sudo
|
54
|
+
# bootstrap with sudo (default: true)
|
55
|
+
# @option options [String] :template
|
56
|
+
# bootstrap template to use (default: omnibus)
|
57
|
+
def initialize(hosts, options = {})
|
58
|
+
@hosts = Array(hosts).collect(&:to_s).uniq
|
59
|
+
@ssh_config = {
|
60
|
+
user: options.fetch(:ssh_user),
|
61
|
+
password: options[:ssh_password],
|
62
|
+
keys: options[:ssh_keys],
|
63
|
+
timeout: (options[:ssh_timeout] || 1.5)
|
64
|
+
}
|
65
|
+
|
66
|
+
@contexts = @hosts.collect do |host|
|
67
|
+
Context.new(host, options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [SSH::ResponseSet]
|
72
|
+
def run
|
73
|
+
if contexts.length >= 2
|
74
|
+
pool = SSH::Worker.pool(size: contexts.length, args: [self.ssh_config])
|
75
|
+
else
|
76
|
+
pool = SSH::Worker.new(self.ssh_config)
|
77
|
+
end
|
78
|
+
|
79
|
+
responses = contexts.collect do |context|
|
80
|
+
pool.future.run(context.host, context.boot_command)
|
81
|
+
end.collect(&:value)
|
82
|
+
|
83
|
+
SSH::ResponseSet.new.tap do |response_set|
|
84
|
+
responses.each do |message|
|
85
|
+
status, response = message
|
86
|
+
|
87
|
+
case status
|
88
|
+
when :ok
|
89
|
+
response_set.add_ok(response)
|
90
|
+
when :error
|
91
|
+
response_set.add_error(response)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
ensure
|
96
|
+
pool.terminate if pool
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Ridley
|
2
|
+
# @author Jamie Winsor <jamie@vialstudios.com>
|
3
|
+
# @api private
|
4
|
+
class ChainLink
|
5
|
+
attr_reader :parent
|
6
|
+
attr_reader :child
|
7
|
+
|
8
|
+
# @param [Class, Object] parent
|
9
|
+
# the parent class or object to send to the child
|
10
|
+
# @param [Class, Object] child
|
11
|
+
# the child class or instance to delegate functions to
|
12
|
+
def initialize(parent, child)
|
13
|
+
@parent = parent
|
14
|
+
@child = child
|
15
|
+
end
|
16
|
+
|
17
|
+
def new(*args)
|
18
|
+
child.send(:new, parent, *args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(fun, *args, &block)
|
22
|
+
child.send(fun, parent, *args, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ridley/connection.rb
CHANGED
@@ -25,6 +25,11 @@ module Ridley
|
|
25
25
|
attr_reader :client_name
|
26
26
|
attr_reader :client_key
|
27
27
|
attr_reader :organization
|
28
|
+
attr_reader :ssh
|
29
|
+
|
30
|
+
attr_reader :validator_client
|
31
|
+
attr_reader :validator_path
|
32
|
+
attr_reader :encrypted_data_bag_secret_path
|
28
33
|
|
29
34
|
attr_accessor :thread_count
|
30
35
|
|
@@ -35,6 +40,7 @@ module Ridley
|
|
35
40
|
def_delegator :conn, :path_prefix
|
36
41
|
|
37
42
|
def_delegator :conn, :url_prefix=
|
43
|
+
def_delegator :conn, :url_prefix
|
38
44
|
|
39
45
|
def_delegator :conn, :get
|
40
46
|
def_delegator :conn, :put
|
@@ -48,7 +54,7 @@ module Ridley
|
|
48
54
|
:server_url,
|
49
55
|
:client_name,
|
50
56
|
:client_key
|
51
|
-
]
|
57
|
+
].freeze
|
52
58
|
|
53
59
|
DEFAULT_THREAD_COUNT = 8
|
54
60
|
|
@@ -62,7 +68,15 @@ module Ridley
|
|
62
68
|
# @option options [String] :organization
|
63
69
|
# the Organization to connect to. This is only used if you are connecting to
|
64
70
|
# private Chef or hosted Chef
|
71
|
+
# @option options [String] :validator_client
|
72
|
+
# (default: nil)
|
73
|
+
# @option options [String] :validator_path
|
74
|
+
# (default: nil)
|
75
|
+
# @option options [String] :encrypted_data_bag_secret_path
|
76
|
+
# (default: nil)
|
65
77
|
# @option options [Integer] :thread_count
|
78
|
+
# @option options [Hash] :ssh
|
79
|
+
# authentication credentials for bootstrapping or connecting to nodes (default: Hash.new)
|
66
80
|
# @option options [Hash] :params
|
67
81
|
# URI query unencoded key/value pairs
|
68
82
|
# @option options [Hash] :headers
|
@@ -76,10 +90,14 @@ module Ridley
|
|
76
90
|
def initialize(options = {})
|
77
91
|
self.class.validate_options(options)
|
78
92
|
|
79
|
-
@client_name
|
80
|
-
@client_key
|
81
|
-
@organization
|
82
|
-
@thread_count
|
93
|
+
@client_name = options.fetch(:client_name)
|
94
|
+
@client_key = options.fetch(:client_key)
|
95
|
+
@organization = options[:organization]
|
96
|
+
@thread_count = (options[:thread_count] || DEFAULT_THREAD_COUNT)
|
97
|
+
@ssh = (options[:ssh] || Hash.new)
|
98
|
+
@validator_client = options[:validator_client]
|
99
|
+
@validator_path = options[:validator_path]
|
100
|
+
@encrypted_data_bag_secret_path = options[:encrypted_data_bag_secret_path]
|
83
101
|
|
84
102
|
unless @client_key.present? && File.exist?(@client_key)
|
85
103
|
raise Errors::ClientKeyFileNotFound, "client key not found at: '#{@client_key}'"
|
@@ -134,6 +152,10 @@ module Ridley
|
|
134
152
|
api_type == :foss
|
135
153
|
end
|
136
154
|
|
155
|
+
def server_url
|
156
|
+
self.url_prefix.to_s
|
157
|
+
end
|
158
|
+
|
137
159
|
private
|
138
160
|
|
139
161
|
attr_reader :conn
|
data/lib/ridley/errors.rb
CHANGED
@@ -3,6 +3,9 @@ module Ridley
|
|
3
3
|
module Errors
|
4
4
|
class RidleyError < StandardError; end
|
5
5
|
class InternalError < RidleyError; end
|
6
|
+
class ArgumentError < InternalError; end
|
7
|
+
|
8
|
+
class ValidatorNotFound < RidleyError; end
|
6
9
|
|
7
10
|
class InvalidResource < RidleyError
|
8
11
|
attr_reader :errors
|
@@ -17,7 +20,9 @@ module Ridley
|
|
17
20
|
alias_method :to_s, :message
|
18
21
|
end
|
19
22
|
|
20
|
-
class
|
23
|
+
class BootstrapError < RidleyError; end
|
24
|
+
class ClientKeyFileNotFound < BootstrapError; end
|
25
|
+
class EncryptedDataBagSecretNotFound < BootstrapError; end
|
21
26
|
|
22
27
|
class HTTPError < RidleyError
|
23
28
|
class << self
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Ridley
|
4
|
+
# @author Jamie Winsor <jamie@vialstudios.com>
|
5
|
+
module Logging
|
6
|
+
class << self
|
7
|
+
# @return [Logger]
|
8
|
+
def logger
|
9
|
+
@logger ||= begin
|
10
|
+
log = Logger.new(STDOUT)
|
11
|
+
log.level = Logger::INFO
|
12
|
+
log
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [Logger, nil] obj
|
17
|
+
#
|
18
|
+
# @return [Logger]
|
19
|
+
def set_logger(obj)
|
20
|
+
@logger = (obj.nil? ? Logger.new('/dev/null') : obj)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Logger]
|
25
|
+
def logger
|
26
|
+
Ridley::Logging.logger
|
27
|
+
end
|
28
|
+
alias_method :log, :logger
|
29
|
+
end
|
30
|
+
end
|
@@ -64,12 +64,12 @@ module Ridley
|
|
64
64
|
# Coerces instance functions into class functions on Ridley::Client. This coercion
|
65
65
|
# sends an instance of the including class along to the class function.
|
66
66
|
#
|
67
|
-
# @see Ridley::
|
67
|
+
# @see Ridley::ChainLink
|
68
68
|
#
|
69
|
-
# @return [Ridley::
|
69
|
+
# @return [Ridley::ChainLink]
|
70
70
|
# a context object to delegate instance functions to class functions on Ridley::Client
|
71
71
|
def client
|
72
|
-
|
72
|
+
ChainLink.new(self, Ridley::Client)
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
@@ -42,12 +42,12 @@ module Ridley
|
|
42
42
|
# Coerces instance functions into class functions on Ridley::Cookbook. This coercion
|
43
43
|
# sends an instance of the including class along to the class function.
|
44
44
|
#
|
45
|
-
# @see Ridley::
|
45
|
+
# @see Ridley::ChainLink
|
46
46
|
#
|
47
|
-
# @return [Ridley::
|
47
|
+
# @return [Ridley::ChainLink]
|
48
48
|
# a context object to delegate instance functions to class functions on Ridley::Cookbook
|
49
49
|
def cookbook
|
50
|
-
|
50
|
+
ChainLink.new(self, Ridley::Cookbook)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|