fog-openstack 0.1.19 → 0.1.20

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/docs/orchestration.md +23 -0
  3. data/examples/event/basics.rb +22 -0
  4. data/gemfiles/Gemfile-1.9 +1 -0
  5. data/lib/fog/compute/openstack.rb +28 -2
  6. data/lib/fog/compute/openstack/models/os_interface.rb +15 -0
  7. data/lib/fog/compute/openstack/models/os_interfaces.rb +28 -0
  8. data/lib/fog/compute/openstack/models/server.rb +5 -0
  9. data/lib/fog/compute/openstack/requests/create_os_interface.rb +42 -0
  10. data/lib/fog/compute/openstack/requests/delete_key_pair.rb +1 -1
  11. data/lib/fog/compute/openstack/requests/delete_os_interface.rb +24 -0
  12. data/lib/fog/compute/openstack/requests/get_hypervisor.rb +64 -0
  13. data/lib/fog/compute/openstack/requests/get_key_pair.rb +1 -1
  14. data/lib/fog/compute/openstack/requests/get_os_interface.rb +24 -0
  15. data/lib/fog/compute/openstack/requests/list_hypervisor_servers.rb +42 -0
  16. data/lib/fog/compute/openstack/requests/list_hypervisors.rb +27 -0
  17. data/lib/fog/compute/openstack/requests/list_hypervisors_detail.rb +71 -0
  18. data/lib/fog/compute/openstack/requests/list_os_interfaces.rb +24 -0
  19. data/lib/fog/dns/openstack/v2/requests/create_zone.rb +1 -1
  20. data/lib/fog/event/openstack.rb +120 -0
  21. data/lib/fog/event/openstack/models/event.rb +16 -0
  22. data/lib/fog/event/openstack/models/events.rb +23 -0
  23. data/lib/fog/event/openstack/requests/get_event.rb +27 -0
  24. data/lib/fog/event/openstack/requests/list_events.rb +42 -0
  25. data/lib/fog/identity/openstack/v3/models/domains.rb +23 -11
  26. data/lib/fog/key_manager/openstack.rb +1 -1
  27. data/lib/fog/metering/openstack.rb +1 -0
  28. data/lib/fog/network/openstack.rb +10 -0
  29. data/lib/fog/network/openstack/models/subnet_pool.rb +47 -0
  30. data/lib/fog/network/openstack/models/subnet_pools.rb +33 -0
  31. data/lib/fog/network/openstack/requests/create_subnet_pool.rb +56 -0
  32. data/lib/fog/network/openstack/requests/delete_subnet_pool.rb +28 -0
  33. data/lib/fog/network/openstack/requests/get_subnet_pool.rb +29 -0
  34. data/lib/fog/network/openstack/requests/list_subnet_pools.rb +25 -0
  35. data/lib/fog/network/openstack/requests/update_subnet_pool.rb +46 -0
  36. data/lib/fog/openstack.rb +90 -68
  37. data/lib/fog/openstack/core.rb +53 -7
  38. data/lib/fog/openstack/version.rb +1 -1
  39. data/lib/fog/shared_file_system/openstack.rb +51 -8
  40. data/lib/fog/shared_file_system/openstack/models/share.rb +28 -0
  41. data/lib/fog/shared_file_system/openstack/models/share_access_rule.rb +35 -0
  42. data/lib/fog/shared_file_system/openstack/models/share_access_rules.rb +30 -0
  43. data/lib/fog/shared_file_system/openstack/requests/extend_share.rb +24 -0
  44. data/lib/fog/shared_file_system/openstack/requests/get_limits.rb +45 -0
  45. data/lib/fog/shared_file_system/openstack/requests/get_quota.rb +26 -0
  46. data/lib/fog/shared_file_system/openstack/requests/grant_share_access.rb +34 -0
  47. data/lib/fog/shared_file_system/openstack/requests/list_share_access_rules.rb +29 -0
  48. data/lib/fog/shared_file_system/openstack/requests/revoke_share_access.rb +24 -0
  49. data/lib/fog/shared_file_system/openstack/requests/share_action.rb +16 -0
  50. data/lib/fog/shared_file_system/openstack/requests/shrink_share.rb +24 -0
  51. data/lib/fog/shared_file_system/openstack/requests/update_quota.rb +30 -0
  52. metadata +36 -2
