openstack-router 0.0.2 → 0.1.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: 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