fog-openstack 0.1.2 → 0.1.3

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/fog-openstack.gemspec +1 -1
  3. data/lib/fog/openstack.rb +46 -33
  4. data/lib/fog/openstack/docs/compute.md +2 -3
  5. data/lib/fog/openstack/docs/getting_started.md +5 -5
  6. data/lib/fog/openstack/docs/introspection.md +251 -0
  7. data/lib/fog/openstack/docs/metering.md +15 -1
  8. data/lib/fog/openstack/docs/planning.md +2 -2
  9. data/lib/fog/openstack/docs/storage.md +3 -4
  10. data/lib/fog/openstack/examples/compute/basics.rb +1 -1
  11. data/lib/fog/openstack/examples/compute/block_device_mapping_v2.rb +1 -3
  12. data/lib/fog/openstack/examples/identity/basics.rb +6 -7
  13. data/lib/fog/openstack/examples/image/upload-test-image.rb +5 -8
  14. data/lib/fog/openstack/examples/introspection/basics.rb +75 -0
  15. data/lib/fog/openstack/examples/planning/basics.rb +1 -1
  16. data/lib/fog/openstack/examples/storage/set-account-quota.rb +7 -9
  17. data/lib/fog/openstack/identity.rb +99 -5
  18. data/lib/fog/openstack/identity_v2.rb +4 -23
  19. data/lib/fog/openstack/identity_v3.rb +10 -22
  20. data/lib/fog/openstack/introspection.rb +133 -0
  21. data/lib/fog/openstack/models/introspection/rules.rb +29 -0
  22. data/lib/fog/openstack/models/introspection/rules_collection.rb +32 -0
  23. data/lib/fog/openstack/models/metering/events.rb +2 -2
  24. data/lib/fog/openstack/models/network/floating_ip.rb +24 -3
  25. data/lib/fog/openstack/network.rb +1 -0
  26. data/lib/fog/openstack/requests/compute/get_volume_details.rb +4 -0
  27. data/lib/fog/openstack/requests/introspection/abort_introspection.rb +25 -0
  28. data/lib/fog/openstack/requests/introspection/create_introspection.rb +35 -0
  29. data/lib/fog/openstack/requests/introspection/create_rules.rb +37 -0
  30. data/lib/fog/openstack/requests/introspection/delete_rules.rb +23 -0
  31. data/lib/fog/openstack/requests/introspection/delete_rules_all.rb +23 -0
  32. data/lib/fog/openstack/requests/introspection/get_introspection.rb +24 -0
  33. data/lib/fog/openstack/requests/introspection/get_introspection_details.rb +24 -0
  34. data/lib/fog/openstack/requests/introspection/get_rules.rb +24 -0
  35. data/lib/fog/openstack/requests/introspection/list_rules.rb +24 -0
  36. data/lib/fog/openstack/version.rb +1 -1
  37. data/tests/fixtures/introspection.yaml +287 -0
  38. data/tests/openstack/identity_version_tests.rb +25 -0
  39. data/tests/openstack/models/network/floating_ip_tests.rb +14 -1
  40. data/tests/openstack/requests/introspection/introspection_tests.rb +297 -0
  41. data/tests/openstack/requests/introspection/rules_tests.rb +46 -0
  42. metadata +22 -4
@@ -17,13 +17,13 @@ If using Ruby 1.8.x execute:
17
17
 
18
18
  ```ruby
19
19
  require 'rubygems'
20
- require 'fog'
20
+ require 'fog/openstack'
21
21
  ```
22
22
 
23
23
  If using Ruby 1.9.x execute:
24
24
 
25
25
  ```ruby
26
- require 'fog'
26
+ require 'fog/openstack'
27
27
  ```
28
28
 
29
29
  ## Create Service
@@ -15,13 +15,13 @@ If using Ruby 1.8.x execute:
15
15
 
16
16
  ```ruby
17
17
  require 'rubygems'
18
- require 'fog'
18
+ require 'fog/openstack'
19
19
  ```
20
20
 
21
21
  If using Ruby 1.9.x execute:
22
22
 
