openstack-router 0.0.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff6163ba07f33adc553faed4b8da3a88ef16e4358deaf076e9b43f1d93712eb7
4
- data.tar.gz: f486bfd58299931d24248d7d46ee294005cffd5115f5188853ff8a2435c3555f
3
+ metadata.gz: c625802ba2090efd3f6e782bc28577d48cccdb75d5562d5730e113e00595ea54
4
+ data.tar.gz: 6799ba121d667839b22bd30153a22752166e7fa7178e02b1ee1ba7ad9b586bd2
5
5
  SHA512:
6
- metadata.gz: bb7eb683c5131e481342f5146c6ee86e91f9ba3fb22110a3b2f26114ec18a793d559df219a25009e6f1e4ccdae8828742335ddf82661ba2f6400150ced194938
7
- data.tar.gz: 84c5203c72ea459d7ae0ceb5475e6444487db240760128ef55e3b1ac65d93d5e3b0ab10d3a9f634e26bb1e34b72efa408b77596025c71ad35cced5b02364d17d
6
+ metadata.gz: 3a579014ffac9edc697d7694fbe7bc85a7f47fd72b6841e1708001800d198b11ff8100d4e91076f043530afb82ed99a3f91f76ecb6a558eb1c28bf01e25817e3
7
+ data.tar.gz: 78ae040b3471a1cc43d1cf77370360c728a7f32004e19452097a4d45c03cdbafca29b1ddd205c03ab89375d4a1999f589045bdfc1f684bd633b90758df201ff8
data/README.md CHANGED
@@ -4,15 +4,20 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/openstack-router.svg)](https://badge.fury.io/rb/openstack-router)
5
5
  [![coverage report](https://gitlab.com/rol_public/openstack-router/badges/master/coverage.svg)](https://gitlab.com/rol_public/openstack-router/commits/master)
6
6
 
7
- This lib is an overlay/router of OpenStack components and region.
7
+ This lib is an overlay/router of OpenStack services and region.
8
+ It's goal will not be to write a wrapper for the requests themself.
8
9
 
9
10
  # Current state and goal
10
11
 
11
- Currently we are not far. So no good explaination for now.
12
-
13
12
  ## Currently (what we have)
14
13
 
15
- TBD
14
+ We can manipulate several regions through a single interface.
15
+ We can launch a request on all regions, or through "circuits" of roundrobin
16
+ operations. This means that you can have several ressources you want to be
17
+ created in a roundrobin way, but you don't want instances roundrobin mix with
18
+ volume ones for example, or maybe you need to create several kinds of instances
19
+ with different roundrobin circuits (allowing small servers or big servers to be
20
+ better splattered).
16
21
 
17
22
  ## v1 goal
18
23
 
@@ -20,6 +25,12 @@ TBD
20
25
  - Allow to interact simply between regions:
21
26
  - create resources where possible (with a round-robin scheme for example)
22
27
  - copy images from a region to all the other ...
28
+ - Create some helpers to get all the images available
29
+ - if possible get a mean to detect all the regions of the cluster.
30
+
31
+ ## Outside the scope of this library
32
+
33
+ - Not a wrapper for the requests them-selfs.
23
34
 
24
35
  # Install and usage
25
36
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenStackRouter
4
+ # Contain all the classes that will treat complexe parameters of other classes.
4
5
  module Parameter
5
6
  # This class is used to parameter the connection to OpenStack instance and services.
6
7
  # Its purpose is to encapsulate the connection parameters.
@@ -45,6 +46,7 @@ module OpenStackRouter
45
46
  ALL_OPTIONS.map { |key| [key, send(key)] }.to_h
46
47
  end
47
48
 
49
+ # convert to string the options (first convert to Hash, then the Hash to String)
48
50
  def to_s
49
51
  to_h.to_s
50
52
  end
@@ -7,90 +7,78 @@ module OpenStackRouter
7
7
  #
8
8
  # @author Roland Laurès
9
9
  # @attr_reader [String] name The region name.
10
- # @attr_reader [Symbol] state The region's state:
11
- # * operating: connected and fully operational
12
- # * limited: connected but some limits has been reached
13
- # * failed: some connection problems occured
14
- # @attr_reader [Hash] connection_parameters The parameters to connect to OpenStack
10
+ # @attr_reader [Symbol] state The region's state. @see {Region::STATES} descriptions
11
+ # @attr_reader [Parameter::Connection] connection_parameters The parameters to connect to OpenStack
15
12
  # services.
16
13
  class Region
14
+ # The possible states of a Region
17
15
  STATES = [
16
+ # connected and fully operational
18
17
  STATE_OPERATING = :operating,
18
+ # connected but some limits has been reached
19
19
  STATE_LIMITED = :limited,
20
+ # some connection problems occured
20
21
  STATE_FAILED = :failed
21
22
  ].freeze
22
23
  attr_reader :state
23
24
  attr_reader :connection_parameters
25
+ attr_reader :name
24
26
 
25
- def initialize(connection_parameters)
26
- unless connection_parameters.class == Parameter::Connection
27
- raise ArgumentError, 'Invalid connection parameters: Please use OpenStackRouter::Parameter::Connection'
28
- end
29
- unless connection_parameters.present? :region
30
- raise ArgumentError, 'Invalid connection parameters: Please specify region name.'
31
- end
27
+ def initialize(name, connection_parameters)
28
+ @name = name
29
+ @connection_parameters = Parameter::Connection.new(connection_parameters.to_h.merge(region: name))
32
30
 
33
- @compute = @image = nil
34
- @connection_parameters = connection_parameters
35
- @state = STATE_FAILED
36
- connect
37
- end
38
-
39
- def name
40
- @connection_parameters.region
41
- end
42
-
43
- # get the limitation in this region for this project
44
- # @see https://developer.openstack.org/api-ref/compute/#show-rate-and-absolute-limits
45
- # The OpenStack API reference for this request.
46
- # @return [Hash] if all goes well
47
- # @return nil on error
48
- def limits
49
- request_wrapper(@compute, :get_limits) do |limits_answer|
50
- break nil if limits_answer.status != 200
51
-
52
- limits_answer.body['limits']
53
- end
31
+ @services = {}
32
+ @state = STATE_OPERATING
54
33
  end
55
34
 
56
- # get the list of images available on that region.
57
- # @see https://developer.openstack.org/api-ref/image/v2/?expanded=list-images-detail#list-images
58
- # The description of images list request.
59
- # You can use the request options with key/value optional argument.
60
- # @param [Hash] opts The options to pass to image#images list request.
35
+ # This method allow to call a request on a service for this region.
36
+ # If the service hasn't been already connected it will be connected.
37
+ #
38
+ # @param [Symbol] service The service to contact (:compute, :image...)
39
+ # @param [symbol] request_name The request to do on that service.
40
+ # It must exist else an exception will be raised.
41
+ # @param [Array] args All other arguments will be passed to the requested
42
+ # method.
61
43
  #
62
- # @return [Array] containing
63
- # @return nil on error
64
- def images(opts = {})
65
- request_wrapper(@image, :list_images, opts) do |list_images_answer|
66
- # 204 is include because the Fog.mock implementation returns 200 | 204 randomly...
67
- break nil unless [200, 204].include?(list_images_answer.status)
44
+ # @return [NilClass | 'a | Excon::Response]
45
+ # * nil if a SocketError occurs and
46
+ # the region cannot be reached.
47
+ # * +'a+ is the type returned by the block you give
48
+ # * Excon::Response is return if no block is given and no error is raised.
49
+ #
50
+ # @yield [answer] Block called with the answer for you to filter.
51
+ #
52
+ # @yieldparam [Excon::Response] answer The answer of the request
53
+ # @yieldreturn ['a] You return what you want. It will be then return without
54
+ # being touched by the method.
55
+ # Since nothing is done after yielding, then you can use the +return+ keyword
56
+ # from the block instead of +break+. But for safety, we recommand using +break+.
57
+ def request(service, request_name, *args, &block)
58
+ service = service.to_s.capitalize
59
+ return nil if @state == STATE_FAILED && setup(service) == STATE_FAILED
68
60
 
69
- list_images_answer.body['images']
70
- end
61
+ do_request(service, request_name, *args, &block)
71
62
  end
72
63
 
73
64
  private
74
65
 
75
- def connect
76
- cp = connection_parameters.to_os_h
77
- @compute = Fog::OpenStack::Compute.new cp
78
- @image = Fog::OpenStack::Image.new cp
66
+ def setup(service)
67
+ @services[service] = Object.const_get(Fog::OpenStack.service_klass(service)).new(@connection_parameters.to_os_h)
79
68
  @state = STATE_OPERATING
69
+ rescue SocketError
70
+ @state = STATE_FAILED if @services.empty?
71
+ STATE_FAILED
80
72
  end
81
73
 
82
- def do_request(ctl, request_name, *args)
83
- answer = ctl.send(request_name, *args)
74
+ def do_request(service, request_name, *args)
75
+ setup(service) unless @services.key?(service)
76
+ answer = @services[service].send(request_name, *args)
84
77
  block_given? ? yield(answer) : answer
85
78
  rescue SocketError
86
- @state = STATE_FAILED
79
+ @services.delete(service)
80
+ @state = STATE_FAILED if @services.empty?
87
81
  nil
88
82
  end
89
-
90
- def request_wrapper(ctl, request_name, *args, &block)
91
- return nil if @state == STATE_FAILED && connect == STATE_FAILED
92
-
93
- do_request(ctl, request_name, *args, &block)
94
- end
95
83
  end
96
84
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'securerandom'
4
+
3
5
  module OpenStackRouter
4
6
  # The main class of the module.
5
7
  # It aims to be the uniq entry point to access all the OpenStack services
@@ -8,19 +10,75 @@ module OpenStackRouter
8
10
  # @author Roland Laurès
9
11
  # @attr_reader [Parameter::Connection] connection_parameters
10
12
  # The connection parameters.
11
- # @attr_reader [Regions] regions The regions object used to
13
+ # @attr_reader [Array<Region>] regions The regions object used to
12
14
  # manage the by region stuffs.
13
15
  class Router
14
16
  attr_reader :connection_parameters
15
17
  attr_reader :regions
16
18
 
17
- def initialize(connection_parameters, regions_name)
19
+ def initialize(connection_parameters, region_names)
18
20
  unless connection_parameters.class == Parameter::Connection
19
21
  raise ArgumentError, 'Invalid connection parameters. Please use OpenStackRouter::Parameter::Connection'
20
22
  end
21
23
 
22
24
  @connection_parameters = connection_parameters
23
- @regions = regions_name
25
+ @regions = region_names.map { |region_name| Region.new(region_name, @connection_parameters) }
26
+ @rr_circuits = {}
27
+ end
28
+
29
+ # This method do a request on a service for each region in the router.
30
+ #
31
+ # @param [String | Symbol] service The service you want to interogate
32
+ # Service name should be capitalized, but by precaution, it is converted to string and capitalized
33
+ # at each request. :compute will be converted to 'Compute'.
34
+ # @param [Symbol] request This is the request you want to launch on the regions' service.
35
+ # This is a method call, and then must be a Symbol.
36
+ # @see https://github.com/fog/fog-openstack For more information on available services and requests name
37
+ #
38
+ # @return [Hash] The result of each region, the key being the region_name and the value the
39
+ # result of Region#request with the given argument.
40
+ # @see Region#request to understand how the block is managed.
41
+ def request_each(service, request, *request_args, &block)
42
+ # TODO: make the requests to be parallele to no do them sequentialy...
43
+ Hash[@regions.map do |region|
44
+ [region.name, region.request(service, request, *request_args, &block)]
45
+ end]
46
+ end
47
+
48
+ # Create an UUID for a round robin circuit.
49
+ # This allow to identify a round robin "group" that you can use for a given request or
50
+ # group of request.
51
+ #
52
+ # @return [String] A randomly generated UUID.
53
+ def rr_create
54
+ key = SecureRandom.uuid
55
+ @rr_circuits[key] = nil
56
+ key
57
+ end
58
+
59
+ # @return [NilClass | Region] the last used region for that round robin circuit.
60
+ # nil is return if the circuit hasn't been used yet.
61
+ def rr_last_region(rr_uuid)
62
+ raise ArgumentError, 'Invalid UUID given' unless @rr_circuits.key?(rr_uuid)
63
+
64
+ @rr_circuits[rr_uuid]
65
+ end
66
+
67
+ def rr_request(rr_uuid, service, request, *request_args, &block)
68
+ raise ArgumentError, 'Invalid UUID given' unless @rr_circuits.key?(rr_uuid)
69
+
70
+ rr_next_region(rr_uuid).request(service, request, *request_args, &block)
71
+ end
72
+
73
+ private
74
+
75
+ def rr_next_region(rr_uuid)
76
+ last_idx = @rr_circuits[rr_uuid]
77
+ n_regions = @regions.length
78
+ @rr_circuits[rr_uuid] = if last_idx.nil? then SecureRandom.rand(n_regions)
79
+ else (@rr_circuits[rr_uuid] + 1).modulo(n_regions)
80
+ end
81
+ @regions[@rr_circuits[rr_uuid]]
24
82
  end
25
83
  end
26
84
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module OpenStackRouter
4
4
  # The version number of this library
5
- VERSION = '0.0.2'
5
+ VERSION = '0.1.0'
6
6
  end
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.0.2
4
+ version: 0.1.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-03 00:00:00.000000000 Z
11
+ date: 2019-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-openstack