openstack-router 0.1.3 → 0.2.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
  SHA256:
3
- metadata.gz: c0f75a1372ca48807478db771b5cef9e87dcf6692b1d996b83b79a46e1e5e094
4
- data.tar.gz: 45c8b6994b400d5f00e812faa71100680dbabb0810284492f84fc77ea0a2d1cf
3
+ metadata.gz: 19e3a08c2546009535178e3a75d05256ebebaca1b143a58b6d8b6d20a01189b4
4
+ data.tar.gz: 56796bc95ea48cc1545dbfc451ddbffb8decddbe01553c50d2454d67916bdbd0
5
5
  SHA512:
6
- metadata.gz: 8bf430ddb4daced99473fea95d448f9da4877810e3ac26d53a88bd6a30d873d1c8aee9220032831c3a1f1a02203b653973a150bb6e1d9a079a703830691901f9
7
- data.tar.gz: a9e6948efba2df9bc0106c16cb50d1d2d3f7a4d56d2acb85fd1960fefbb27bb87e76fb6023cb04b6f19c4042e4770bbae6483b0ffc0f67c7b93801fafeedbacd
6
+ metadata.gz: 465a9722170a66d4c9da527b76f588ecf85f31ab580636ef0ea18e718ea879cb2219aafaf191b3e27cefead826ee5399b80e2d0290425dc23c81512d6e5fdc27
7
+ data.tar.gz: '0296b148ca61f0954c108f7834b6a4eb5c6b6ce3cbe57640851de9f44e6f07389f8ac0f111ed60130336fcbfe7677bb919d91d4f2c95f0a1f421c6835be917c3'
data/README.md CHANGED
@@ -18,6 +18,13 @@ created in a roundrobin way, but you don't want instances roundrobin mix with
18
18
  volume ones for example, or maybe you need to create several kinds of instances
19
19
  with different roundrobin circuits (allowing small servers or big servers to be
20
20
  better splattered).
21
+ We can automatically detect the available regions (by using endpoints sorting).
22
+
23
+ ## What we currently don't have
24
+
25
+ We cannot manage 'admin' or 'internal' interfaces. We only work over 'public'.
26
+ We certainly don't support multiple project users... This will probably fail on
27
+ the catalog detection and stuffs.
21
28
 
22
29
  ## v1 goal
23
30
 
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module OpenStackRouter
6
+ # The class responsible to detect the allowed endpoints (= regions) for
7
+ # connection parameters.
8
+ #
9
+ # @since v0.2.0
10
+ # @author Roland Laurès
11
+ # @attr_reader [Parameter::Connection] connection_parameters
12
+ # The connection parameters.
13
+ #
14
+ # @todo finish description of the next attribute.
15
+ # @attr_reader [Array<String>] endpoints The regions object used to
16
+ # manage the by region stuffs.
17
+ class Catalog
18
+ attr_reader :connection_parameters
19
+ attr_reader :endpoints
20
+
21
+ def initialize(connection_parameters)
22
+ unless connection_parameters.class == Parameter::Connection
23
+ raise ArgumentError, 'Invalid connection parameters. Please use OpenStackRouter::Parameter::Connection'
24
+ end
25
+
26
+ @connection_parameters = connection_parameters
27
+ @token = Fog::OpenStack::Auth::Token.build(@connection_parameters.to_os_h, {})
28
+ @endpoints = {}
29
+ build_endpoints_hierarchy
30
+ end
31
+
32
+ def catalog
33
+ token.catalog.payload.dup
34
+ end
35
+
36
+ def region_ids(interface = 'public')
37
+ return [] unless @endpoints.key?(interface)
38
+
39
+ @endpoints[interface].keys
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :connection
45
+ attr_reader :token
46
+
47
+ # I want to be able to explore from ('interface') / region_id / service
48
+ # TODO: It should manage users that can manipulate several project...
49
+ # I have no instance of OpenStack to create such users. So maybe if someone can.
50
+ def build_endpoints_hierarchy
51
+ catalog.each do |service|
52
+ service_type = service['type']
53
+ service['endpoints'].each do |service_endpoint|
54
+ append_endpoint(service_endpoint, service_type)
55
+ end
56
+ end
57
+ end
58
+
59
+ def append_endpoint(service_endpoint, service_type)
60
+ interface = service_endpoint['interface']
61
+ region_id = service_endpoint['region_id']
62
+ endpoint_path(interface, region_id, service_type).append(service_endpoint)
63
+ end
64
+
65
+ # create or get and return corresponding endpoint path
66
+ def endpoint_path(interface, region_id, service_type)
67
+ ep_interface = @endpoints[interface]
68
+ if ep_interface.nil?
69
+ @endpoints[interface] = ep_interface = { region_id => { service_type => [] } }
70
+ elsif !@endpoints[interface].key?(region_id)
71
+ ep_interface[region_id] = { service_type => [] }
72
+ elsif !@endpoints[interface][region_id].key?(service_type)
73
+ ep_interface[region_id][service_type] = []
74
+ end
75
+ ep_interface[region_id][service_type]
76
+ end
77
+ end
78
+ end
@@ -8,28 +8,30 @@ module OpenStackRouter
8
8
  #
