vagrant-softlayer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/.gitignore +15 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +20 -0
  4. data/README.md +233 -0
  5. data/Rakefile +6 -0
  6. data/dummy.box +0 -0
  7. data/example_box/README.md +13 -0
  8. data/example_box/metadata.json +3 -0
  9. data/lib/vagrant-softlayer/action/create_instance.rb +54 -0
  10. data/lib/vagrant-softlayer/action/destroy_instance.rb +23 -0
  11. data/lib/vagrant-softlayer/action/is.rb +21 -0
  12. data/lib/vagrant-softlayer/action/message.rb +22 -0
  13. data/lib/vagrant-softlayer/action/read_ssh_info.rb +28 -0
  14. data/lib/vagrant-softlayer/action/read_state.rb +42 -0
  15. data/lib/vagrant-softlayer/action/rebuild_instance.rb +35 -0
  16. data/lib/vagrant-softlayer/action/setup_softlayer.rb +37 -0
  17. data/lib/vagrant-softlayer/action/start_instance.rb +21 -0
  18. data/lib/vagrant-softlayer/action/stop_instance.rb +30 -0
  19. data/lib/vagrant-softlayer/action/sync_folders.rb +99 -0
  20. data/lib/vagrant-softlayer/action/update_dns.rb +96 -0
  21. data/lib/vagrant-softlayer/action/wait_for_provision.rb +40 -0
  22. data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -0
  23. data/lib/vagrant-softlayer/action.rb +200 -0
  24. data/lib/vagrant-softlayer/command/rebuild.rb +34 -0
  25. data/lib/vagrant-softlayer/config.rb +178 -0
  26. data/lib/vagrant-softlayer/errors.rb +25 -0
  27. data/lib/vagrant-softlayer/plugin.rb +77 -0
  28. data/lib/vagrant-softlayer/provider.rb +47 -0
  29. data/lib/vagrant-softlayer/util/network.rb +42 -0
  30. data/lib/vagrant-softlayer/util/warden.rb +38 -0
  31. data/lib/vagrant-softlayer/version.rb +5 -0
  32. data/lib/vagrant-softlayer.rb +22 -0
  33. data/locales/en.yml +146 -0
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/vagrant-softlayer/config_spec.rb +156 -0
  36. data/vagrant-softlayer.gemspec +53 -0
  37. metadata +152 -0
