vagrant-openstack-provider 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Appraisals +13 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.txt +22 -0
  7. data/RELEASE.md +15 -0
  8. data/Rakefile +21 -0
  9. data/Vagrantfile +37 -0
  10. data/dummy.box +0 -0
  11. data/example_box/README.md +13 -0
  12. data/example_box/metadata.json +3 -0
  13. data/features/provision.feature +35 -0
  14. data/features/steps/sdk_steps.rb +13 -0
  15. data/features/steps/server_steps.rb +25 -0
  16. data/features/support/env.rb +37 -0
  17. data/features/support/fog_mock.rb +19 -0
  18. data/features/vagrant-openstack.feature +70 -0
  19. data/gemfiles/latest_stable.gemfile +13 -0
  20. data/gemfiles/oldest_current.gemfile +13 -0
  21. data/gemfiles/previous_release.gemfile +13 -0
  22. data/lib/vagrant-openstack.rb +53 -0
  23. data/lib/vagrant-openstack/action.rb +123 -0
  24. data/lib/vagrant-openstack/action/connect_openstack.rb +30 -0
  25. data/lib/vagrant-openstack/action/create_server.rb +134 -0
  26. data/lib/vagrant-openstack/action/delete_server.rb +26 -0
  27. data/lib/vagrant-openstack/action/is_created.rb +16 -0
  28. data/lib/vagrant-openstack/action/message_already_created.rb +16 -0
  29. data/lib/vagrant-openstack/action/message_not_created.rb +16 -0
  30. data/lib/vagrant-openstack/action/read_ssh_info.rb +52 -0
  31. data/lib/vagrant-openstack/action/read_state.rb +40 -0
  32. data/lib/vagrant-openstack/action/sync_folders.rb +125 -0
  33. data/lib/vagrant-openstack/config.rb +229 -0
  34. data/lib/vagrant-openstack/errors.rb +36 -0
  35. data/lib/vagrant-openstack/openstack_client.rb +91 -0
  36. data/lib/vagrant-openstack/plugin.rb +37 -0
  37. data/lib/vagrant-openstack/provider.rb +50 -0
  38. data/lib/vagrant-openstack/version.rb +5 -0
  39. data/locales/en.yml +85 -0
  40. data/spec/vagrant-openstack/config_spec.rb +184 -0
  41. data/stackrc +32 -0
  42. data/vagrant-openstack.gemspec +23 -0
  43. metadata +135 -0