9
9
  # @author Roland Laurès
10
10
  # @attr_reader [String] auth_url The OpenStack url of the auth system
11
- # @attr_reader [String] username The username to use to connect to OpenStack
12
- # @attr_reader [String] api_key The api key that you have been given to connect
11
+ # @attr_reader [String | NilClass] username The username to use to connect to OpenStack
12
+ # @note You can have username or userid set as you prefere, but need at least one of them set.
13
+ # @attr_reader [String | NilClass] userid The user_id that you have been given to connect
13
14
  # to the OpenStack services
14
- # @attr_reader [String] tenant The tenant that you have been given to connect
15
+ # @note You can have username or userid set as you prefere, but need at least one of them set.
16
+ # @attr_reader [String] api_key The api key that you have been given to connect
15
17
  # to the OpenStack services
16
- # @attr_reader [String] project_id The Project ID that you want to limit your
17
- # actions on the OpenStack services
18
18
  # @attr_reader [String | NilClass] region The region on which to connect.
19
+ # @attr_reader [String | NilClass] project_id The Project ID that you want to limit your
20
+ # actions on the OpenStack services
19
21
  class Connection
20
22
  attr_reader :auth_url
21
- attr_reader :username
22
23
  attr_reader :api_key
23
- attr_reader :tenant
24
- attr_reader :tenant_id
24
+ attr_reader :username
25
+ attr_reader :userid
25
26
  attr_reader :region
27
+ attr_reader :project_id
26
28
 
27
29
  # The mandatory options needed to be pass in argument at initialization of that class.
28
- MANDATORY_OPTIONS = %i[auth_url username api_key].freeze
30
+ MANDATORY_OPTIONS = %i[auth_url api_key].freeze
29
31
  # Paired mandatory options (means that one of one pair must me present, not the other).
30
- PAIRED_MANDATORY_OPTIONS = [%i[tenant tenant_id]].freeze
32
+ PAIRED_MANDATORY_OPTIONS = [%i[username userid]].freeze
31
33
  # The options that are not mandatory for this object.
32
- OTHER_OPTIONS = %i[region].freeze
34
+ OTHER_OPTIONS = %i[region project_id].freeze
33
35
  # Constant containing all the available options.
34
36
  ALL_OPTIONS = (MANDATORY_OPTIONS + PAIRED_MANDATORY_OPTIONS.flatten + OTHER_OPTIONS).freeze
35
37
 
@@ -41,7 +43,7 @@ module OpenStackRouter
41
43
 
42
44
  # get the corresponding connection parameter hash with openstack_ prefix.
43
45
  def to_os_h
44
- to_h.map { |key, value| ["openstack_#{key}", value] }.to_h
46
+ to_h.map { |key, value| ["openstack_#{key}".to_sym, value] }.reject { |a| a.last.nil? }.to_h
45
47
  end
46
48
 
47
49
  # convert the connection parameters to hash
@@ -68,11 +70,11 @@ module OpenStackRouter
68
70
  private
69
71
 
70
72
  attr_writer :auth_url
71
- attr_writer :username
72
73
  attr_writer :api_key
73
- attr_writer :tenant
74
- attr_writer :tenant_id
74
+ attr_writer :username
75
+ attr_writer :userid
75
76
  attr_writer :region
77
+ attr_writer :project_id
76
78
 
77
79
  def mandatory_options(cfg)
78
80
  missing_keys = []
@@ -7,6 +7,9 @@ module OpenStackRouter
7
7
  # It aims to be the uniq entry point to access all the OpenStack services
8
8
  # and all the regions.
9
9
  #
10
+ # @note For now we are using the default endpoint type only: 'public'. We have
11
+ # to make the router able to managed parametirized endpoint type ('admin' or so).
12
+ #
10
13
  # @author Roland Laurès
11
14
  # @attr_reader [Parameter::Connection] connection_parameters
12
15
  # The connection parameters.
@@ -16,18 +19,19 @@ module OpenStackRouter
16
19
  attr_reader :connection_parameters
17
20
  attr_reader :regions
18
21
 
19
- def initialize(connection_parameters, region_names)
22
+ def initialize(connection_parameters, region_ids = [])
20
23
  unless connection_parameters.class == Parameter::Connection