@@ -0,0 +1,56 @@
1
+ module Fog
2
+ module Network
3
+ class OpenStack
4
+ class Real
5
+ def create_subnet_pool(name, prefixes, options = {})
6
+ data = {
7
+ 'subnetpool' => {
8
+ 'name' => name,
9
+ 'prefixes' => prefixes
10
+ }
11
+ }
12
+
13
+ vanilla_options = [:description, :address_scope_id, :shared,
14
+ :min_prefixlen, :max_prefixlen, :default_prefixlen]
15
+ vanilla_options.select { |o| options.key?(o) }.each do |key|
16
+ data['subnetpool'][key] = options[key]
17
+ end
18
+
19
+ request(
20
+ :body => Fog::JSON.encode(data),
21
+ :expects => [201],
22
+ :method => 'POST',
23
+ :path => 'subnetpools'
24
+ )
25
+ end
26
+ end
27
+
28
+ class Mock
29
+ def create_subnet_pool(name, prefixes, options = {})
30
+ response = Excon::Response.new
31
+ response.status = 201
32
+ data = {
33
+ 'id' => Fog::Mock.random_numbers(6).to_s,
34
+ 'name' => name,
35
+ 'prefixes' => prefixes,
36
+ 'description' => options[:description],
37
+ 'min_prefixlen' => options[:min_prefixlen] || 64,
38
+ 'max_prefixlen' => options[:max_prefixlen] || 64,
39
+ 'default_prefixlen' => options[:default_prefixlen] || 64,
40
+ 'address_scope_id' => options[:address_scope_id],
41
+ 'default_quota' => options[:default_quota],
42
+ 'ip_version' => options[:ip_version] || 4,
43
+ 'shared' => options[:shared].nil? ? false : options[:shared],
44
+ 'is_default' => options[:is_default].nil? ? false : options[:is_default],
45
+ 'created_at' => Time.now.to_s,
46
+ 'updated_at' => Time.now.to_s,
47
+ 'tenant_id' => Fog::Mock.random_hex(8).to_s
48
+ }
49
+ self.data[:subnet_pools][data['id']] = data
50
+ response.body = {'subnetpool' => data}
51
+ response
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,28 @@
1
+ module Fog
2
+ module Network
3
+ class OpenStack
4
+ class Real
5
+ def delete_subnet_pool(subnet_pool_id)
6
+ request(
7
+ :expects => 204,
8
+ :method => 'DELETE',
9
+ :path => "subnetpools/#{subnet_pool_id}"
10
+ )
11
+ end
12
+ end
13
+
14
+ class Mock
15
+ def delete_subnet_pool(subnet_pool_id)
16
+ response = Excon::Response.new
17
+ if list_subnet_pools.body['subnetpools'].map { |r| r['id'] }.include? subnet_pool_id
18
+ data[:subnet_pools].delete(subnet_pool_id)
19
+ response.status = 204
20
+ response
21
+ else
22
+ raise Fog::Network::OpenStack::NotFound
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module Fog
2
+ module Network
3
+ class OpenStack
4
+ class Real
5
+ def get_subnet_pool(subnet_pool_id)
6
+ request(
7
+ :expects => [200],
8
+ :method => 'GET',
9
+ :path => "subnetpools/#{subnet_pool_id}"
10
+ )
11
+ end
12
+ end
13
+
14
+ class Mock
15
+ def get_subnet_pool(subnet_pool_id)
16
+ data = self.data[:subnet_pools][subnet_pool_id]
17
+ if data
18
+ response = Excon::Response.new
19
+ response.status = 200
20
+ response.body = {'subnetpool' => data}
21
+ response
22
+ else
23
+ raise Fog::Network::OpenStack::NotFound
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module Fog
2
+ module Network
3
+ class OpenStack
4
+ class Real
5
+ def list_subnet_pools(filters = {})
6
+ request(
7
+ :expects => 200,
8
+ :method => 'GET',
9
+ :path => 'subnetpools',
10
+ :query => filters
11
+ )
12
+ end
13
+ end
14
+
15
+ class Mock
16
+ def list_subnet_pools(_filters = {})
17
+ Excon::Response.new(
18
+ :body => {'subnetpools' => data[:subnet_pools].values},
19
+ :status => 200
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ module Fog
2
+ module Network
3
+ class OpenStack
4
+ class Real
5
+ def update_subnet_pool(subnet_pool_id, options = {})
6
+ data = {'subnetpool' => {}}
7
+
8
+ vanilla_options = [:name, :description, :prefixes, :address_scope_id,
9
+ :min_prefixlen, :max_prefixlen, :default_prefixlen]
10
+ vanilla_options.select { |o| options.key?(o) }.each do |key|
11
+ data['subnetpool'][key] = options[key]
12
+ end
13
+
14
+ request(
15
+ :body => Fog::JSON.encode(data),
16
+ :expects => 200,
17
+ :method => 'PUT',
18
+ :path => "subnetpools/#{subnet_pool_id}"
19
+ )
20
+ end
21
+ end
22
+
23
+ class Mock
24
+ def update_subnet_pool(subnet_pool_id, options = {})
25
+ subnet_pool = list_subnet_pools.body['subnetpools'].find { |s| s['id'] == subnet_pool_id }
26
+ if subnet_pool
27
+ subnet_pool['name'] = options[:name]
28
+ subnet_pool['description'] = options[:description]
29
+ subnet_pool['prefixes'] = options[:prefixes] || []
30
+ subnet_pool['min_prefixlen'] = options[:min_prefixlen] || 64
31
+ subnet_pool['max_prefixlen'] = options[:max_prefixlen] || 64
32
+ subnet_pool['default_prefixlen'] = options[:default_prefixlen] || 64
33
+ subnet_pool['address_scope_id'] = options[:address_scope_id]
34
+ subnet_pool['updated_at'] = Time.now.to_s
35
+ response = Excon::Response.new
36
+ response.body = {'subnetpool' => subnet_pool}
37
+ response.status = 200
38
+ response
39
+ else
40
+ raise Fog::Network::OpenStack::NotFound
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -29,6 +29,10 @@ module Fog
29
29
  end
30
30
  end
31
31
 
32
+ module Event
33
+ autoload :OpenStack, File.expand_path('../event/openstack', __FILE__)
34
+ end
35
+
32
36
  module Identity
33
37
  autoload :OpenStack, File.expand_path('../identity/openstack', __FILE__)
34
38
 
@@ -51,6 +55,10 @@ module Fog
51
55
  autoload :OpenStack, File.expand_path('../introspection/openstack', __FILE__)
52
56
  end
53
57
 
58
+ module KeyManager
59
+ autoload :OpenStack, File.expand_path('../key_manager/openstack', __FILE__)
60
+ end
61
+
54
62
  module Metering
55
63
  autoload :OpenStack, File.expand_path('../metering/openstack', __FILE__)
56
64
  end
@@ -100,32 +108,29 @@ module Fog
100
108
  end
101
109
  end
102
110
 
103
- module KeyManager
104
- autoload :OpenStack, File.expand_path('../key_manager/openstack', __FILE__)
105
- end
106
-
107
111
  module OpenStack
108
112
  extend Fog::Provider
109
113
 
114
+ service(:baremetal, 'Baremetal')
110
115
  service(:compute, 'Compute')
111
- service(:image, 'Image')
116
+ service(:container_infra, 'ContainerInfra')
117
+ service(:dns, 'DNS')
118
+ service(:event, 'Event')
112
119
  service(:identity, 'Identity')
113
- service(:network, 'Network')
114
- service(:storage, 'Storage')
115
- service(:volume, 'Volume')
120
+ service(:image, 'Image')
121
+ service(:introspection, 'Introspection')
122
+ service(:key, 'KeyManager')
116
123
  service(:metering, 'Metering')
117
124
  service(:metric, 'Metric')
118
- service(:orchestration, 'Orchestration')
125
+ service(:monitoring, 'Monitoring')
126
+ service(:network, 'Network')
119
127
  service(:nfv, 'NFV')
120
- service(:baremetal, 'Baremetal')
128
+ service(:orchestration, 'Orchestration')
121
129
  service(:planning, 'Planning')
122
- service(:introspection, 'Introspection')
123
- service(:monitoring, 'Monitoring')
124
- service(:workflow, 'Workflow')
125
- service(:dns, 'DNS')
126
- service(:key, 'KeyManager')
127
130
  service(:shared_file_system, 'SharedFileSystem')
128
- service(:container_infra, 'ContainerInfra')
131
+ service(:storage, 'Storage')
132
+ service(:volume, 'Volume')
133
+ service(:workflow, 'Workflow')
129
134
 
130
135
  @token_cache = {}
131
136
 
@@ -259,7 +264,7 @@ module Fog
259
264
 
260
265
  # Keystone Style Auth
261
266
  def self.authenticate_v3(options, connection_options = {})
262
- uri = options[:openstack_auth_uri]
267
+ uri = options[:openstack_auth_uri]
263
268
  project_name = options[:openstack_project_name]
264
269
  service_type = options[:openstack_service_type]
265
270
  service_name = options[:openstack_service_name]
@@ -302,6 +307,26 @@ module Fog
302
307
  service = get_service_v3(body, service_type, service_name, openstack_region, options)
303
308
  end
304
309
 
310
+ # If no identity endpoint is found, try the auth uri (slicing /auth/tokens)
311
+ # It covers the case where identityv3 endpoint is not present in the catalog but we have to use it
312
+ unless service
313
+ if service_type.include? "identity"
314
+ identity_uri = uri.to_s.sub('/auth/tokens', '')
315
+ response = Fog::Core::Connection.new(identity_uri, false, connection_options).request({:method => 'GET'})
316
+ if response.status == 200
317
+ service = {
318
+ "endpoints" => [{
319
+ "url" => identity_uri,
320
+ "region" => openstack_region,
321
+ "interface" => endpoint_type
322
+ }],
323
+ "type" => service_type,
324
+ "name" => service_name
325
+ }
326
+ end
327
+ end
328
+ end
329
+
305
330
  unless service
306
331
  available_services = body['token']['catalog'].map { |service|
307
332
  service['type']
@@ -537,65 +562,27 @@ module Fog
537
562
  end
538
563
 
539
564
  def self.get_supported_version(supported_versions, uri, auth_token, connection_options = {})
540
- connection = Fog::Core::Connection.new("#{uri.scheme}://#{uri.host}:#{uri.port}", false, connection_options)
541
- response = connection.request({
542
- :expects => [200, 204, 300],
543
- :headers => {'Content-Type' => 'application/json',
544
- 'Accept' => 'application/json',
545
- 'X-Auth-Token' => auth_token},
546
- :method => 'GET'
547
- })
548
-
549
- body = Fog::JSON.decode(response.body)
550
- version = nil
551
- unless body['versions'].empty?
552
- versions = body['versions'].kind_of?(Array) ? body['versions'] : body['versions']['values']
553
- supported_version = versions.find do |x|
554
- x["id"].match(supported_versions) &&
555
- (x["status"] == "CURRENT" || x["status"] == "SUPPORTED" || x["status"] == "stable")
556
- end
557
- version = supported_version["id"] if supported_version
558
- end
559
- if version.nil?
560
- raise Fog::OpenStack::Errors::ServiceUnavailable.new(
561
- "OpenStack service only supports API versions #{supported_versions.inspect}")
562
- end
565
+ supported_version = get_version(supported_versions, uri, auth_token, connection_options)
566
+ version = supported_version['id'] if supported_version
567
+ version_raise(supported_versions) if version.nil?
563
568
 
564
569
  version
565
570
  end
566
571
 
567
572
  def self.get_supported_version_path(supported_versions, uri, auth_token, connection_options = {})
568
- # Find a version in the path (e.g. the v1 in /xyz/v1/tenantid/abc) and get the path up until that version (e.g. /xyz))
569
- path_components = uri.path.split '/'
570
- version_component_index = path_components.index{|comp| comp.match(/v[0-9].?[0-9]?/) }
571
- versionless_path = (path_components.take(version_component_index).join '/' if version_component_index) || uri.path
572
- connection = Fog::Core::Connection.new("#{uri.scheme}://#{uri.host}:#{uri.port}#{versionless_path}", false, connection_options)
573
- response = connection.request({
574
- :expects => [200, 204, 300],
575
- :headers => {'Content-Type' => 'application/json',
576
- 'Accept' => 'application/json',
577
- 'X-Auth-Token' => auth_token},
578
- :method => 'GET'
579
- })
580
-
581
- body = Fog::JSON.decode(response.body)
582
- path = nil
583
- unless body['versions'].empty?
584
- versions = body['versions'].kind_of?(Array) ? body['versions'] : body['versions']['values']
585
- supported_version = versions.find do |x|
586
- x["id"].match(supported_versions) &&
587
- (x["status"] == "CURRENT" || x["status"] == "SUPPORTED")
588
- end
589
- path = URI.parse(supported_version['links'].first['href']).path if supported_version
590
- end
591
- if path.nil?
592
- raise Fog::OpenStack::Errors::ServiceUnavailable.new(
593
- "OpenStack service only supports API versions #{supported_versions.inspect}")
594
- end
573
+ supported_version = get_version(supported_versions, uri, auth_token, connection_options)
574
+ link = supported_version['links'].find { |l| l['rel'] == 'self' } if supported_version
575
+ path = URI.parse(link['href']).path if link
576
+ version_raise(supported_versions) if path.nil?
595
577
 
596
578
  path.chomp '/'
597
579
  end
598
580
 
581
+ def self.get_supported_microversion(supported_versions, uri, auth_token, connection_options = {})
582
+ supported_version = get_version(supported_versions, uri, auth_token, connection_options)
583
+ supported_version['version'] if supported_version
584
+ end
585
+
599
586
  # CGI.escape, but without special treatment on spaces
600
587
  def self.escape(str, extra_exclude_chars = '')
601
588
  str.gsub(/([^a-zA-Z0-9_.-#{extra_exclude_chars}]+)/) do
@@ -614,6 +601,41 @@ module Fog
614
601
  end
615
602
 
616
603
  end
617
- end
618
604
 
605
+ def self.get_version(supported_versions, uri, auth_token, connection_options = {})
606
+ version_cache = "#{uri}#{supported_versions}"
607
+ return @version[version_cache] if @version && @version[version_cache]
608
+ connection = Fog::Core::Connection.new("#{uri.scheme}://#{uri.host}:#{uri.port}", false, connection_options)
609
+ response = connection.request(
610
+ :expects => [200, 204, 300],
611
+ :headers => {'Content-Type' => 'application/json',
612
+ 'Accept' => 'application/json',
613
+ 'X-Auth-Token' => auth_token},
614
+ :method => 'GET'
615
+ )
616
+
617
+ body = Fog::JSON.decode(response.body)
618
+
619
+ @version = {} unless @version
620
+ @version[version_cache] = extract_version_from_body(body, supported_versions)
621
+ end
622
+
623
+ def self.extract_version_from_body(body, supported_versions)
624
+ return nil if body['versions'].empty?
625
+ versions = body['versions'].kind_of?(Array) ? body['versions'] : body['versions']['values']
626
+ version = nil
627
+ # order is important, preffered status should be first
628
+ %w(CURRENT stable SUPPORTED DEPRECATED).each do |status|
629
+ version = versions.find { |x| x['id'].match(supported_versions) && (x['status'] == status) }
630
+ break if version
631
+ end
632
+
633
+ version
634
+ end
635
+
636
+ def self.version_raise(supported_versions)
637
+ raise Fog::OpenStack::Errors::ServiceUnavailable,
638
+ "OpenStack service only supports API versions #{supported_versions.inspect}"
639
+ end
640
+ end
619
641
  end
@@ -50,9 +50,9 @@ module Fog
50
50
  @openstack_can_reauthenticate = true
51
51
  end
52
52
 
53
- @current_user = options[:current_user]
53
+ @current_user = options[:current_user]
54
54
  @current_user_id = options[:current_user_id]
55
- @current_tenant = options[:current_tenant]
55
+ @current_tenant = options[:current_tenant]
56
56
  end
57
57
 
58
58
  def credentials
@@ -79,11 +79,7 @@ module Fog
79
79
  retried = false
80
80
  begin
81
81
  response = @connection.request(params.merge(
82
- :headers => {
83
- 'Content-Type' => 'application/json',
84
- 'Accept' => 'application/json',
85
- 'X-Auth-Token' => @auth_token
86
- }.merge!(params[:headers] || {}),
82
+ :headers => headers(params.delete(:headers)),
87
83
  :path => "#{@path}/#{params[:path]}"
88
84
  ))
89
85
  rescue Excon::Errors::Unauthorized => error
@@ -119,6 +115,53 @@ module Fog
119
115
  # if the service supports multiple versions, do the selection here
120
116
  end
121
117
 
118
+ def set_microversion
119
+ @microversion_key ||= 'Openstack-API-Version'.freeze
120
+ @microversion_service_type ||= @openstack_service_type.first
121
+
122
+ @microversion = Fog::OpenStack.get_supported_microversion(
123
+ @supported_versions,
124
+ @openstack_management_uri,
125
+ @auth_token,
126
+ @connection_options
127
+ ).to_s
128
+
129
+ # choose minimum out of reported and supported version
130
+ if microversion_newer_than?(@supported_microversion)
131
+ @microversion = @supported_microversion
132
+ end
133
+
134
+ # choose minimum out of set and wished version
135
+ if @fixed_microversion && microversion_newer_than?(@fixed_microversion)
136
+ @microversion = @fixed_microversion
137
+ elsif @fixed_microversion && @microversion != @fixed_microversion
138
+ Fog::Logger.warning("Microversion #{@fixed_microversion} not supported")
139
+ end
140
+ end
141
+
142
+ def microversion_newer_than?(version)
143
+ Gem::Version.new(version) < Gem::Version.new(@microversion)
144
+ end
145
+
146
+ def headers(additional_headers)
147
+ additional_headers ||= {}
148
+ if @microversion
149
+ microversion_value = if @microversion_key == 'Openstack-API-Version'
150
+ "#{@microversion_service_type} #{@microversion}"
151
+ else
152
+ @microversion
153
+ end
154
+ microversion_header = {@microversion_key => microversion_value}
155
+ additional_headers.merge!(microversion_header)
156
+ end
157
+
158
+ {
159
+ 'Content-Type' => 'application/json',
160
+ 'Accept' => 'application/json',
161
+ 'X-Auth-Token' => @auth_token
162
+ }.merge!(additional_headers)
163
+ end
164
+
122
165
  def openstack_options
123
166
  options = {}
124
167
  # Create a hash of (:openstack_*, value) of all the @openstack_* instance variables
@@ -165,6 +208,9 @@ module Fog
165
208
  )
166
209
  end
167
210
 
211
+ # both need to be set in service's initialize for microversions to work
212
+ set_microversion if @supported_microversion && @supported_versions
213
+
168
214
  true
169
215
  end
170
216
  end