chef-provisioning-fog 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fe75ef2b7b47f463c63d139a34b263eacf4b900
4
- data.tar.gz: d8f13c9f9302f33dc71e234ac8f6e3a830a60d40
3
+ metadata.gz: e48c5dfd96019788e8add883cf24a604e197e3d1
4
+ data.tar.gz: 5f6cdf09bb038c76620ed6492333e3a912ae3a6e
5
5
  SHA512:
6
- metadata.gz: 0da8a4fa982e2d900b5fe83537276c95112280646aa60ce279f7cc2004c82f90fa6b4a1284e3eeb475e0b26c551a0207f2a68e9e81956cdb6229b92815d122a8
7
- data.tar.gz: b16b69e8db0bf1cac20bb1dcad8952d482ad4aadb56a3e7483088c687a909cbf0df7c67f47f7fe23772008d7eb68c8d46815da38a9d60edd1d6e530f95bd152b
6
+ metadata.gz: f2a4be0a7ea606d12f33aa5942fc2c313644fb58dbb564ca804505fc5df774b6d4269a148d69e9987b102bfab86dbe839210a439d1a4f96d5181c5d3f9c05c96
7
+ data.tar.gz: 5a4b1ec56cf012cd0b59d0d4c48c5391b08d08390f67574e47918e1c12b992186fad1929f86c57b8c0a0b7c9b1701da2231c95b984677495a282bcbdddcfb162
data/README.md CHANGED
@@ -19,11 +19,11 @@ These are the primary documents to help learn about using Provisioning and creat
19
19
 
20
20
  ## chef-provisioning-fog Usage and Examples
21
21
 
22
- **A note about key pairs** - The key name used in `fog_key_pair` must be the same as the filename of the local key to be used. If the key does not exist in one of `private_key_paths` (which you can set in knife.rb or in a client.rb) it will be created.
22
+ **A note about key pairs** - The key name used in `fog_key_pair` must be the same as the filename of the local key to be used. If the key does not exist in one of `private_key_paths` (which you can set in `knife.rb` or in a `client.rb`) it will be created.
23
23
 
24
24
  ### DigitalOcean
25
25
 
26
- Update your knife.rb to contain your DigitalOcean API token and the driver
26
+ Update your `knife.rb` to contain your DigitalOcean API token and the driver:
27
27
 
28
28
  ```ruby
29
29
  driver 'fog:DigitalOcean'
@@ -34,14 +34,16 @@ For a full example see [examples/digitalocean/simple.rb](examples/digitalocean/s
34
34
 
35
35
  ### OpenStack
36
36
 
37
- You'll need to update your `knife.rb` to work with this also:
37
+ You'll need to update your `knife.rb` to work:
38
38
 
39
39
  ```ruby
40
40
  driver 'fog:OpenStack'
41
- driver_options :compute_options => { :openstack_auth_url => 'http://YOUROPENSTACK-CLOUD:5000/v2.0/tokens',
42
- :openstack_username => 'YOURUSERNAME',
43
- :openstack_api_key => 'YOURPASSWORD',
44
- :openstack_tenant => 'YOURTENANTIDNAME' }
41
+ driver_options :compute_options => {
42
+ :openstack_auth_url => 'http://YOUROPENSTACK-CLOUD:5000/v2.0/tokens',
43
+ :openstack_username => 'YOUR-USERNAME',
44
+ :openstack_api_key => 'YOUR-PASSWORD',
45
+ :openstack_tenant => 'YOUR-TENANT-ID-NAME'
46
+ }
45
47
  ```
46
48
 
47
49
  For a full example see [examples/openstack/simple.rb](examples/openstack/simple.rb).
@@ -52,16 +54,92 @@ For this example, you must configure `knife.rb` with your credentials and a regi
52
54
 
53
55
  You must configure some credentials and region in a `knife.rb` file like so:
54
56
  ```ruby