21
24
  raise ArgumentError, 'Invalid connection parameters. Please use OpenStackRouter::Parameter::Connection'
22
25
  end
23
26
 
24
27
  @connection_parameters = connection_parameters
25
- @regions = region_names.map { |region_name| Region.new(region_name, @connection_parameters) }
26
28
  @rr_circuits = {}
29
+ @catalog = Catalog.new(connection_parameters)
30
+ @regions = setup_regions(region_ids)
27
31
  end
28
32
 
29
33
  # @return [Array<String>] the region names
30
- def region_names
34
+ def region_ids
31
35
  @regions.map(&:name)
32
36
  end
33
37
 
@@ -42,14 +46,14 @@ module OpenStackRouter
42
46
  # as is.
43
47
  # @see https://github.com/fog/fog-openstack For more information on available services and requests name
44
48
  #
45
- # @return [Hash] The result of each region, the key being the region_name and the value of the
49
+ # @return [Hash] The result of each region, the key being the region_id and the value of the
46
50
  # result of Region#request with the given argument.
47
51
  #
48
- # @yield [region_name, answer] Block called for each region that answers
49
- # @yieldparam [String] region_name The name of the region for that answer
52
+ # @yield [region_id, answer] Block called for each region that answers
53
+ # @yieldparam [String] region_id The name of the region for that answer
50
54
  # @yieldparam [Excon::Response] answer The answer to the request.
51
55
  # @yieldreturn ['a] the return of the block is stored in the hash as a value
52
- # to the key that will be the region_name.
56
+ # to the key that will be the region_id.
53
57
  def request_each(service, request, *request_args)
54
58
  # TODO: make the requests to be parallele to no do them sequentialy...
55
59
  Hash[@regions.map do |region|
@@ -97,15 +101,15 @@ module OpenStackRouter
97
101
  # @return ['a] The result of the selected region, the value of the
98
102
  # result of Region#request with the given argument.
99
103
  #
100
- # @yield [region_name, answer] Block called over the result of the request.
101
- # @yieldparam [String] region_name The name of the region that has been elected to run the request
104
+ # @yield [region_id, answer] Block called over the result of the request.
105
+ # @yieldparam [String] region_id The name of the region that has been elected to run the request
102
106
  # @yieldparam [Excon::Response] answer The answer to the request.
103
107
  # @yieldreturn ['a] the result value of the block is returned by the method itself.
104
108
  def rr_request(rr_uuid, service, request, *request_args)
105
109
  raise ArgumentError, 'Invalid UUID given' unless @rr_circuits.key?(rr_uuid)
106
110
 
107
111
  region = rr_next_region(rr_uuid)
108
- region.request(service, request, *region.my_args(request_args, region_names)) do |answer|
112
+ region.request(service, request, *region.my_args(request_args, region_ids)) do |answer|
109
113
  next answer unless block_given?
110
114
 
111
115
  yield(region.name, answer)
@@ -114,6 +118,17 @@ module OpenStackRouter
114
118
 
115
119
  private
116
120
 
121
+ def setup_regions(region_ids)
122
+ if region_ids.empty?
123
+ @catalog.region_ids.map { |region_id| Region.new(region_id, @connection_parameters) }
124
+ else
125
+ region_ids.map do |region_id|
126
+ @catalog.region_ids.include?(region_id) ? Region.new(region_id, @connection_parameters) : nil
127
+ end
128
+ .reject(&:nil?)
129
+ end
130
+ end
131
+
117
132
  def rr_next_region(rr_uuid)
118
133
  last_idx = @rr_circuits[rr_uuid]
119
134
  n_regions = @regions.length
@@ -2,5 +2,5 @@
2
2
 
3
3
  module OpenStackRouter
4
4
  # The version number of this library
5
- VERSION = '0.1.3'
5
+ VERSION = '0.2.0'
6
6
  end
@@ -9,4 +9,5 @@ end
9
9
  require_relative 'openstack-router/version'
10
10
  require_relative 'openstack-router/parameter/connection'
11
11
  require_relative 'openstack-router/region'
12
+ require_relative 'openstack-router/catalog'
12
13
  require_relative 'openstack-router/router'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstack-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roland Laurès
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-15 00:00:00.000000000 Z
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-openstack
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.6.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.6.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: pry
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -144,6 +158,7 @@ extra_rdoc_files: []
144
158
  files:
145
159
  - LICENSE
146
160
  - README.md
161
+ - lib/openstack-router/catalog.rb
147
162
  - lib/openstack-router/parameter/connection.rb
148
163
  - lib/openstack-router/region.rb
149
164
  - lib/openstack-router/router.rb