@@ -0,0 +1,25 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Errors
4
+ class VagrantSoftLayerError < Vagrant::Errors::VagrantError
5
+ error_namespace("vagrant_softlayer.errors")
6
+ end
7
+
8
+ class SLApiError < VagrantSoftLayerError
9
+ error_key(:api_error)
10
+ end
11
+
12
+ class SLCertificateError < VagrantSoftLayerError
13
+ error_key(:certificate_error)
14
+ end
15
+
16
+ class SLDNSZoneNotFound < VagrantSoftLayerError
17
+ error_key(:dns_zone_not_found)
18
+ end
19
+
20
+ class SLSshKeyNotFound < VagrantSoftLayerError
21
+ error_key(:ssh_key_not_found)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,77 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant SoftLayer plugin must be run within Vagrant."
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install
8
+ # this into an early Vagrant version.
9
+ if Vagrant::VERSION < "1.3.0"
10
+ raise "The Vagrant SoftLayer plugin is only compatible with Vagrant 1.3+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module SoftLayer
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "SoftLayer"
17
+ description <<-DESC
18
+ This plugin installs a provider that allows Vagrant to manage
19
+ SoftLayer CCI.
20
+ DESC
21
+
22
+ command(:rebuild) do
23
+ require_relative 'command/rebuild'
24
+ Command::Rebuild
25
+ end
26
+
27
+ config(:softlayer, :provider) do
28
+ require_relative "config"
29
+ Config
30
+ end
31
+
32
+ provider(:softlayer) do
33
+ init_logging
34
+ init_i18n
35
+
36
+ require_relative "provider"
37
+ Provider
38
+ end
39
+
40
+ # This initializes the I18n load path so that the plugin specific
41
+ # transations work.
42
+ def self.init_i18n
43
+ I18n.load_path << File.expand_path("locales/en.yml", SoftLayer.source_root)
44
+ I18n.reload!
45
+ end
46
+
47
+ # This sets up our log level to be whatever VAGRANT_LOG is.
48
+ def self.init_logging
49
+ require "log4r"
50
+
51
+ level = nil
52
+ begin
53
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
54
+ rescue NameError
55
+ # This means that the logging constant wasn't found,
56
+ # which is fine. We just keep `level` as `nil`. But
57
+ # we tell the user.
58
+ level = nil
59
+ end
60
+
61
+ # Some constants, such as "true" resolve to booleans, so the
62
+ # above error checking doesn't catch it. This will check to make
63
+ # sure that the log level is an integer, as Log4r requires.
64
+ level = nil if !level.is_a?(Integer)
65
+
66
+ # Set the logging level on all "vagrant" namespaced
67
+ # logs as long as we have a valid level.
68
+ if level
69
+ logger = Log4r::Logger.new("vagrant_softlayer")
70
+ logger.outputters = Log4r::Outputter.stderr
71
+ logger.level = level
72
+ logger = nil
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,47 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ class Provider < Vagrant.plugin("2", :provider)
4
+ def initialize(machine)
5
+ @machine = machine
6
+ end
7
+
8
+ def action(name)
9
+ # Attempt to get the action method from the Action class if it
10
+ # exists, otherwise return nil to show that we don't support the
11
+ # given action.
12
+ action_method = "action_#{name}"
13
+ return Action.send(action_method) if Action.respond_to?(action_method)
14
+ nil
15
+ end
16
+
17
+ def ssh_info
18
+ # Run a custom action called "read_ssh_info" which does what it
19
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
20
+ # key in the environment.
21
+ env = @machine.action("read_ssh_info")
22
+ env[:machine_ssh_info]
23
+ end
24
+
25
+ def state
26
+ # Run a custom action we define called "read_state" which does
27
+ # what it says. It puts the state in the `:machine_state_id`
28
+ # key in the environment.
29
+ env = @machine.action("read_state")
30
+
31
+ state_id = env[:machine_state_id]
32
+
33
+ # Get the short and long description
34
+ short = I18n.t("vagrant_softlayer.states.short_#{state_id}")
35
+ long = I18n.t("vagrant_softlayer.states.long_#{state_id}")
36
+
37
+ # Return the MachineState object
38
+ Vagrant::MachineState.new(state_id, short, long)
39
+ end
40
+
41
+ def to_s
42
+ id = @machine.id || "new VM"
43
+ "SoftLayer (#{id})"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,42 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Util
4
+ module Network
5
+ # Gets instance's IP address.
6
+ #
7
+ # Returns the private IP address if the instance has been
8
+ # defined as private only, the public IP address otherwise.
9
+ def ip_address(env)
10
+ service = env[:machine].provider_config.private_only ? :getPrimaryBackendIpAddress : :getPrimaryIpAddress
11
+ return sl_warden { env[:sl_machine].send(service) }
12
+ end
13
+
14
+ # Returns SSH keys starting from the configuration parameter.
15
+ #
16
+ # In the configuration, each key could be passed either as an
17
+ # id or as a label. The routine will detect this and lookup
18
+ # the id if needed.
19
+ #
20
+ # The first parameter is the current environment.
21
+ #
22
+ # The second parameter is useful for returning: if it is set
23
+ # the routine will return just the array of ids (this is needed,
24
+ # as an example, for reloading OS), otherwise an hash is
25
+ # returned (this latter case is needed instead for creating
26
+ # an instance).
27
+ def ssh_keys(env, ids_only = false)
28
+ account = ::SoftLayer::Service.new("SoftLayer_Account", env[:sl_credentials])
29
+ acc_keys = sl_warden { account.object_mask("id", "label").getSshKeys }
30
+ key_ids = []
31
+ Array(env[:machine].provider_config.ssh_key).each do |key|
32
+ pattern = key.is_a?(String) ? "label" : "id"
33
+ key_hash = acc_keys.find { |acc_key| acc_key[pattern] == key }
34
+ raise Errors::SLSshKeyNotFound, :key => key unless key_hash
35
+ key_ids << key_hash["id"]
36
+ end
37
+ return (ids_only ? key_ids : key_ids.map { |key_id| { :id => key_id } })
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Util
4
+ module Warden
5
+ # Handles gracefully SoftLayer API calls.
6
+ #
7
+ # The block code is executed, catching both common
8
+ # connection errors and API exceptions.
9
+ #
10
+ # Optionally, in the not-so-uncommon case when
11
+ # the object (e.g. the SoftLayer instance) is not
12
+ # found, executes a proc and/or retry the API call
13
+ # after some seconds.
14
+ #
15
+ # A future version of the method will add a retry timeout.
16
+ def sl_warden(rescue_proc = nil, retry_interval = 0, &block)
17
+ begin
18
+ yield
19
+ rescue ::OpenSSL::SSL::SSLError
20
+ raise Errors::SLCertificateError
21
+ rescue SocketError, ::SoftLayer::SoftLayerAPIException => e
22
+ if e.class == ::SoftLayer::SoftLayerAPIException && e.message.start_with?("Unable to find object with id")
23
+ out = rescue_proc.call if rescue_proc
24
+ if retry_interval > 0
25
+ sleep retry_interval
26
+ retry
27
+ else
28
+ return out
29
+ end
30
+ else
31
+ raise Errors::SLApiError, :class => e.class, :message => e.message
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require "pathname"
2
+ require "softlayer_api"
3
+ require "vagrant-softlayer/plugin"
4
+
5
+ module VagrantPlugins
6
+ module SoftLayer
7
+ API_PRIVATE_ENDPOINT = ::SoftLayer::API_PRIVATE_ENDPOINT
8
+ API_PUBLIC_ENDPOINT = ::SoftLayer::API_PUBLIC_ENDPOINT
9
+
10
+ lib_path = Pathname.new(File.expand_path("../vagrant-softlayer", __FILE__))
11
+ autoload :Action, lib_path.join("action")
12
+ autoload :Config, lib_path.join("config")
13
+ autoload :Errors, lib_path.join("errors")
14
+
15
+ # This returns the path to the source of this plugin.
16
+ #
17
+ # @return [Pathname]
18
+ def self.source_root
19
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
20
+ end
21
+ end
22
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,146 @@
1
+ en:
2
+ vagrant_softlayer:
3
+ config:
4
+ api_key_required: |-
5
+ The SoftLayer API key is required. Please specify it
6
+ using the SL_API_KEY environment variable or in the provider
7
+ section of the Vagrantfile:
8
+
9
+ config.vm.provider :softlayer do |sl|
10
+ sl.api_key = "my_API_key"
11
+ end
12
+ domain_required: |-
13
+ The domain of the SoftLayer instance is required.
14
+ Please specify it in the provider section of the Vagrantfile:
15
+
16
+ config.vm.provider :softlayer do |sl|
17
+ sl.domain = "example.com"
18
+ end
19
+ hostname_required: |-
20
+ The hostname of the SoftLayer instance is required.
21
+ Please specify it either with `config.vm.hostname` or
22
+ in the provider section of the Vagrantfile:
23
+
24
+ config.vm.hostname = "vagrant"
25
+
26
+ config.vm.provider :softlayer do |sl|
27
+ sl.hostname = "vagrant"
28
+ end
29
+ ssh_key_required: |-
30
+ At least an SSH key for the instance is required.
31
+ Please specify it, either using name or id, in the
32
+ provider section of the Vagrantfile:
33
+
34
+ config.vm.provider :softlayer do |sl|
35
+ sl.ssh_key = 1
36
+ end
37
+ username_required: |-
38
+ The SoftLayer username is required. Please specify it
39
+ using the SL_USERNAME environment variable or in the provider
40
+ section of the Vagrantfile:
41
+
42
+ config.vm.provider :softlayer do |sl|
43
+ sl.username = "my_username"
44
+ end
45
+ errors:
46
+ api_error: |-
47
+ Vagrant returned an exception while calling the SoftLayer API.
48
+
49
+ Exception class: %{class}
50
+ Exception message: %{message}
51
+ certificate_error: |-
52
+ The secure connection to the SoftLayer API has failed. This is
53
+ generally caused by the OpenSSL configuration associated with
54
+ the Ruby install being unaware of the system specific CA certs.
55
+
56
+ Please ensure that the SSL_CERT_FILE environment variable is set
57
+ with a path to a certificate authority.
58
+
59
+ Linux example:
60
+
61
+ export SSL_CERT_FILE=/opt/vagrant/embedded/cacert.pem
62
+
63
+ Mac OS X example:
64
+
65
+ export SSL_CERT_FILE=/Applications/Vagrant/embedded/cacert.pem
66
+
67
+ Windows example:
68
+
69
+ set SSL_CERT_FILE=C:\HashiCorp\Vagrant\embedded\cacert.pem
70
+ dns_zone_not_found: |-
71
+ The DNS zone you're trying to manage (%{zone}) has not been
72
+ found in the zone list.
73
+ ssh_key_not_found: |-
74
+ The SSH key you're trying to set (%{key}) does not exists in the
75
+ SoftLayer account's keychain.
76
+ states:
77
+ short_not_created: |-
78
+ not created
79
+ long_not_created: |-
80
+ The SoftLayer instance is not created. Run `vagrant up` to create it.
81
+ short_halted: |-
82
+ stopped
83
+ long_halted: |-
84
+ The SoftLayer instance is stopped. Run `vagrant up` to start it.
85
+ short_paused: |-
86
+ paused
87
+ long_paused: |-
88
+ The SoftLayer instance is paused. You need to resume it using another
89
+ SoftLayer client tool (e.g. `sl` command line utility).
90
+ short_running: |-
91
+ running
92
+ long_running: |-
93
+ The SoftLayer instance is running. To stop this machine, you can run
94
+ `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
95
+ short_unknown: |-
96
+ unknown
97
+ long_unknown: |-
98
+ The SoftLayer instance is in an unknown state. You need to check it
99
+ out using SoftLayer administrative interface.
100
+ sync_folders:
101
+ rsync_folder: |-
102
+ Rsyncing folder: %{hostpath} => %{guestpath}
103
+ rsync_not_found: |-
104
+ Warning! Folder sync disabled because the rsync binary is missing in the %{side}.
105
+ Make sure rsync is installed and the binary can be found in the PATH.
106
+ vm:
107
+ already_running: |-
108
+ The SoftLayer instance is already running.
109
+ already_stopped: |-
110
+ The SoftLayer instance is already stopped.
111
+ creating: |-
112
+ Creating a new SoftLayer instance...
113
+ creating_dns_record: |-
114
+ Creating DNS record for the instance...
115
+ deleting_dns_record: |-
116
+ Deleting DNS record for the instance...
117
+ destroying: |-
118
+ Destroying the SoftLayer instance...
119
+ not_destroying: |-
120
+ The SoftLayer instance will not be destroyed, since the confirmation
121
+ was declined.
122
+ not_created: |-
123
+ The SoftLayer instance does not exists.
124
+ not_rebuilding: |-
125
+ The SoftLayer instance will not be rebuilded, since the confirmation
126
+ was declined.
127
+ not_running: |-
128
+ The SoftLayer instance is not running. Please run `vagrant up` first.
129
+ provisioned: |-
130
+ SoftLayer instance successfully provisioned!
131
+ rebuilding: |-
132
+ Rebuilding the SoftLayer instance...
133
+ rebuild_confirmation: |-
134
+ Are you sure you want to rebuild the current VM? [y/N]
135
+ rebuilt: |-
136
+ SoftLayer instance successfully rebuilt!
137
+ starting: |-
138
+ Starting the SoftLayer instance...
139
+ stopping: |-
140
+ Stopping the SoftLayer instance gracefully...
141
+ stopping_force: |-
142
+ Stopping the SoftLayer instance forcibly...
143
+ wait_for_provision: |-
144
+ Waiting for instance provisioning. This may take a few minutes...
145
+ wait_for_rebuild: |-
146
+ Waiting for instance rebuilding. This may take a few minutes...
@@ -0,0 +1 @@
1
+ require_relative "../lib/vagrant-softlayer"
@@ -0,0 +1,156 @@
1
+ require "spec_helper"
2
+
3
+ describe VagrantPlugins::SoftLayer::Config do
4
+ let(:config) { described_class.new }
5
+ let(:machine) { double("machine") }
6
+
7
+ describe "defaults" do
8
+ subject do
9
+ config.tap do |o|
10
+ o.finalize!
11
+ end
12
+ end
13
+
14
+ its("api_key") { should be_nil }
15
+ its("endpoint_url") { should eq VagrantPlugins::SoftLayer::API_PUBLIC_ENDPOINT }
16
+ its("username") { should be_nil }
17
+
18
+ its("datacenter") { should be_nil }
19
+ its("dedicated") { should be_false }
20
+ its("domain") { should be_nil }
21
+ its("hostname") { should be_nil }
22
+ its("hourly_billing") { should be_true }
23
+ its("local_disk") { should be_true }
24
+ its("max_memory") { should eq 1024 }
25
+ its("network_speed") { should eq 10 }
26
+ its("operating_system") { should eq "UBUNTU_LATEST" }
27
+ its("post_install") { should be_nil }
28
+ its("private_only") { should be_false }
29
+ its("ssh_key") { should be_nil }
30
+ its("start_cpus") { should eq 1 }
31
+ its("user_data") { should be_nil }
32
+ its("vlan_private") { should be_nil }
33
+ its("vlan_public") { should be_nil }
34
+
35
+ its("manage_dns") { should be_false }
36
+ end
37
+
38
+ describe "overriding defaults" do
39
+ context "booleans" do
40
+ [true, false].each do |bool|
41
+ [:dedicated, :hourly_billing, :local_disk, :manage_dns, :private_only].each do |attribute|
42
+ it "should accept both true and false for #{attribute}" do
43
+ config.send("#{attribute}=".to_sym, bool)
44
+ config.finalize!
45
+ expect(config.send(attribute)).to eq bool
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ context "integers" do
52
+ [:max_memory, :network_speed, :ssh_key, :start_cpus, :vlan_private, :vlan_public].each do |attribute|
53
+ it "should not default #{attribute} if overridden" do
54
+ config.send("#{attribute}=".to_sym, 999)
55
+ config.finalize!
56
+ expect(config.send(attribute)).to eq 999
57
+ end
58
+ end
59
+ end
60
+
61
+ context "strings" do
62
+ [:api_key, :datacenter, :endpoint_url, :username, :domain, :hostname, :operating_system, :post_install, :ssh_key, :user_data].each do |attribute|
63
+ it "should not default #{attribute} if overridden" do
64
+ config.send("#{attribute}=".to_sym, "foo")
65
+ config.finalize!
66
+ expect(config.send(attribute)).to eq "foo"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "using SL_ environment variables" do
73
+ before :each do
74
+ ENV.stub(:[]).with("SL_API_KEY").and_return("env_api_key")
75
+ ENV.stub(:[]).with("SL_USERNAME").and_return("env_username")
76
+ end
77
+
78
+ subject do
79
+ config.tap do |o|
80
+ o.finalize!
81
+ end
82
+ end
83
+
84
+ its("api_key") { should eq "env_api_key" }
85
+ its("username") { should eq "env_username" }
86
+ end
87
+
88
+ describe "validation" do
89
+ before :each do
90
+ # Setup some good configuration values
91
+ config.api_key = "An API key"
92
+ config.username = "An username"
93
+
94
+ config.datacenter = "ams01"
95
+ config.dedicated = false
96
+ config.domain = "example.com"
97
+ config.hostname = "vagrant"
98
+ config.hourly_billing = true
99
+ config.local_disk = true
100
+ config.max_memory = 1024
101
+ config.network_speed = 10
102
+ config.operating_system = "UBUNTU_LATEST"
103
+ config.post_install = "http://example.com/foo"
104
+ config.ssh_key = ["First key", "Second key"]
105
+ config.start_cpus = 1
106
+ config.user_data = "some metadata"
107
+ config.vlan_private = 111
108
+ config.vlan_public = 222
109
+
110
+ config.manage_dns = false
111
+
112
+ machine.stub_chain(:config, :vm, :hostname).and_return(nil)
113
+ end
114
+
115
+ it "should validate" do
116
+ config.finalize!
117
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
118
+ end
119
+
120
+ it "should fail if API key is not given" do
121
+ config.api_key = nil
122
+ config.finalize!
123
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
124
+ end
125
+
126
+ it "should fail if username is not given" do
127
+ config.username = nil
128
+ config.finalize!
129
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
130
+ end
131
+
132
+ it "should fail if domain is not given" do
133
+ config.domain = nil
134
+ config.finalize!
135
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
136
+ end
137
+
138
+ it "should fail if hostname is not given" do
139
+ config.hostname = nil
140
+ config.finalize!
141
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
142
+ end
143
+
144
+ it "should validate if hostname is not given but config.vm.hostname is set" do
145
+ config.hostname = nil
146
+ machine.stub_chain(:config, :vm, :hostname).and_return("vagrant")
147
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
148
+ end
149
+
150
+ it "should fail if ssh key is not given" do
151
+ config.ssh_key = nil
152
+ config.finalize!
153
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,53 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "vagrant-softlayer/version"
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "vagrant-softlayer"
6
+ spec.version = VagrantPlugins::SoftLayer::VERSION
7
+ spec.authors = "Audiolize GmbH"
8
+ spec.email = ""
9
+ spec.description = "Enables Vagrant to manages SoftLayer CCI."
10
+ spec.summary = "Enables Vagrant to manages SoftLayer CCI."
11
+
12
+ # The following block of code determines the files that should be included
13
+ # in the gem. It does this by reading all the files in the directory where
14
+ # this gemspec is, and parsing out the ignored files from the gitignore.
15
+ # Note that the entire gitignore(5) syntax is not supported, specifically
16
+ # the "!" syntax, but it should mostly work correctly.
17
+ root_path = File.dirname(__FILE__)
18
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
19
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
20
+ gitignore_path = File.join(root_path, ".gitignore")
21
+ gitignore = File.readlines(gitignore_path)
22
+ gitignore.map! { |line| line.chomp.strip }
23
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
24
+
25
+ unignored_files = all_files.reject do |file|
26
+ # Ignore any directories, the gemspec only cares about files
27
+ next true if File.directory?(file)
28
+
29
+ # Ignore any paths that match anything in the gitignore. We do
30
+ # two tests here:
31
+ #
32
+ # - First, test to see if the entire path matches the gitignore.
33
+ # - Second, match if the basename does, this makes it so that things
34
+ # like '.DS_Store' will match sub-directories too (same behavior
35
+ # as git).
36
+ #
37
+ gitignore.any? do |ignore|
38
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
39
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
40
+ end
41
+ end
42
+
43
+ spec.files = unignored_files
44
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
45
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
46
+ spec.require_path = "lib"
47
+
48
+ spec.add_dependency "softlayer_api"
49
+
50
+ spec.add_development_dependency "bundler", "~> 1.3"
51
+ spec.add_development_dependency "rake"
52
+ spec.add_development_dependency "rspec"
53
+ end