@@ -0,0 +1,37 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Openstack Cloud provider 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.1.0"
10
+ raise "Openstack Cloud provider is only compatible with Vagrant 1.1+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Openstack
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "Openstack Cloud"
17
+ description <<-DESC
18
+ This plugin enables Vagrant to manage machines in Openstack Cloud.
19
+ DESC
20
+
21
+ config(:openstack, :provider) do
22
+ require_relative "config"
23
+ Config
24
+ end
25
+
26
+ provider(:openstack) do
27
+ # Setup some things
28
+ Openstack.init_i18n
29
+ Openstack.init_logging
30
+
31
+ # Load the actual provider
32
+ require_relative "provider"
33
+ Provider
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+ require "vagrant"
2
+
3
+ require "vagrant-openstack/action"
4
+
5
+ module VagrantPlugins
6
+ module Openstack
7
+ class Provider < Vagrant.plugin("2", :provider)
8
+ def initialize(machine)
9
+ @machine = machine
10
+ end
11
+
12
+ def action(name)
13
+ # Attempt to get the action method from the Action class if it
14
+ # exists, otherwise return nil to show that we don't support the
15
+ # given action.
16
+ action_method = "action_#{name}"
17
+ return Action.send(action_method) if Action.respond_to?(action_method)
18
+ nil
19
+ end
20
+
21
+ def ssh_info
22
+ # Run a custom action called "read_ssh_info" which does what it
23
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
24
+ # key in the environment.
25
+ env = @machine.action("read_ssh_info")
26
+ env[:machine_ssh_info]
27
+ end
28
+
29
+ def state
30
+ # Run a custom action we define called "read_state" which does
31
+ # what it says. It puts the state in the `:machine_state_id`
32
+ # key in the environment.
33
+ env = @machine.action("read_state")
34
+
35
+ state_id = env[:machine_state_id]
36
+
37
+ # Get the short and long description
38
+ short = I18n.t("vagrant_openstack.states.short_#{state_id}")
39
+ long = I18n.t("vagrant_openstack.states.long_#{state_id}")
40
+
41
+ # Return the MachineState object
42
+ Vagrant::MachineState.new(state_id, short, long)
43
+ end
44
+
45
+ def to_s
46
+ "Openstack Cloud"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Openstack
3
+ VERSION = "0.1"
4
+ end
5
+ end
@@ -0,0 +1,85 @@
1
+ en:
2
+ vagrant_openstack:
3
+ already_created: |-
4
+ The server is already created.
5
+ deleting_server: |-
6
+ Deleting server...
7
+ finding_flavor: |-
8
+ Finding flavor for server...
9
+ finding_image: |-
10
+ Finding image for server...
11
+ launching_server: |-
12
+ Launching a server with the following settings...
13
+ not_created: |-
14
+ The server hasn't been created yet. Run `vagrant up` first.
15
+ ready: |-
16
+ The server is ready!
17
+ timeout: |-
18
+ Timeout!
19
+ rsync_folder: |-
20
+ Rsyncing folder: %{hostpath} => %{guestpath}
21
+ waiting_for_build: |-
22
+ Waiting for the server to be built...
23
+ waiting_for_rackconnect: |-
24
+ Waiting for RackConnect to complete...
25
+ waiting_for_ssh: |-
26
+ Waiting for SSH to become available...
27
+ warn_networks: |-
28
+ Warning! The Openstack provider doesn't support any of the Vagrant
29
+ high-level network configurations (`config.vm.network`). They
30
+ will be silently ignored.
31
+
32
+ config:
33
+ api_key_required: |-
34
+ An API key is required.
35
+ username_required: |-
36
+ A username is required.
37
+ invalid_uri: |-
38
+ The value for %{key} is not a valid URI: %{uri}
39
+ metadata_must_be_hash: |-
40
+ Metadata must be a hash.
41
+
42
+ errors:
43
+ create_bad_state: |-
44
+ While creating the server, it transitioned to an unexpected
45
+ state: '%{state}', instead of properly booting. Run `vagrant status`
46
+ to find out what can be done about this state, or `vagrant destroy`
47
+ if you want to start over.
48
+ no_matching_flavor: |-
49
+ No matching flavor was found! Please check your flavor setting
50
+ to make sure you have a valid flavor chosen.
51
+ no_matching_image: |-
52
+ No matching image was found! Please check your image setting to
53
+ make sure you have a valid image chosen.
54
+ sync_method_error: |-
55
+ Value '%{sync_method_value}' is not allowed for 'sync_method' configuration parameter. Valid values are 'rsync' and 'none'
56
+ rsync_error: |-
57
+ There was an error when attemping to rsync a share folder.
58
+ Please inspect the error message below for more info.
59
+
60
+ Host path: %{hostpath}
61
+ Guest path: %{guestpath}
62
+ Error: %{stderr}
63
+ ssh_unavailble: |-
64
+ SSH server anavailable on instance %{host}. You should maybe increase the timeout value which currently is %{timeout} second(s).
65
+
66
+ states:
67
+ short_active: |-
68
+ active
69
+ long_active: |-
70
+ The server is up and running. Run `vagrant ssh` to access it.
71
+ short_build: |-
72
+ building
73
+ long_build: |-
74
+ The server is currently being built. You must wait for this to
75
+ complete before you can access it. You can delete the server, however,
76
+ by running `vagrant destroy`.
77
+ short_error: |-
78
+ error
79
+ long_error: |-
80
+ The server is in an erroneous state. Contact Openstack support
81
+ or destroy the machine with `vagrant destroy`.
82
+ short_not_created: |-
83
+ not created
84
+ long_not_created: |-
85
+ The server is not created. Run `vagrant up` to create it.
@@ -0,0 +1,184 @@
1
+ if ENV['COVERAGE'] != 'false'
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start
9
+ end
10
+
11
+ require "vagrant-openstack/config"
12
+ require 'fog'
13
+
14
+ describe VagrantPlugins::Openstack::Config do
15
+ describe "defaults" do
16
+ let(:vagrant_public_key) { Vagrant.source_root.join("keys/vagrant.pub") }
17
+
18
+ subject do
19
+ super().tap do |o|
20
+ o.finalize!
21
+ end
22
+ end
23
+
24
+ its(:api_key) { should be_nil }
25
+ its(:openstack_region) { should be_nil }
26
+ its(:openstack_compute_url) { should be_nil }
27
+ its(:openstack_auth_url) { should be_nil }
28
+ its(:flavor) { should eq(/m1.tiny/) }
29
+ its(:image) { should eq(/cirros/) }
30
+ its(:rackconnect) { should be_nil }
31
+ its(:network) { should be_nil }
32
+ its(:server_name) { should be_nil }
33
+ its(:username) { should be_nil }
34
+ its(:disk_config) { should be_nil }
35
+ its(:network) { should be_nil }
36
+ its(:rsync_includes) { should be_nil }
37
+ its(:keypair_name) { should be_nil }
38
+ its(:ssh_username) { should be_nil }
39
+ end
40
+
41
+ describe "overriding defaults" do
42
+ [:api_key,
43
+ :openstack_region,
44
+ :openstack_compute_url,
45
+ :openstack_auth_url,
46
+ :flavor,
47
+ :image,
48
+ :rackconnect,
49
+ :server_name,
50
+ :network,
51
+ :disk_config,
52
+ :username,
53
+ :keypair_name,
54
+ :ssh_username].each do |attribute|
55
+ it "should not default #{attribute} if overridden" do
56
+ subject.send("#{attribute}=".to_sym, "foo")
57
+ subject.finalize!
58
+ subject.send(attribute).should == "foo"
59
+ end
60
+ end
61
+
62
+ it "should not default rsync_includes if overridden" do
63
+ inc = "core"
64
+ subject.send(:rsync_include, inc)
65
+ subject.finalize!
66
+ subject.send(:rsync_includes).should include(inc)
67
+ end
68
+ end
69
+
70
+ describe "validation" do
71
+ let(:machine) { double("machine") }
72
+ let(:validation_errors) { subject.validate(machine)['Openstack Provider'] }
73
+ let(:error_message) { double("error message") }
74
+
75
+ before(:each) do
76
+ machine.stub_chain(:env, :root_path).and_return '/'
77
+ subject.username = 'foo'
78
+ subject.api_key = 'bar'
79
+ subject.keypair_name = 'keypair'
80
+ end
81
+
82
+ subject do
83
+ super().tap do |o|
84
+ o.finalize!
85
+ end
86
+ end
87
+
88
+ context "with invalid key" do
89
+ it "should raise an error" do
90
+ subject.nonsense1 = true
91
+ subject.nonsense2 = false
92
+ I18n.should_receive(:t).with('vagrant.config.common.bad_field',
93
+ { :fields => 'nonsense1, nonsense2' })
94
+ .and_return error_message
95
+ validation_errors.first.should == error_message
96
+ end
97
+ end
98
+ context "with good values" do
99
+ it "should validate" do
100
+ validation_errors.should be_empty
101
+ end
102
+ end
103
+
104
+ context "the keypair name" do
105
+ it "should error if not given" do
106
+ subject.keypair_name = nil
107
+ I18n.should_receive(:t).with('vagrant_openstack.config.keypair_name required').and_return error_message
108
+ validation_errors.first.should == error_message
109
+ end
110
+ end
111
+
112
+ context "the API key" do
113
+ it "should error if not given" do
114
+ subject.api_key = nil
115
+ I18n.should_receive(:t).with('vagrant_openstack.config.api_key required').and_return error_message
116
+ validation_errors.first.should == error_message
117
+ end
118
+ end
119
+
120
+ context "the username" do
121
+ it "should error if not given" do
122
+ subject.username = nil
123
+ I18n.should_receive(:t).with('vagrant_openstack.config.username required').and_return error_message
124
+ validation_errors.first.should == error_message
125
+ end
126
+ end
127
+
128
+ [:openstack_compute_url, :openstack_auth_url].each do |url|
129
+ context "the #{url}" do
130
+ it "should not validate if the URL is invalid" do
131
+ subject.send "#{url}=", 'baz'
132
+ I18n.should_receive(:t).with('vagrant_openstack.config.invalid_uri', {:key => url, :uri => 'baz'}).and_return error_message
133
+ validation_errors.first.should == error_message
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "openstack_auth_url" do
140
+ it "should return UNSET_VALUE if openstack_auth_url and openstack_region are UNSET" do
141
+ subject.openstack_auth_url.should == VagrantPlugins::Openstack::Config::UNSET_VALUE
142
+ end
143
+ it "should return UNSET_VALUE if openstack_auth_url is UNSET and openstack_region is :ord" do
144
+ subject.openstack_region = :ord
145
+ subject.openstack_auth_url.should == VagrantPlugins::Openstack::Config::UNSET_VALUE
146
+ end
147
+ it "should return custom endpoint if supplied and openstack_region is :lon" do
148
+ my_endpoint = 'http://custom-endpoint.com'
149
+ subject.openstack_region = :lon
150
+ subject.openstack_auth_url = my_endpoint
151
+ subject.openstack_auth_url.should == my_endpoint
152
+ end
153
+ it "should return custom endpoint if supplied and openstack_region is UNSET" do
154
+ my_endpoint = 'http://custom-endpoint.com'
155
+ subject.openstack_auth_url = my_endpoint
156
+ subject.openstack_auth_url.should == my_endpoint
157
+ end
158
+ end
159
+
160
+
161
+ describe "lon_region?" do
162
+ it "should return false if openstack_region is UNSET_VALUE" do
163
+ subject.openstack_region = VagrantPlugins::Openstack::Config::UNSET_VALUE
164
+ subject.send(:lon_region?).should be_false
165
+ end
166
+ it "should return false if openstack_region is nil" do
167
+ subject.openstack_region = nil
168
+ subject.send(:lon_region?).should be_false
169
+ end
170
+ it "should return false if openstack_region is :ord" do
171
+ subject.openstack_region = :ord
172
+ subject.send(:lon_region?).should be_false
173
+ end
174
+ it "should return true if openstack_region is 'lon'" do
175
+ subject.openstack_region = 'lon'
176
+ subject.send(:lon_region?).should be_true
177
+ end
178
+ it "should return true if openstack_Region is :lon" do
179
+ subject.openstack_region = :lon
180
+ subject.send(:lon_region?).should be_true
181
+ end
182
+ end
183
+
184
+ end
data/stackrc ADDED
@@ -0,0 +1,32 @@
1
+
2
+ #!/bin/bash
3
+
4
+ # With the addition of Keystone, to use an openstack cloud you should
5
+ # authenticate against keystone, which returns a **Token** and **Service
6
+ # Catalog**. The catalog contains the endpoint for all services the
7
+ # user/tenant has access to - including nova, glance, keystone, swift.
8
+ #
9
+ # *NOTE*: Using the 2.0 *auth api* does not mean that compute api is 2.0. We
10
+ # will use the 1.1 *compute api*
11
+ export OS_AUTH_URL=https://cloud.numergy.com:5000/v2.0/tokens
12
+ export OS_COMPUTE_URL=https://cloud.numergy.com:8774/v2/7f264bf82ce7420e8d7939f31dd1daac
13
+
14
+ # With the addition of Keystone we have standardized on the term **tenant**
15
+ # as the entity that owns the resources.
16
+ export OS_TENANT_ID=7f264bf82ce7420e8d7939f31dd1daac
17
+ export OS_TENANT_NAME="PaaS"
18
+
19
+ # In addition to the owning entity (tenant), openstack stores the entity
20
+ # performing the action as the **user**.
21
+ if [ -z "$OS_USERNAME" ]; then
22
+ echo "Please enter your OpenStack username: "
23
+ read -sr OS_USERNAME_INPUT
24
+ export OS_USERNAME=$OS_USERNAME_INPUT
25
+ fi
26
+
27
+ # With Keystone you pass the keystone password.
28
+ if [ -z "$OS_PASSWORD" ]; then
29
+ echo "Please enter your OpenStack Password: "
30
+ read -sr OS_PASSWORD_INPUT
31
+ export OS_PASSWORD=$OS_PASSWORD_INPUT
32
+ fi
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-openstack/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "vagrant-openstack-provider"
8
+ gem.version = VagrantPlugins::Openstack::VERSION
9
+ gem.authors = ["Guillaume Giamarchi", "Julien Vey"]
10
+ gem.email = ["guillaume.giamarchi@gmail.com", "vey.julien@gmail.com"]
11
+ gem.description = "Enables Vagrant to manage machines in Openstack Cloud."
12
+ gem.summary = "Enables Vagrant to manage machines in Openstack Cloud."
13
+ gem.homepage = "https://github.com/ggiamarchi/vagrant-openstack"
14
+
15
+ gem.add_development_dependency "rake"
16
+ gem.add_development_dependency "rspec", "~> 2.13.0"
17
+ gem.add_development_dependency "aruba"
18
+
19
+ gem.files = `git ls-files`.split($/)
20
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
+ gem.require_paths = ["lib"]
23
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-openstack-provider
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Guillaume Giamarchi
8
+ - Julien Vey
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 2.13.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 2.13.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: aruba
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ description: Enables Vagrant to manage machines in Openstack Cloud.
57
+ email:
58
+ - guillaume.giamarchi@gmail.com
59
+ - vey.julien@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - Appraisals
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - RELEASE.md
70
+ - Rakefile
71
+ - Vagrantfile
72
+ - dummy.box
73
+ - example_box/README.md
74
+ - example_box/metadata.json
75
+ - features/provision.feature
76
+ - features/steps/sdk_steps.rb
77
+ - features/steps/server_steps.rb
78
+ - features/support/env.rb
79
+ - features/support/fog_mock.rb
80
+ - features/vagrant-openstack.feature
81
+ - gemfiles/latest_stable.gemfile
82
+ - gemfiles/oldest_current.gemfile
83
+ - gemfiles/previous_release.gemfile
84
+ - lib/vagrant-openstack.rb
85
+ - lib/vagrant-openstack/action.rb
86
+ - lib/vagrant-openstack/action/connect_openstack.rb
87
+ - lib/vagrant-openstack/action/create_server.rb
88
+ - lib/vagrant-openstack/action/delete_server.rb
89
+ - lib/vagrant-openstack/action/is_created.rb
90
+ - lib/vagrant-openstack/action/message_already_created.rb
91
+ - lib/vagrant-openstack/action/message_not_created.rb
92
+ - lib/vagrant-openstack/action/read_ssh_info.rb
93
+ - lib/vagrant-openstack/action/read_state.rb
94
+ - lib/vagrant-openstack/action/sync_folders.rb
95
+ - lib/vagrant-openstack/config.rb
96
+ - lib/vagrant-openstack/errors.rb
97
+ - lib/vagrant-openstack/openstack_client.rb
98
+ - lib/vagrant-openstack/plugin.rb
99
+ - lib/vagrant-openstack/provider.rb
100
+ - lib/vagrant-openstack/version.rb
101
+ - locales/en.yml
102
+ - spec/vagrant-openstack/config_spec.rb
103
+ - stackrc
104
+ - vagrant-openstack.gemspec
105
+ homepage: https://github.com/ggiamarchi/vagrant-openstack
106
+ licenses: []
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.2.2
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Enables Vagrant to manage machines in Openstack Cloud.
128
+ test_files:
129
+ - features/provision.feature
130
+ - features/steps/sdk_steps.rb
131
+ - features/steps/server_steps.rb
132
+ - features/support/env.rb
133
+ - features/support/fog_mock.rb
134
+ - features/vagrant-openstack.feature
135
+ - spec/vagrant-openstack/config_spec.rb