23
23
  ```ruby
24
- require 'fog'
24
+ require 'fog/openstack'
25
25
  ```
26
26
 
27
27
  ## Create Service
@@ -29,8 +29,7 @@ require 'fog'
29
29
  Next, create a connection to Swift:
30
30
 
31
31
  ```ruby
32
- service = Fog::Storage.new({
33
- :provider => 'OpenStack', # OpenStack Fog provider
32
+ service = Fog::Storage::OpenStack.new({
34
33
  :openstack_username => USERNAME, # Your OpenStack Username
35
34
  :openstack_api_key => PASSWORD, # Your OpenStack Password
36
35
  :openstack_auth_url => 'http://YOUR_OPENSTACK_ENDPOINT:PORT/v2.0/tokens'
@@ -1,6 +1,6 @@
1
1
  # OpenStack Compute (Nova) Example
2
2
 
3
- require 'fog'
3
+ require 'fog/openstack'
4
4
 
5
5
  auth_url = "https://example.net/v2.0/tokens"
6
6
  username = 'admin@example.net'
@@ -1,6 +1,5 @@
1
1
  # OpenStack Compute (Nova) Example
2
2
 
3
- require 'fog'
4
3
  require 'fog/openstack'
5
4
 
6
5
  auth_url = "https://example.net/v2.0/tokens"
@@ -8,8 +7,7 @@ username = 'admin@example.net'
8
7
  password = 'secret'
9
8
  tenant = 'My Compute Tenant' # String
10
9
 
11
- compute_client ||= ::Fog::Compute.new(
12
- :provider => :openstack,
10
+ compute_client ||= ::Fog::Compute::OpenStack.new(
13
11
  :openstack_api_key => password,
14
12
  :openstack_username => username,
15
13
  :openstack_auth_url => auth_url,
@@ -1,18 +1,17 @@
1
1
  # OpenStack Identity Service (Keystone) Example
2
2
 
3
- require 'fog'
3
+ require 'fog/openstack'
4
4
  require 'pp'
5
5
 
6
6
  auth_url = "https://example.net/v2.0/tokens"
7
7
  username = 'admin@example.net'
8
8
  password = 'secret'
9
9
 
10
- keystone = Fog::Identity.new :provider => 'OpenStack',
11
- :openstack_auth_url => auth_url,
12
- :openstack_username => username,
13
- :openstack_api_key => password
14
- # Optional, self-signed certs
15
- #:connection_options => { :ssl_verify_peer => false }
10
+ keystone = Fog::Identity::OpenStack.new :openstack_auth_url => auth_url,
11
+ :openstack_username => username,
12
+ :openstack_api_key => password
13
+ # Optional, self-signed certs
14
+ #:connection_options => { :ssl_verify_peer => false }
16
15
 
17
16
  #
18
17
  # Listing keystone tenants
@@ -1,7 +1,7 @@
1
1
  require 'securerandom'
2
2
  require 'rubygems/package'
3
3
  require 'zlib'
4
- require 'fog'
4
+ require 'fog/openstack'
5
5
 
6
6
  #
7
7
  # Download CirrOS 0.3.0 image from launchpad (~6.5MB) to /tmp
@@ -43,13 +43,10 @@ Gem::Package::TarReader.new(Zlib::GzipReader.open(image_out.path)).each do |entr
43
43
  end
44
44
  end
45
45
 
46
- image_service = Fog::Image.new({
47
- :provider => 'OpenStack',
48
- :openstack_api_key => ENV['OS_PASSWORD'],
49
- :openstack_username => ENV["OS_USERNAME"],
50
- :openstack_auth_url => ENV["OS_AUTH_URL"] + "/tokens",
51
- :openstack_tenant => ENV["OS_TENANT_NAME"]
52
- })
46
+ image_service = Fog::Image::OpenStack.new :openstack_api_key => ENV['OS_PASSWORD'],
47
+ :openstack_username => ENV["OS_USERNAME"],
48
+ :openstack_auth_url => ENV["OS_AUTH_URL"] + "/tokens",
49
+ :openstack_tenant => ENV["OS_TENANT_NAME"]
53
50
 
54
51
  puts "Uploading AKI..."
55
52
  aki = image_service.images.create :name => 'cirros-0.3.0-amd64-aki',
@@ -0,0 +1,75 @@
1
+
2
+ require 'rubygems'
3
+ require 'fog/openstack' # version >= 1.37
4
+
5
+ auth_url = "https://example.net:5000/v3/auth/tokens"
6
+ username = 'admin@example.net'
7
+ password = 'secret'
8
+ project = 'admin'
9
+
10
+ @connection_params = {
11
+ :openstack_auth_url => auth_url,
12
+ :openstack_username => username,
13
+ :openstack_api_key => password,
14
+ :openstack_project_name => project,
15
+ :openstack_domain_id => "default"
16
+ }
17
+
18
+ inspector = Fog::Introspection::OpenStack.new(@connection_params)
19
+
20
+ # Introspection of an Ironic node
21
+ ironic = Fog::Baremetal::OpenStack.new(@connection_params)
22
+ nodes = ironic.list_nodes
23
+ node1_uuid = nodes.body["nodes"][0]["uuid"]
24
+
25
+ # Launch introspection
26
+ inspector.create_introspection(node1_uuid)
27
+
28
+ # Introspection status
29
+ inspector.get_introspection(node1_uuid)
30
+
31
+ # Abort introspection
32
+ inspector.abort_introspection(node1_uuid)
33
+
34
+ # Retrieve introspection data
35
+ # Note: introspection must be finished and ended successfully
36
+ inspector.get_introspection_details(node1_uuid)
37
+
38
+ ## Introspection Rules
39
+ # Create a set of rules
40
+ rules = {
41
+ "description" => "Successful Rule",
42
+ "actions" => [
43
+ {
44
+ "action" => "set-attribute",
45
+ "path" => "/extra/rule_success",
46
+ "value" => "yes"
47
+ }
48
+ ],
49
+ "conditions" => [
50
+ {
51
+ "field" => "memory_mb",
52
+ "op" => "ge",
53
+ "value" => 256
54
+ },
55
+ {
56
+ "field" => "local_gb",
57
+ "op" => "ge",
58
+ "value" => 1
59
+ }
60
+ ]
61
+ }
62
+ inspector.create_rules(rules)
63
+
64
+ # List all rules set
65
+ rules1 = inspector.list_rules
66
+
67
+ # Show a rules set
68
+ rules1_uuid = rules1[:body]["rules"][0]['uuid']
69
+ inspector.get_rules(rules1_uuid)
70
+
71
+ # Delete a specific rules set
72
+ inspector.delete_rules(rules1_uuid)
73
+
74
+ # Destroys all rules sets
75
+ inspector.delete_rules_all
@@ -1,6 +1,6 @@
1
1
  # OpenStack Planning Service (Tuskar) Example
2
2
 
3
- require 'fog'
3
+ require 'fog/openstack'
4
4
  require 'pp'
5
5
 
6
6
  auth_url = "https://example.net/v2.0/tokens"
@@ -1,4 +1,4 @@
1
- require 'fog'
1
+ require 'fog/openstack'
2
2
  require 'pp'
3
3
 
4
4
  #
@@ -28,18 +28,16 @@ Excon.defaults[:ssl_verify_peer] = false
28
28
  # to retrieve the list of tenants available and find
29
29
  # the tenant we want to set the quotas for.
30
30
  #
31
- id = Fog::Identity.new :provider => 'OpenStack',
32
- :openstack_auth_url => auth_url,
33
- :openstack_username => user,
34
- :openstack_api_key => password
31
+ id = Fog::Identity::OpenStack.new :openstack_auth_url => auth_url,
32
+ :openstack_username => user,
33
+ :openstack_api_key => password
35
34
 
36
35
  #
37
36
  # Storage service (Swift)
38
37
  #
39
- st = Fog::Storage.new :provider => 'OpenStack',
40
- :openstack_auth_url => auth_url,
41
- :openstack_username => user,
42
- :openstack_api_key => password
38
+ st = Fog::Storage::OpenStack.new :openstack_auth_url => auth_url,
39
+ :openstack_username => user,
40
+ :openstack_api_key => password
43
41
 
44
42
  id.tenants.each do |t|
45
43
  # We want to set the account quota for tenant demo@test.lan
@@ -3,25 +3,119 @@
3
3
  module Fog
4
4
  module Identity
5
5
  class OpenStack < Fog::Service
6
+ requires :openstack_auth_url
7
+ recognizes :openstack_auth_token, :openstack_management_url, :persistent,
8
+ :openstack_service_type, :openstack_service_name, :openstack_tenant,
9
+ :openstack_endpoint_type, :openstack_region, :openstack_domain_id,
10
+ :openstack_project_name, :openstack_domain_name,
11
+ :openstack_user_domain, :openstack_project_domain,
12
+ :openstack_user_domain_id, :openstack_project_domain_id,
13
+ :openstack_api_key, :openstack_current_user_id, :openstack_userid, :openstack_username,
14
+ :current_user, :current_user_id, :current_tenant,
15
+ :provider, :openstack_identity_prefix, :openstack_endpoint_path_matches
6
16
 
7
17
  # Fog::Identity::OpenStack.new() will return a Fog::Identity::OpenStack::V2 or a Fog::Identity::OpenStack::V3,
8
18
  # depending on whether the auth URL is for an OpenStack Identity V2 or V3 API endpoint
9
19
  def self.new(args = {})
10
- @openstack_auth_uri = URI.parse(args[:openstack_auth_url]) if args[:openstack_auth_url]
11
20
  if self.inspect == 'Fog::Identity::OpenStack'
12
- service = (is_v3? args) ? Fog::Identity::OpenStack::V3.new(args) : Fog::Identity::OpenStack::V2.new(args)
21
+ identity = super
22
+ config = identity.config
23
+ service = identity.v3? ? Fog::Identity::OpenStack::V3.new(config) : Fog::Identity::OpenStack::V2.new(config)
13
24
  else
14
25
  service = Fog::Service.new(args)
15
26
  end
16
27
  service
17
28
  end
18
29
 
19
- private
30
+ class Mock
31
+ attr_reader :config
20
32
 
21
- def self.is_v3?(args)
22
- @openstack_auth_uri && @openstack_auth_uri.path =~ /\/v3/
33
+ def initialize(options = {})
34
+ @openstack_auth_uri = URI.parse(options[:openstack_auth_url])
35
+ @openstack_identity_prefix = options[:openstack_identity_prefix]
36
+ @config = options
37
+ end
38
+
39
+ def v3?
40
+ if @openstack_identity_prefix
41
+ @openstack_identity_prefix =~ /v3/
42
+ else
43
+ @openstack_auth_uri && @openstack_auth_uri.path =~ %r{/v3}
44
+ end
45
+ end
23
46
  end
24
47
 
48
+ class Real
49
+ DEFAULT_SERVICE_TYPE_V3 = %w(identity_v3 identityv3 identity).collect(&:freeze).freeze
50
+ DEFAULT_SERVICE_TYPE = %w(identity).collect(&:freeze).freeze
51
+
52
+ def self.not_found_class
53
+ Fog::Identity::OpenStack::NotFound
54
+ end
55
+ include Fog::OpenStack::Common
56
+
57
+ def initialize(options = {})
58
+ if options.respond_to?(:config_service?) && options.config_service?
59
+ configure(options)
60
+ return
61
+ end
62
+
63
+ initialize_identity(options)
64
+
65
+ @openstack_service_type = options[:openstack_service_type] || default_service_type(options)
66
+ @openstack_service_name = options[:openstack_service_name]
67
+
68
+ @connection_options = options[:connection_options] || {}
69
+
70
+ @openstack_endpoint_type = options[:openstack_endpoint_type] || 'adminURL'
71
+ initialize_endpoint_path_matches(options)
72
+
73
+ authenticate
74
+
75
+ if options[:openstack_identity_prefix]
76
+ @path = "/#{options[:openstack_identity_prefix]}/#{@path}"
77
+ end
78
+
79
+ @persistent = options[:persistent] || false
80
+ @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
81
+ end
82
+
83
+ def v3?
84
+ @path && @path =~ %r{/v3}
85
+ end
86
+
87
+ def config_service?
88
+ true
89
+ end
90
+
91
+ def config
92
+ self
93
+ end
94
+
95
+ private
96
+
97
+ def default_service_type(options)
98
+ unless options[:openstack_identity_prefix]
99
+ if @openstack_auth_uri.path =~ %r{/v3} ||
100
+ (options[:openstack_endpoint_path_matches] && options[:openstack_endpoint_path_matches] =~ '/v3')
101
+ return DEFAULT_SERVICE_TYPE_V3
102
+ end
103
+ end
104
+ DEFAULT_SERVICE_TYPE
105
+ end
106
+
107
+ def initialize_endpoint_path_matches(options)
108
+ if options[:openstack_endpoint_path_matches]
109
+ @openstack_endpoint_path_matches = options[:openstack_endpoint_path_matches]
110
+ end
111
+ end
112
+
113
+ def configure(source)
114
+ source.instance_variables.each do |v|
115
+ instance_variable_set(v, source.instance_variable_get(v))
116
+ end
117
+ end
118
+ end
25
119
  end
26
120
  end
27
121
  end
@@ -171,30 +171,11 @@ module Fog
171
171
  end
172
172
  end
173
173
 
174
- class Real
175
- def self.not_found_class
176
- Fog::Identity::OpenStack::NotFound
177
- end
178
- include Fog::OpenStack::Common
179
-
180
- def initialize(options={})
181
- initialize_identity options
182
-
183
- @openstack_service_type = options[:openstack_service_type] || ['identity']
184
- @openstack_service_name = options[:openstack_service_name]
185
-
186
- @connection_options = options[:connection_options] || {}
187
-
188
- @openstack_endpoint_type = options[:openstack_endpoint_type] || 'adminURL'
189
-
190
- authenticate
191
-
192
- if options[:openstack_identity_prefix]
193
- @path = "/#{options[:openstack_identity_prefix]}/#{@path}"
194
- end
174
+ class Real < Fog::Identity::OpenStack::Real
175
+ private
195
176
 
196
- @persistent = options[:persistent] || false
197
- @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
177
+ def default_service_type(_)
178
+ DEFAULT_SERVICE_TYPE
198
179
  end
199
180
  end
200
181
  end
@@ -148,31 +148,19 @@ module Fog
148
148
  version
149
149
  end
150
150
 
151
- class Real
152
- def self.not_found_class
153
- Fog::Identity::OpenStack::NotFound
154
- end
155
- include Fog::OpenStack::Common
156
-
157
- def initialize(options={})
158
- initialize_identity options
159
-
160
- @openstack_service_type = options[:openstack_service_type] || ['identity_v3','identityv3','identity']
161
- @openstack_service_name = options[:openstack_service_name]
151
+ class Real < Fog::Identity::OpenStack::Real
152
+ private
162
153
 
163
- @connection_options = options[:connection_options] || {}
164
-
165
- @openstack_endpoint_type = options[:openstack_endpoint_type] || 'adminURL'
166
-
167
- @openstack_endpoint_path_matches = options[:openstack_endpoint_path_matches] ||= /\/v3/
168
- authenticate
154
+ def default_service_type(_)
155
+ DEFAULT_SERVICE_TYPE_V3
156
+ end
169
157
 
170
- if options[:openstack_identity_prefix]
171
- @path = "/#{options[:openstack_identity_prefix]}/#{@path}"
158
+ def initialize_endpoint_path_matches(options)
159
+ if options[:openstack_endpoint_path_matches]
160
+ @openstack_endpoint_path_matches = options[:openstack_endpoint_path_matches]
161
+ else
162
+ @openstack_endpoint_path_matches = %r{/v3} unless options[:openstack_identity_prefix]
172
163
  end
173
-
174
- @persistent = options[:persistent] || false
175
- @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
176
164
  end
177
165
  end
178
166
  end
@@ -0,0 +1,133 @@
1
+ require 'yaml'
2
+
3
+ module Fog
4
+ module Introspection
5
+ class OpenStack < Fog::Service
6
+ SUPPORTED_VERSIONS = /v1/
7
+
8
+ requires :openstack_auth_url
9
+ recognizes :openstack_auth_token, :openstack_management_url,
10
+ :persistent, :openstack_service_type, :openstack_service_name,
11
+ :openstack_tenant, :openstack_tenant_id,
12
+ :openstack_api_key, :openstack_username, :openstack_identity_endpoint,
13
+ :current_user, :current_tenant, :openstack_region,
14
+ :openstack_endpoint_type,
15
+ :openstack_project_name, :openstack_project_id,
16
+ :openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
17
+ :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id
18
+
19
+ ## REQUESTS
20
+ #
21
+ request_path 'fog/openstack/requests/introspection'
22
+
23
+ # Introspection requests
24
+ request :create_introspection
25
+ request :get_introspection
26
+ request :abort_introspection
27
+ request :get_introspection_details
28
+
29
+ # Rules requests
30
+ request :create_rules
31
+ request :list_rules
32
+ request :delete_rules_all
33
+ request :get_rules
34
+ request :delete_rules
35
+
36
+ ## MODELS
37
+ #
38
+ model_path 'fog/openstack/models/introspection'
39
+ model :rules
40
+ collection :rules_collection
41
+
42
+ class Mock
43
+ def self.data
44
+ @data ||= Hash.new do |hash, key|
45
+ # Introspection data is *huge* we load it from a yaml file
46
+ file = "../../../../tests/fixtures/introspection.yaml"
47
+ hash[key] = YAML.load(File.read(File.expand_path(file, __FILE__)))
48
+ end
49
+ end
50
+
51
+ def self.reset
52
+ @data = nil
53
+ end
54
+
55
+ include Fog::OpenStack::Core
56
+
57
+ def initialize(options = {})
58
+ @auth_token = Fog::Mock.random_base64(64)
59
+ @auth_token_expiration = (Time.now.utc + 86_400).iso8601
60
+
61
+ initialize_identity options
62
+ end
63
+
64
+ def data
65
+ self.class.data[@openstack_username]
66
+ end
67
+
68
+ def reset_data
69
+ self.class.data.delete(@openstack_username)
70
+ end
71
+ end
72
+
73
+ class Real
74
+ include Fog::OpenStack::Core
75
+
76
+ def initialize(options = {})
77
+ initialize_identity options
78
+
79
+ @openstack_service_type = options[:openstack_service_type] || ['introspection']
80
+ @openstack_service_name = options[:openstack_service_name]
81
+
82
+ @connection_options = options[:connection_options] || {}
83
+
84
+ authenticate
85
+
86
+ unless @path.match(SUPPORTED_VERSIONS)
87
+ @path = "/" + Fog::OpenStack.get_supported_version(
88
+ SUPPORTED_VERSIONS,
89
+ @openstack_management_uri,
90
+ @auth_token,
91
+ @connection_options
92
+ )
93
+ end
94
+
95
+ @persistent = options[:persistent] || false
96
+ @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
97
+ end
98
+
99
+ def request(params)
100
+ response = @connection.request(
101
+ params.merge(
102
+ :headers => {
103
+ 'Content-Type' => 'application/json',
104
+ 'X-Auth-Token' => @auth_token
105
+ }.merge!(params[:headers] || {}),
106
+ :path => "#{@path}/#{params[:path]}"
107
+ )
108
+ )
109
+ rescue Excon::Errors::Unauthorized => error
110
+ if error.response.body != "Bad username or password" # token expiration
111
+ @openstack_must_reauthenticate = true
112
+ authenticate
113
+ retry
114
+ else # bad credentials
115
+ raise error
116
+ end
117
+ rescue Excon::Errors::HTTPStatusError => error
118
+ raise case error
119
+ when Excon::Errors::NotFound
120
+ Fog::Introspection::OpenStack::NotFound.slurp(error)
121
+ else
122
+ error
123
+ end
124
+ else
125
+ unless response.body.empty?
126
+ response.body = Fog::JSON.decode(response.body)
127
+ end
128
+ response
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end