chef-metal 0.3.1 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -1
- data/lib/chef/provider/fog_key_pair.rb +16 -0
- data/lib/chef_metal/aws_credentials.rb +8 -5
- data/lib/chef_metal/fog.rb +5 -1
- data/lib/chef_metal/machine/unix_machine.rb +4 -4
- data/lib/chef_metal/openstack_credentials.rb +44 -0
- data/lib/chef_metal/provisioner/fog_provisioner.rb +115 -8
- data/lib/chef_metal/recipe_dsl.rb +1 -1
- data/lib/chef_metal/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93940616771e3e091f441bce2587a1383f7859ef
|
4
|
+
data.tar.gz: 8e49d7a64afdc1fe06c82b99056accc1b4ae587c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1815d8c7b09c9fdb5fa68bcea2282abe2253bb71e4d3345c12b75774e545dea7532ddb45772f428b4c65b4361fb9006b45e633d12c80cdd780860f89b9b06886
|
7
|
+
data.tar.gz: 5bf3f00b97b72d98a9fcbf962c99bcb201afc696ae7ed25f9ef023234442e16cfab6e1a5e0d4256554a4ad3769f881b986be6593ebfb637624361708c2cd77e8
|
data/README.md
CHANGED
@@ -92,7 +92,16 @@ end
|
|
92
92
|
|
93
93
|
`vagrant_box` makes sure a particular vagrant box exists, and lets you specify `provisioner_options` for things like port forwarding, OS definitions, and any other vagrant-isms. A more complicated vagrant box, with provisioner options, can be found in [myapp::windows](https://github.com/opscode/chef-metal/blob/master/cookbooks/myapp/recipes/windows.rb).
|
94
94
|
|
95
|
-
`with_chef_local_server` is a generic directive that creates a chef-zero server pointed at the given repository. nodes, clients, data bags, and all data will be stored here on your provisioner machine if you do this. You can use `with_chef_server` instead if you want to point at OSS, Hosted or Enterprise Chef, and if you don't specify a Chef server at all, it will use the one you are running chef-client against.
|
95
|
+
`with_chef_local_server` is a generic directive that creates a chef-zero server pointed at the given repository. nodes, clients, data bags, and all data will be stored here on your provisioner machine if you do this. You can use `with_chef_server` instead if you want to point at OSS, Hosted or Enterprise Chef, and if you don't specify a Chef server at all, it will use the one you are running chef-client against. Keep in mind when using `with_chef_server` and running `chef-client -z` on your workstation that you will also need to set the client name and signing key for the chef server. If you've already got knife.rb set up, then something like this will correctly create a client for the chef server on instance using your knife.rb configuration:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
require 'chef/config'
|
99
|
+
|
100
|
+
with_chef_server "https://chef-server.example.org", {
|
101
|
+
:client_name => Chef::Config[:node_name],
|
102
|
+
:signing_key_filename => Chef::Config[:client_key]
|
103
|
+
}
|
104
|
+
```
|
96
105
|
|
97
106
|
Typically, you declare these in separate files from your machine resources. Chef Metal picks up the provisioners you have declared, and uses them to instantiate the machines you request. The actual machine definitions, in this case, are in `myapp::small`, and are generic--you could use them against EC2 as well:
|
98
107
|
|
@@ -150,6 +159,18 @@ To pass options like ami, you can say something like this:
|
|
150
159
|
with_provisioner_options :image_id => 'ami-5ee70037'
|
151
160
|
```
|
152
161
|
|
162
|
+
If you need to pass bootstrapping options on a per-machine basis, you can do that as well by doing something like the following:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
machine "Ubuntu_64bit" do
|
166
|
+
action :create
|
167
|
+
provisioner_options 'bootstrap_options' => {
|
168
|
+
'image_id' => 'ami-59a4a230',
|
169
|
+
'flavor_id' => 't1.micro'
|
170
|
+
}
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
153
174
|
You will notice that we are still using `myapp::small` here. Machine definitions are generally provisioner-independent. This is an important feature that allows you to spin up your clusters in different places to create staging, test or miniature dev environments.
|
154
175
|
|
155
176
|
Bugs and The Plan
|
@@ -18,6 +18,8 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
|
18
18
|
case new_resource.provisioner.compute_options[:provider]
|
19
19
|
when 'DigitalOcean'
|
20
20
|
compute.destroy_key_pair(@current_id)
|
21
|
+
when 'OpenStack'
|
22
|
+
compute.key_pairs.destroy(@current_id)
|
21
23
|
else
|
22
24
|
compute.key_pairs.delete(new_resource.name)
|
23
25
|
end
|
@@ -45,6 +47,8 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
|
45
47
|
new_fingerprint = case new_resource.provisioner.compute_options[:provider]
|
46
48
|
when 'DigitalOcean'
|
47
49
|
Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)
|
50
|
+
when 'OpenStack'
|
51
|
+
Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)
|
48
52
|
else
|
49
53
|
Cheffish::KeyFormatter.encode(desired_key, :format => :fingerprint)
|
50
54
|
end
|
@@ -55,6 +59,8 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
|
55
59
|
case new_resource.provisioner.compute_options[:provider]
|
56
60
|
when 'DigitalOcean'
|
57
61
|
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
62
|
+
when 'OpenStack'
|
63
|
+
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
58
64
|
else
|
59
65
|
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
60
66
|
end
|
@@ -72,6 +78,8 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
|
72
78
|
case new_resource.provisioner.compute_options[:provider]
|
73
79
|
when 'DigitalOcean'
|
74
80
|
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
81
|
+
when 'OpenStack'
|
82
|
+
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
75
83
|
else
|
76
84
|
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
77
85
|
end
|
@@ -131,6 +139,14 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
|
131
139
|
else
|
132
140
|
current_resource.action :delete
|
133
141
|
end
|
142
|
+
when 'OpenStack'
|
143
|
+
current_key_pair = compute.key_pairs.get(new_resource.name)
|
144
|
+
if current_key_pair
|
145
|
+
@current_id = current_key_pair.name
|
146
|
+
@current_fingerprint = current_key_pair ? compute.key_pairs.get(@current_id).public_key : nil
|
147
|
+
else
|
148
|
+
current_resource.action :delete
|
149
|
+
end
|
134
150
|
else
|
135
151
|
current_key_pair = compute.key_pairs.get(new_resource.name)
|
136
152
|
if current_key_pair
|
@@ -21,11 +21,14 @@ module ChefMetal
|
|
21
21
|
require 'inifile'
|
22
22
|
inifile = IniFile.load(File.expand_path(credentials_ini_file))
|
23
23
|
inifile.each_section do |section|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
if section =~ /^\s*profile\s+(.+)$/ || section =~ /^\s*(default)\s*/
|
25
|
+
profile = $1.strip
|
26
|
+
@credentials[profile] = {
|
27
|
+
:access_key_id => inifile[section]['aws_access_key_id'],
|
28
|
+
:secret_access_key => inifile[section]['aws_secret_access_key'],
|
29
|
+
:region => inifile[section]['region']
|
30
|
+
}
|
31
|
+
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
data/lib/chef_metal/fog.rb
CHANGED
@@ -6,11 +6,15 @@ require 'chef_metal/provisioner/fog_provisioner'
|
|
6
6
|
class Chef
|
7
7
|
class Recipe
|
8
8
|
def with_fog_provisioner(options = {}, &block)
|
9
|
-
ChefMetal.with_provisioner(ChefMetal::Provisioner::FogProvisioner.new(options, &block)
|
9
|
+
ChefMetal.with_provisioner(ChefMetal::Provisioner::FogProvisioner.new(options), &block)
|
10
10
|
end
|
11
11
|
|
12
12
|
def with_fog_ec2_provisioner(options = {}, &block)
|
13
13
|
with_fog_provisioner({ :provider => 'AWS' }.merge(options), &block)
|
14
14
|
end
|
15
|
+
|
16
|
+
def with_fog_openstack_provisioner(options = {}, &block)
|
17
|
+
with_fog_provisioner({ :provider => 'OpenStack' }.merge(options), &block)
|
18
|
+
end
|
15
19
|
end
|
16
20
|
end
|
@@ -162,8 +162,8 @@ elif test -f "/etc/debian_version"; then
|
|
162
162
|
platform="debian"
|
163
163
|
platform_version=`cat /etc/debian_version`
|
164
164
|
elif test -f "/etc/redhat-release"; then
|
165
|
-
platform=`sed 's
|
166
|
-
platform_version=`sed 's
|
165
|
+
platform=`sed 's/^\\(.\\+\\) release.*/\\1/' /etc/redhat-release | tr '[A-Z]' '[a-z]'`
|
166
|
+
platform_version=`sed 's/^.\\+ release \\([.0-9]\\+\\).*/\\1/' /etc/redhat-release`
|
167
167
|
|
168
168
|
# If /etc/redhat-release exists, we act like RHEL by default
|
169
169
|
if test "$platform" = "fedora"; then
|
@@ -172,8 +172,8 @@ platform_version="6.0"
|
|
172
172
|
fi
|
173
173
|
platform="el"
|
174
174
|
elif test -f "/etc/system-release"; then
|
175
|
-
platform=`sed 's
|
176
|
-
platform_version=`sed 's
|
175
|
+
platform=`sed 's/^\\(.\\+\\) release.\\+/\\1/' /etc/system-release | tr '[A-Z]' '[a-z]'`
|
176
|
+
platform_version=`sed 's/^.\\+ release \\([.0-9]\\+\\).*/\\1/' /etc/system-release | tr '[A-Z]' '[a-z]'`
|
177
177
|
# amazon is built off of fedora, so act like RHEL
|
178
178
|
if test "$platform" = "amazon linux ami"; then
|
179
179
|
platform="el"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ChefMetal
|
2
|
+
# Reads in a credentials file
|
3
|
+
class OpenstackCredentials
|
4
|
+
def initialize
|
5
|
+
@credentials = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def default
|
9
|
+
@credentials['default'] || @credentials.first[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def keys
|
13
|
+
@credentials.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](name)
|
17
|
+
@credentials[name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_yaml(credentials_yaml_file)
|
21
|
+
creds_file = YAML.load_file(File.expand_path(credentials_yaml_file))
|
22
|
+
creds_file.each do |section, creds|
|
23
|
+
@credentials[section] = {
|
24
|
+
:openstack_username => creds_file[section]['openstack_username'],
|
25
|
+
:openstack_api_key => creds_file[section]['openstack_api_key'],
|
26
|
+
:openstack_tenant => creds_file[section]['openstack_tenant'],
|
27
|
+
:openstack_auth_url => creds_file[section]['openstack_auth_url']
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_default
|
33
|
+
load_yaml('~/.fog')
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.method_missing(name, *args, &block)
|
37
|
+
singleton.send(name, *args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.singleton
|
41
|
+
@openstack_credentials ||= OpenstackCredentials.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'chef_metal/provisioner'
|
2
2
|
require 'chef_metal/aws_credentials'
|
3
|
+
require 'chef_metal/openstack_credentials'
|
4
|
+
require 'chef_metal/version'
|
3
5
|
|
4
6
|
module ChefMetal
|
5
7
|
class Provisioner
|
@@ -32,7 +34,9 @@ module ChefMetal
|
|
32
34
|
# - :ssh_timeout - the time to wait for ssh to be available if the instance is detected as up (defaults to 20)
|
33
35
|
def initialize(compute_options)
|
34
36
|
@base_bootstrap_options = compute_options.delete(:base_bootstrap_options) || {}
|
35
|
-
|
37
|
+
|
38
|
+
case compute_options[:provider]
|
39
|
+
when 'AWS'
|
36
40
|
aws_credentials = compute_options.delete(:aws_credentials)
|
37
41
|
if aws_credentials
|
38
42
|
@aws_credentials = aws_credentials
|
@@ -42,6 +46,19 @@ module ChefMetal
|
|
42
46
|
end
|
43
47
|
compute_options[:aws_access_key_id] ||= @aws_credentials.default[:access_key_id]
|
44
48
|
compute_options[:aws_secret_access_key] ||= @aws_credentials.default[:secret_access_key]
|
49
|
+
when 'OpenStack'
|
50
|
+
openstack_credentials = compute_options.delete(:openstack_credentials)
|
51
|
+
if openstack_credentials
|
52
|
+
@openstack_credentials = openstack_credentials
|
53
|
+
else
|
54
|
+
@openstack_credentials = ChefMetal::OpenstackCredentials.new
|
55
|
+
@openstack_credentials.load_default
|
56
|
+
end
|
57
|
+
|
58
|
+
compute_options[:openstack_username] ||= @openstack_credentials.default[:openstack_username]
|
59
|
+
compute_options[:openstack_api_key] ||= @openstack_credentials.default[:openstack_api_key]
|
60
|
+
compute_options[:openstack_auth_url] ||= @openstack_credentials.default[:openstack_auth_url]
|
61
|
+
compute_options[:openstack_tenant] ||= @openstack_credentials.default[:openstack_tenant]
|
45
62
|
end
|
46
63
|
@key_pairs = {}
|
47
64
|
@compute_options = compute_options
|
@@ -50,6 +67,7 @@ module ChefMetal
|
|
50
67
|
|
51
68
|
attr_reader :compute_options
|
52
69
|
attr_reader :aws_credentials
|
70
|
+
attr_reader :openstack_credentials
|
53
71
|
attr_reader :key_pairs
|
54
72
|
|
55
73
|
def current_base_bootstrap_options
|
@@ -89,7 +107,7 @@ module ChefMetal
|
|
89
107
|
# Example bootstrap_options for ec2:
|
90
108
|
# :image_id =>'ami-311f2b45',
|
91
109
|
# :flavor_id =>'t1.micro',
|
92
|
-
# :key_name => '
|
110
|
+
# :key_name => 'key-pair-name'
|
93
111
|
#
|
94
112
|
# node['normal']['provisioner_output'] will be populated with information
|
95
113
|
# about the created machine. For vagrant, it is a hash with this
|
@@ -100,13 +118,21 @@ module ChefMetal
|
|
100
118
|
#
|
101
119
|
def acquire_machine(provider, node)
|
102
120
|
# Set up the modified node data
|
103
|
-
provisioner_options = node['normal']['provisioner_options'] || {}
|
104
121
|
provisioner_output = node['normal']['provisioner_output'] || {
|
105
|
-
'provisioner_url' => provisioner_url
|
122
|
+
'provisioner_url' => provisioner_url,
|
123
|
+
'provisioner_version' => ChefMetal::VERSION,
|
124
|
+
'creator' => aws_login_info[1]
|
106
125
|
}
|
107
126
|
|
108
127
|
if provisioner_output['provisioner_url'] != provisioner_url
|
109
|
-
|
128
|
+
if (provisioner_output['provisioner_version'].to_f <= 0.3) && provisioner_output['provisioner_url'].start_with?('fog:AWS:') && compute_options[:provider] == 'AWS'
|
129
|
+
Chef::Log.warn "The upgrade from chef-metal 0.3 to 0.4 changed the provisioner URL format! Metal will assume you are in fact using the same AWS account, and modify the provisioner URL to match."
|
130
|
+
provisioner_output['provisioner_url'] = provisioner_url
|
131
|
+
provisioner_output['provisioner_version'] ||= ChefMetal::VERSION
|
132
|
+
provisioner_output['creator'] ||= aws_login_info[1]
|
133
|
+
else
|
134
|
+
raise "Switching providers for a machine is not currently supported! Use machine :destroy and then re-create the machine on the new provider."
|
135
|
+
end
|
110
136
|
end
|
111
137
|
|
112
138
|
node['normal']['provisioner_output'] = provisioner_output
|
@@ -143,6 +169,7 @@ module ChefMetal
|
|
143
169
|
if need_to_create
|
144
170
|
# If the server does not exist, create it
|
145
171
|
bootstrap_options = bootstrap_options_for(provider.new_resource, node)
|
172
|
+
bootstrap_options.merge(:name => provider.new_resource.name)
|
146
173
|
|
147
174
|
start_time = Time.now
|
148
175
|
timeout = option_for(node, :create_timeout)
|
@@ -158,8 +185,22 @@ module ChefMetal
|
|
158
185
|
end
|
159
186
|
|
160
187
|
if server
|
188
|
+
@@ip_pool_lock = Mutex.new
|
161
189
|
# Re-retrieve the server in a more malleable form and wait for it to be ready
|
162
190
|
server = compute.servers.get(server.id)
|
191
|
+
if bootstrap_options[:floating_ip_pool]
|
192
|
+
Chef::Log.info 'Attaching IP from pool'
|
193
|
+
server.wait_for { ready? }
|
194
|
+
provider.converge_by "attach floating IP from #{bootstrap_options[:floating_ip_pool]} pool" do
|
195
|
+
attach_ip_from_pool(server, bootstrap_options[:floating_ip_pool])
|
196
|
+
end
|
197
|
+
elsif bootstrap_options[:floating_ip]
|
198
|
+
Chef::Log.info 'Attaching given IP'
|
199
|
+
server.wait_for { ready? }
|
200
|
+
provider.converge_by "attach floating IP #{bootstrap_options[:floating_ip]}" do
|
201
|
+
attach_ip(server, bootstrap_options[:floating_ip])
|
202
|
+
end
|
203
|
+
end
|
163
204
|
provider.converge_by "machine #{node['name']} created as #{server.id} on #{provisioner_url}" do
|
164
205
|
end
|
165
206
|
# Wait for the machine to come up and for ssh to start listening
|
@@ -205,6 +246,31 @@ module ChefMetal
|
|
205
246
|
machine_for(node, server)
|
206
247
|
end
|
207
248
|
|
249
|
+
# Attach IP to machine from IP pool
|
250
|
+
# Code taken from kitchen-openstack driver
|
251
|
+
# https://github.com/test-kitchen/kitchen-openstack/blob/master/lib/kitchen/driver/openstack.rb#L196-L207
|
252
|
+
def attach_ip_from_pool(server, pool)
|
253
|
+
@@ip_pool_lock.synchronize do
|
254
|
+
Chef::Log.info "Attaching floating IP from <#{pool}> pool"
|
255
|
+
free_addrs = compute.addresses.collect do |i|
|
256
|
+
i.ip if i.fixed_ip.nil? and i.instance_id.nil? and i.pool == pool
|
257
|
+
end.compact
|
258
|
+
if free_addrs.empty?
|
259
|
+
raise ActionFailed, "No available IPs in pool <#{pool}>"
|
260
|
+
end
|
261
|
+
attach_ip(server, free_addrs[0])
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Attach given IP to machine
|
266
|
+
# Code taken from kitchen-openstack driver
|
267
|
+
# https://github.com/test-kitchen/kitchen-openstack/blob/master/lib/kitchen/driver/openstack.rb#L209-L213
|
268
|
+
def attach_ip(server, ip)
|
269
|
+
Chef::Log.info "Attaching floating IP <#{ip}>"
|
270
|
+
server.associate_address ip
|
271
|
+
(server.addresses['public'] ||= []) << { 'version' => 4, 'addr' => ip }
|
272
|
+
end
|
273
|
+
|
208
274
|
# Connect to machine without acquiring it
|
209
275
|
def connect_to_machine(node)
|
210
276
|
machine_for(node)
|
@@ -224,7 +290,7 @@ module ChefMetal
|
|
224
290
|
# If the machine doesn't exist, we silently do nothing
|
225
291
|
if node['normal']['provisioner_output'] && node['normal']['provisioner_output']['server_id']
|
226
292
|
server = compute.servers.get(node['normal']['provisioner_output']['server_id'])
|
227
|
-
provider.converge_by "stop machine #{node['name']} (#{server.id} at #{provisioner_url}" do
|
293
|
+
provider.converge_by "stop machine #{node['name']} (#{server.id} at #{provisioner_url})" do
|
228
294
|
server.stop
|
229
295
|
end
|
230
296
|
end
|
@@ -246,9 +312,11 @@ module ChefMetal
|
|
246
312
|
def provisioner_url
|
247
313
|
provider_identifier = case compute_options[:provider]
|
248
314
|
when 'AWS'
|
249
|
-
|
315
|
+
aws_login_info[0]
|
250
316
|
when 'DigitalOcean'
|
251
317
|
compute_options[:digitalocean_client_id]
|
318
|
+
when 'OpenStack'
|
319
|
+
compute_options[:openstack_auth_url]
|
252
320
|
else
|
253
321
|
'???'
|
254
322
|
end
|
@@ -273,6 +341,32 @@ module ChefMetal
|
|
273
341
|
end
|
274
342
|
end
|
275
343
|
|
344
|
+
# Returns [ Account ID, User ]
|
345
|
+
# Account ID is the 12 digit identifier on your Manage Account page in AWS Console. It is used as part of all ARNs identifying resources.
|
346
|
+
# User is an identifier like "root" or "user/username" or "federated-user/username"
|
347
|
+
def aws_login_info
|
348
|
+
@aws_login_info ||= begin
|
349
|
+
iam = Fog::AWS::IAM.new(:aws_access_key_id => compute_options[:aws_access_key_id], :aws_secret_access_key => compute_options[:aws_secret_access_key])
|
350
|
+
arn = begin
|
351
|
+
# TODO it would be nice if Fog let you do this normally ...
|
352
|
+
iam.send(:request, {
|
353
|
+
'Action' => 'GetUser',
|
354
|
+
:parser => Fog::Parsers::AWS::IAM::GetUser.new
|
355
|
+
}).body['User']['Arn']
|
356
|
+
rescue Fog::AWS::IAM::Error
|
357
|
+
# TODO Someone tell me there is a better way to find out your current
|
358
|
+
# user ID than this! This is what happens when you use an IAM user
|
359
|
+
# with default privileges.
|
360
|
+
if $!.message =~ /AccessDenied.+(arn:aws:iam::\d+:\S+)/
|
361
|
+
arn = $1
|
362
|
+
else
|
363
|
+
raise
|
364
|
+
end
|
365
|
+
end
|
366
|
+
arn.split(':')[4..5]
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
276
370
|
def symbolize_keys(options)
|
277
371
|
options.inject({}) { |result,(key,value)| result[key.to_sym] = value; result }
|
278
372
|
end
|
@@ -392,7 +486,20 @@ module ChefMetal
|
|
392
486
|
if compute_options[:sudo] || (!compute_options.has_key?(:sudo) && username != 'root')
|
393
487
|
options[:prefix] = 'sudo '
|
394
488
|
end
|
395
|
-
|
489
|
+
|
490
|
+
remote_host = nil
|
491
|
+
if compute_options[:use_private_ip_for_ssh]
|
492
|
+
remote_host = server.private_ip_address
|
493
|
+
elsif !server.public_ip_address
|
494
|
+
Chef::Log.warn("Server has no public ip address. Using private ip '#{server.private_ip_address}'. Set provisioner option 'use_private_ip_for_ssh' => true if this will always be the case ...")
|
495
|
+
remote_host = server.private_ip_address
|
496
|
+
elsif server.public_ip_address
|
497
|
+
remote_host = server.public_ip_address
|
498
|
+
else
|
499
|
+
raise "Server #{server.id} has no private or public IP address!"
|
500
|
+
end
|
501
|
+
|
502
|
+
ChefMetal::Transport::SSH.new(remote_host, username, ssh_options, options)
|
396
503
|
end
|
397
504
|
|
398
505
|
def wait_until_ready(server, timeout)
|
data/lib/chef_metal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-metal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/chef_metal/machine/unix_machine.rb
|
142
142
|
- lib/chef_metal/machine/windows_machine.rb
|
143
143
|
- lib/chef_metal/machine.rb
|
144
|
+
- lib/chef_metal/openstack_credentials.rb
|
144
145
|
- lib/chef_metal/provisioner/fog_provisioner.rb
|
145
146
|
- lib/chef_metal/provisioner/vagrant_provisioner.rb
|
146
147
|
- lib/chef_metal/provisioner.rb
|