55
- driver 'fog:Rackspace'
56
- driver_options :compute_options => {
57
- :rackspace_username => 'my_rackspace_user',
58
- :rackspace_api_key => 'api_key_for_user',
59
- :rackspace_region => 'dfw' # could be 'org', 'iad', 'hkg', etc
60
- }
57
+ driver 'fog:Rackspace'
58
+ driver_options :compute_options => {
59
+ :rackspace_username => 'MY-RACKSPACE-USERr',
60
+ :rackspace_api_key => 'API-KEY-FOR-USER',
61
+ :rackspace_region => 'dfw' # could be 'org', 'iad', 'hkg', etc
62
+ }
61
63
  ```
62
64
 
63
65
  For a full example see [examples/rackspace/simple.rb](examples/rackspace/simple.rb).
64
66
 
67
+ ### Google Compute Engine
68
+
69
+ You'll need to update your `knife.rb` to work:
70
+
71
+ ```ruby
72
+ driver 'fog:Google'
73
+ driver_options :compute_options => { :provider => 'google',
74
+ :google_project => 'YOUR-PROJECT-ID', # the name will work here
75
+ :google_client_email => 'YOUR-SERVICE-ACCOUNT-EMAIL',
76
+ :google_key_location => 'YOUR-SERVICE-P12-KEY-FILE-FULL-PATH.p12'
77
+ }
78
+
79
+ ```
80
+
81
+ In order to get the `YOUR-SERVICE-P12-KEY-FILE.p12` you need to set up a Service
82
+ account. This is located at `Home > Permissions > Service Accounts` and you'll
83
+ need to create a new one to get a new key. After that place it some place such
84
+ as `~/.chef/` so chef-provisioning-fog can find it. Your `google_client_email`
85
+ would be something like: `<UNIQUE_NAME>@<PROJECT>.iam.gserviceaccount.com`.
86
+
87
+ For a full simple example see [examples/google/simple.rb](examples/google/simple.rb).
88
+
89
+ For an example that shows a different `:disk_type` see
90
+ [examples/google/simple_different_disk.rb](examples/google/simple_different_disk.rb).
91
+
92
+ ### Joyent
93
+
94
+ You'll need to update your `knife.rb` to work:
95
+
96
+ ```ruby
97
+ driver 'fog:Joyent'
98
+ driver_options :compute_options => { :joyent_username => 'YOUR-JOYENT-LOGIN',
99
+ :joyent_password => 'YOUR-JOYENT-PASSWORD',
100
+ :joyent_keyname => 'THE-SSH-KEY-YOUVE-UPLOADED',
101
+ :joyent_version => '7.3.0', # if you are using the joyent public cloud
102
+ :joyent_keyfile => 'YOUR-PRIVATE-SSH-KEY-LOCATION' # Such as '/Users/jasghar/.ssh/id_rsa'
103
+ }
104
+ ```
105
+
106
+ Tested this with the [Joyent Public Cloud](https://docs.joyent.com/public-cloud). For the package names, use the
107
+ GUI to find the name(s) that you want to use. This is also required to figure out the Image UUID, there doesn't seem to be an
108
+ effective way of doing this without the GUI.
109
+
110
+ For a more in-depth usage of this driver to use with either Private or Public Joyent cloud, checkout [this blog post][joyent_howto] by mhicks from [#smartos][freenode_smartos] on freenode.
111
+
112
+ For a infrastructure container example see [examples/joyent/infrastructure.rb](examples/joyent/infrastructure.rb).
113
+
114
+ ### IBM SoftLayer
115
+
116
+ You'll need to update your `knife.rb` to work with this also:
117
+
118
+ ```ruby
119
+ driver 'fog:SoftLayer'
120
+ driver_options :compute_options => { :provider => 'softlayer',
121
+ :softlayer_username => 'username',
122
+ :softlayer_api_key => 'api_key',
123
+ :softlayer_default_domain => 'example.com',
124
+ }
125
+
126
+ ```
127
+
128
+ Once you or your administrator has created a SoftLayer account you can manage
129
+ your API key at https://control.softlayer.com/account/users
130
+
131
+ `:bootstrap_options => {:key_name => 'label'}` is looked up by_label; make sure
132
+ you have a public key created on control portal at
133
+ https://control.softlayer.com/devices/sshkeys with a matching label.
134
+
135
+ NOTE: the SoftLayer driver injects a custom post provisioning script that
136
+ ensures some packages needed by chef-provisioning-fog to install chef are
137
+ present (e.g. sudo). The injected script will call your :postInstallScriptUri
138
+ if you define one. The driver will wait until the injected script is done. The
139
+ driver and script communicate using userMetadata so you cannot use metadata.
140
+
141
+ For a full example see [examples/softlayer/simple.rb](examples/softlayer/simple.rb).
142
+
65
143
  ### Cleaning up
66
144
 
67
145
  ```ruby
@@ -177,3 +255,5 @@ with_machine_options({
177
255
  [gem]: https://rubygems.org/gems/chef-provisioning-fog
178
256
  [travis]: https://travis-ci.org/chef/chef-provisioning-fog
179
257
  [gemnasium]: https://gemnasium.com/chef/chef-provisioning-fog
258
+ [joyent_howto]: https://numericillustration.wordpress.com/2015/12/04/using-chef-provisioner-with-the-joyent-smart-data-center/
259
+ [freenode_smartos]: http://webchat.freenode.net/?randomnick=1&channels=smartos&prompt=1
data/Rakefile CHANGED
@@ -4,3 +4,12 @@ require 'bundler/gem_tasks'
4
4
  task :spec do
5
5
  require File.expand_path('spec/run')
6
6
  end
7
+
8
+ require "github_changelog_generator/task"
9
+
10
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
11
+ config.future_release = Chef::Provisioning::FogDriver::VERSION
12
+ config.enhancement_labels = "enhancement,Enhancement,New Feature".split(",")
13
+ config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(",")
14
+ config.exclude_labels = "duplicate,question,invalid,wontfix,no_changelog,Exclude From Changelog,Question".split(",")
15
+ end
@@ -8,16 +8,19 @@ Gem::Specification.new do |s|
8
8
  s.extra_rdoc_files = ['README.md', 'LICENSE' ]
9
9
  s.summary = 'Driver for creating Fog instances in Chef Provisioning.'
10
10
  s.description = s.summary
11
- s.authors = ['John Keiser', "Chris McClimans", "Taylor Carpenter", "Wavell Watson"]
12
- s.email = ['jkeiser@getchef.com', 'hh@vulk.co', 't@vulk.co', 'w@vulk.co']
11
+ s.authors = ['John Keiser', "Chris McClimans", "Taylor Carpenter", "Wavell Watson", "JJ Asghar"]
12
+ s.email = ['jkeiser@getchef.com', 'hh@vulk.co', 't@vulk.co', 'w@vulk.co','jj@chef.io']
13
13
  s.homepage = 'https://github.com/opscode/chef-provisioning-fog'
14
14
 
15
15
  s.add_dependency 'chef-provisioning', '~> 1.0'
16
- s.add_dependency 'fog', '>= 1.35.0'
16
+ s.add_dependency 'fog', '>= 1.38.0'
17
+ s.add_dependency 'google-api-client', "~> 0.8.0"
18
+ s.add_dependency 'fog-softlayer' , '~> 1.1.0'
17
19
  s.add_dependency 'retryable'
18
20
 
19
21
  s.add_development_dependency 'rspec'
20
22
  s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'github_changelog_generator'
21
24
 
22
25
  s.bindir = "bin"
23
26
  s.executables = %w( )
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'chef/provider/lwrp_base'
2
3
  require 'chef/provisioning/fog_driver/driver'
3
4
 
@@ -213,9 +214,9 @@ class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
213
214
  @current_resource = Chef::Resource::FogKeyPair.new(new_resource.name, run_context)
214
215
  case new_driver.provider
215
216
  when 'DigitalOcean'
216
- current_key_pair = compute.ssh_keys.select { |key| key.name == new_resource.name }.first
217
+ current_key_pair = compute.list_ssh_keys.body['ssh_keys'].select { |key| key['name'] == new_resource.name }.first
217
218
  if current_key_pair
218
- @current_id = current_key_pair.id
219
+ @current_id = current_key_pair['id']
219
220
  @current_fingerprint = current_key_pair ? compute.ssh_keys.get(@current_id).public_key : nil
220
221
  else
221
222
  current_resource.action :delete
@@ -297,7 +297,7 @@ module FogDriver
297
297
  specs_and_options.each do |machine_spec, machine_options|
298
298
  server = specs_and_servers[machine_spec]
299
299
  if server
300
- if %w(terminated archive).include?(server.status) # Can't come back from that
300
+ if %w(terminated archive DELETED).include?(server.state) # Can't come back from that
301
301
  Chef::Log.warn "Machine #{machine_spec.name} (#{server.id} on #{driver_url}) is terminated. Recreating ..."
302
302
  else
303
303
  yield machine_spec, server if block_given?
@@ -307,9 +307,30 @@ module FogDriver
307
307
  Chef::Log.warn "Machine #{machine_spec.name} (#{machine_spec.reference['server_id']} on #{driver_url}) no longer exists. Recreating ..."
308
308
  end
309
309
 
310
+ machine_spec.reference ||= {}
311
+ machine_spec.reference.update(
312
+ 'driver_url' => driver_url,
313
+ 'driver_version' => FogDriver::VERSION,
314
+ 'creator' => creator,
315
+ 'allocated_at' => Time.now.to_i
316
+ )
317
+
310
318
  bootstrap_options = bootstrap_options_for(action_handler, machine_spec, machine_options)
319
+ machine_spec.reference['key_name'] = bootstrap_options[:key_name] if bootstrap_options[:key_name]
311
320
  by_bootstrap_options[bootstrap_options] ||= []
312
321
  by_bootstrap_options[bootstrap_options] << machine_spec
322
+
323
+ # TODO 2.0 We no longer support `use_private_ip_for_ssh`, only `transport_address_location
324
+ if machine_options[:use_private_ip_for_ssh]
325
+ unless @transport_address_location_warned
326
+ Chef::Log.warn("The machine option ':use_private_ip_for_ssh' has been deprecated, use ':transport_address_location'")
327
+ @transport_address_location_warned = true
328
+ end
329
+ machine_options = Cheffish::MergedConfig.new(machine_options, {:transport_address_location => :private_ip})
330
+ end
331
+ %w(is_windows ssh_username sudo transport_address_location ssh_gateway).each do |key|
332
+ machine_spec.reference[key] = machine_options[key.to_sym] if machine_options[key.to_sym]
333
+ end
313
334
  end
314
335
 
315
336
  # Create the servers in parallel
@@ -329,25 +350,8 @@ module FogDriver
329
350
  # Assign each one to a machine spec
330
351
  machine_spec = machine_specs.pop
331
352
  machine_options = specs_and_options[machine_spec]
332
- machine_spec.reference = {
333
- 'driver_url' => driver_url,
334
- 'driver_version' => FogDriver::VERSION,
335
- 'server_id' => server.id,
336
- 'creator' => creator,
337
- 'allocated_at' => Time.now.to_i
338
- }
339
- machine_spec.reference['key_name'] = bootstrap_options[:key_name] if bootstrap_options[:key_name]
340
- # TODO 2.0 We no longer support `use_private_ip_for_ssh`, only `transport_address_location
341
- if machine_options[:use_private_ip_for_ssh]
342
- unless @transport_address_location_warned
343
- Chef::Log.warn("The machine option ':use_private_ip_for_ssh' has been deprecated, use ':transport_address_location'")
344
- @transport_address_location_warned = true
345
- end
346
- machine_options = Cheffish::MergedConfig.new(machine_options, {:transport_address_location => :private_ip})
347
- end
348
- %w(is_windows ssh_username sudo transport_address_location ssh_gateway).each do |key|
349
- machine_spec.reference[key] = machine_options[key.to_sym] if machine_options[key.to_sym]
350
- end
353
+ machine_spec.reference['server_id'] = server.id
354
+
351
355
  action_handler.performed_action "machine #{machine_spec.name} created as #{server.id} on #{driver_url}"
352
356
 
353
357
  yield machine_spec, server if block_given?
@@ -371,13 +375,13 @@ module FogDriver
371
375
 
372
376
  def start_server(action_handler, machine_spec, server)
373
377
  # If it is stopping, wait for it to get out of "stopping" transition status before starting
374
- if server.status == 'stopping'
378
+ if server.state == 'stopping'
375
379
  action_handler.report_progress "wait for #{machine_spec.name} (#{server.id} on #{driver_url}) to finish stopping ..."
376
- server.wait_for { server.status != 'stopping' }
380
+ server.wait_for { server.state != 'stopping' }
377
381
  action_handler.report_progress "#{machine_spec.name} is now stopped"
378
382
  end
379
383
 
380
- if server.status == 'stopped'
384
+ if server.state == 'stopped'
381
385
  action_handler.perform_action "start machine #{machine_spec.name} (#{server.id} on #{driver_url})" do
382
386
  server.start
383
387
  machine_spec.reference['started_at'] = Time.now.to_i
@@ -35,6 +35,13 @@ class Chef
35
35
  bootstrap_options[:zone_name] ||= 'europe-west1-b'
36
36
  bootstrap_options[:name] ||= machine_spec.name
37
37
  bootstrap_options[:disk_size] ||= 10
38
+ disk_type_prefix = "https://www.googleapis.com/compute/v1/projects/#{compute_options[:google_project]}/zones/#{bootstrap_options[:zone_name]}/diskTypes/"
39
+ standard_disk_type = disk_type_prefix + 'pd-standard'
40
+ if bootstrap_options[:disk_type].nil?
41
+ bootstrap_options[:disk_type] = standard_disk_type
42
+ else
43
+ bootstrap_options[:disk_type] = disk_type_prefix + bootstrap_options[:disk_type]
44
+ end
38
45
 
39
46
  if bootstrap_options[:disks].nil?
40
47
  # create the persistent boot disk
@@ -43,6 +50,7 @@ class Chef
43
50
  :size_gb => bootstrap_options[:disk_size],
44
51
  :zone_name => bootstrap_options[:zone_name],
45
52
  :source_image => bootstrap_options[:image_name],
53
+ :type => bootstrap_options[:disk_type],
46
54
  }
47
55
 
48
56
  disk = compute.disks.create(disk_defaults)
@@ -1,3 +1,9 @@
1
+ require 'base64'
2
+ require 'uri'
3
+ require 'fog/softlayer'
4
+ require 'fog/softlayer/models/compute/server'
5
+
6
+ # fog:SoftLayer:<datacenter>
1
7
  class Chef
2
8
  module Provisioning
3
9
  module FogDriver
@@ -5,6 +11,8 @@ class Chef
5
11
  class SoftLayer < FogDriver::Driver
6
12
  Driver.register_provider_class('SoftLayer', FogDriver::Providers::SoftLayer)
7
13
 
14
+ POST_SCRIPT_DONE = 'post-script-done'
15
+
8
16
  def creator
9
17
  compute_options[:softlayer_username]
10
18
  end
@@ -14,19 +22,189 @@ class Chef
14
22
  new_compute_options[:provider] = provider
15
23
  new_config = { :driver_options => { :compute_options => new_compute_options }}
16
24
  new_defaults = {
17
- :driver_options => { :compute_options => {} },
25
+ :driver_options => { :compute_options => Fog.credentials },
18
26
  :machine_options => { :bootstrap_options => {} }
19
27
  }
20
28
  result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
29
+ id ||= ''
30
+ new_defaults[:machine_options][:bootstrap_options][:datacenter] = id if not id.empty?
31
+
32
+ [result, id]
33
+ end
21
34
 
22
- credential = Fog.credentials
35
+ def bootstrap_options_for(action_handler, machine_spec, machine_options)
36
+ # probably best to only ADD options here since super class looks
37
+ # for some values; for example, :key_name doesn't get saved to
38
+ # chef_provisioning.reference if you remove it here.
39
+ # Therefore, we remove things SoftLayer rejects in
40
+ # create_many_servers just before the actual fog create calls.
23
41
 
24
- new_compute_options[:softlayer_username] ||= credential[:softlayer_username]
25
- new_compute_options[:softlayer_api_key] ||= credential[:softlayer_api_key]
42
+ opts = super
26
43
 
27
- id = result[:driver_options][:compute_options][:softlayer_auth_url]
44
+ if opts[:key_name]
45
+ key_label = opts[:key_name]
46
+ opts[:key_pairs] = [compute.key_pairs.by_label(key_label)] if key_label.is_a? String
47
+ end
28
48
 
29
- [result, id]
49
+ opts
50
+ end
51
+
52
+ def create_many_servers(num_servers, bootstrap_options, parallelizer)
53
+ # need to filter out options that SoftLayer doesn't accept
54
+ opts = bootstrap_options.dup
55
+
56
+ # options are passed directly to SoftLayer API and
57
+ # SoftLayer_Hardware_Server rejects requests with unrecognized
58
+ # options
59
+ opts.keep_if do |opt, val|
60
+ ::Fog::Compute::Softlayer::Server.attributes.include?(opt)
61
+ end
62
+ # fog-softlayer defines :tags but SoftLayer_Hardware_Server rejects it...
63
+ #opts.delete :tags
64
+
65
+ # we hook in our own post-install script which uses userMetadata to
66
+ # tell us when post-install is complete. If the user supplies their
67
+ # own script it will be called by our hook before indicating
68
+ # completion in userData.
69
+ opts[:postInstallScriptUri] = 'https://dal05.objectstorage.service.networklayer.com/v1/AUTH_b1b23a05-1c03-4961-8b08-2339886e476f/dist/sl-post-hook.sh'
70
+
71
+ super(num_servers, opts, parallelizer)
72
+ end
73
+
74
+ def find_floating_ips(server, action_handler)
75
+ []
76
+ end
77
+
78
+ def server_for(machine_spec)
79
+ if machine_spec.reference
80
+ id = machine_spec.reference['server_id']
81
+ if id and 0 != id
82
+ compute.servers.get(id)
83
+ else
84
+ sv = compute.servers.new(
85
+ :uid => machine_spec.reference['uid'],
86
+ :name => machine_spec.name,
87
+ :domain => machine_spec.reference['domain']
88
+ )
89
+
90
+ Chef::Log.info("waiting for server.id")
91
+ sv.wait_for_id
92
+ machine_spec.reference['server_id'] = sv.id
93
+ return sv
94
+ end
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def servers_for(machine_specs)
101
+ result = {}
102
+ machine_specs.each do |machine_spec|
103
+ result[machine_spec] = server_for(machine_spec)
104
+ end
105
+
106
+ result
107
+ end
108
+
109
+ def create_servers(action_handler, specs_and_options, parallelizer, &block)
110
+ super do |machine_spec, server|
111
+ machine_spec.reference['uid'] = server.uid
112
+ machine_spec.reference['domain'] = server.domain
113
+ machine_spec.save(action_handler)
114
+ bootstrap_options = specs_and_options[machine_spec][:bootstrap_options]
115
+ create_timeout = bootstrap_options[:create_timeout] || 3600
116
+ wait_for_id(action_handler, server, create_timeout)
117
+ set_post_install_info(action_handler, server, bootstrap_options)
118
+
119
+ block.call(machine_spec, server) if block
120
+ end
121
+ end
122
+
123
+ def request(server, path, **options)
124
+ service = server.bare_metal? ? :hardware_server : :virtual_guest
125
+ server.service.request(service, path, options)
126
+ end
127
+
128
+ def set_post_install_info(action_handler, server, bootstrap_options)
129
+ existing_user_data = request(server, server.id, :query => {:objectMask => 'userData'}).body['userData']
130
+ Chef::Log.info("userData from SLAPI is #{existing_user_data.inspect}")
131
+ if existing_user_data.is_a? Array
132
+ if existing_user_data.size < 1
133
+ existing_user_data = ''
134
+ else
135
+ existing_user_data = existing_user_data.first.fetch('value', '')
136
+ end
137
+ end
138
+ Chef::Log.info("userData after processing is #{existing_user_data.inspect}")
139
+ # VSI userData is empty; bare metal userData will be an Array
140
+ if existing_user_data.empty?
141
+ action_handler.report_progress("Setting userData to detect post install status.")
142
+ sl_user = compute.instance_variable_get '@softlayer_username'
143
+ sl_key = compute.instance_variable_get '@softlayer_api_key'
144
+ service = server.bare_metal? ? 'Hardware_Server' : 'Virtual_Guest'
145
+ ::Retryable.retryable(:tries => 60, :sleep => 5) do
146
+ update_url = URI::HTTPS.build(
147
+ :userinfo => "#{sl_user}:#{sl_key}",
148
+ :host => 'api.service.softlayer.com',
149
+ :path => "/rest/v3/SoftLayer_#{service}/#{server.id}/setUserMetadata",
150
+ ).to_s
151
+
152
+ post_install_info = <<SHELL
153
+ ##POST_INSTALL_INFO
154
+ POSTINST_UPDATE_URL='#{update_url}'
155
+ POSTINST_REQUESTED_URL='#{bootstrap_options[:postInstallScriptUri]}'
156
+ SHELL
157
+
158
+ encoded_info = Base64.strict_encode64(post_install_info)
159
+ Chef::Log.debug("encoded info: #{encoded_info.inspect}")
160
+
161
+ res = request(
162
+ server,
163
+ "#{server.id}/setUserMetadata",
164
+ :http_method => 'POST', :body => [
165
+ [
166
+ encoded_info
167
+ ]
168
+ ]
169
+ )
170
+
171
+ raise "Failed to setUserMetadata" unless TrueClass == res.body.class or res.body.first['value']
172
+ end
173
+ end
174
+ end
175
+
176
+ def wait_for_id(action_handler, server, create_timeout)
177
+ return if 0 != server.id
178
+
179
+ # Cannot use Fog.wait_for because it requires server.id which is
180
+ # not initially available for bare metal.
181
+ server.wait_for_id(create_timeout) do |srv_info|
182
+ srv_id = srv_info ? srv_info['id'] : 'not set yet'
183
+ action_handler.report_progress "waiting for server.id on #{server.name} (#{server.uid}): #{srv_id} #{srv_info}"
184
+ end
185
+ end
186
+
187
+ def wait_until_ready(action_handler, machine_spec, machine_options, server)
188
+ super
189
+
190
+ action_handler.report_progress "waiting for post-install script on #{server.name} to finish"
191
+
192
+ ::Retryable.retryable(:tries => 600, :sleep => 2) do
193
+ action_handler.report_progress "checking post-install status on #{server.name}"
194
+ res = request(server, server.id, :query => 'objectMask=userData')
195
+ userData = res.body['userData']
196
+ value = userData.first['value']
197
+
198
+ raise "Waiting for post-install script" unless POST_SCRIPT_DONE == value
199
+ end
200
+
201
+ action_handler.report_progress "post-install done on #{server.name}"
202
+ end
203
+
204
+ def start_server(action_handler, machine_spec, server)
205
+ ::Retryable.retryable(:tries => 10, :sleep => 2) do
206
+ super
207
+ end
30
208
  end
31
209
  end
32
210
  end
@@ -1,7 +1,7 @@
1
1
  class Chef
2
2
  module Provisioning
3
3
  module FogDriver
4
- VERSION = '0.16.0'
4
+ VERSION = '0.17.0'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'chef/provisioning/fog_driver/providers/softlayer'
3
+
4
+ describe Chef::Provisioning::FogDriver::Providers::SoftLayer do
5
+ subject do
6
+ Chef::Provisioning::FogDriver::Driver.from_provider(
7
+ 'SoftLayer',
8
+ driver_options: {
9
+ compute_options: {
10
+ softlayer_username: 'test_username', softlayer_api_key: 'test_api_key'}
11
+ }
12
+ )
13
+ end
14
+
15
+ it "returns the correct driver" do
16
+ expect(subject).to be_an_instance_of Chef::Provisioning::FogDriver::Providers::SoftLayer
17
+ end
18
+
19
+ it "has a Fog backend" do
20
+ pending unless Fog.mock?
21
+ expect(subject.compute).to be_an_instance_of Fog::Compute::Softlayer::Mock
22
+ end
23
+ end
24
+
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-provisioning-fog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
8
8
  - Chris McClimans
9
9
  - Taylor Carpenter
10
10
  - Wavell Watson
11
+ - JJ Asghar
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2016-02-03 00:00:00.000000000 Z
15
+ date: 2016-03-28 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: chef-provisioning
@@ -33,14 +34,42 @@ dependencies:
33
34
  requirements:
34
35
  - - ">="
35
36
  - !ruby/object:Gem::Version
36
- version: 1.35.0
37
+ version: 1.38.0
37
38
  type: :runtime
38
39
  prerelease: false
39
40
  version_requirements: !ruby/object:Gem::Requirement
40
41
  requirements:
41
42
  - - ">="
42
43
  - !ruby/object:Gem::Version
43
- version: 1.35.0
44
+ version: 1.38.0
45
+ - !ruby/object:Gem::Dependency
46
+ name: google-api-client
47
+ requirement: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: 0.8.0
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: 0.8.0
59
+ - !ruby/object:Gem::Dependency
60
+ name: fog-softlayer
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: 1.1.0
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: 1.1.0
44
73
  - !ruby/object:Gem::Dependency
45
74
  name: retryable
46
75
  requirement: !ruby/object:Gem::Requirement
@@ -83,12 +112,27 @@ dependencies:
83
112
  - - ">="
84
113
  - !ruby/object:Gem::Version
85
114
  version: '0'
115
+ - !ruby/object:Gem::Dependency
116
+ name: github_changelog_generator
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
86
129
  description: Driver for creating Fog instances in Chef Provisioning.
87
130
  email:
88
131
  - jkeiser@getchef.com
89
132
  - hh@vulk.co
90
133
  - t@vulk.co
91
134
  - w@vulk.co
135
+ - jj@chef.io
92
136
  executables: []
93
137
  extensions: []
94
138
  extra_rdoc_files:
@@ -125,6 +169,7 @@ files:
125
169
  - spec/unit/fog_driver_spec.rb
126
170
  - spec/unit/providers/aws/credentials_spec.rb
127
171
  - spec/unit/providers/rackspace_spec.rb
172
+ - spec/unit/providers/softlayer.rb
128
173
  homepage: https://github.com/opscode/chef-provisioning-fog
129
174
  licenses: []
130
175
  metadata: {}