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 +4 -4
- data/README.md +15 -4
- data/lib/openstack-router/parameter/connection.rb +2 -0
- data/lib/openstack-router/region.rb +47 -59
- data/lib/openstack-router/router.rb +61 -3
- data/lib/openstack-router/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c625802ba2090efd3f6e782bc28577d48cccdb75d5562d5730e113e00595ea54
|
4
|
+
data.tar.gz: 6799ba121d667839b22bd30153a22752166e7fa7178e02b1ee1ba7ad9b586bd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a579014ffac9edc697d7694fbe7bc85a7f47fd72b6841e1708001800d198b11ff8100d4e91076f043530afb82ed99a3f91f76ecb6a558eb1c28bf01e25817e3
|
7
|
+
data.tar.gz: 78ae040b3471a1cc43d1cf77370360c728a7f32004e19452097a4d45c03cdbafca29b1ddd205c03ab89375d4a1999f589045bdfc1f684bd633b90758df201ff8
|
data/README.md
CHANGED
@@ -4,15 +4,20 @@
|
|
4
4
|
[](https://badge.fury.io/rb/openstack-router)
|
5
5
|
[](https://gitlab.com/rol_public/openstack-router/commits/master)
|
6
6
|
|
7
|
-
This lib is an overlay/router of OpenStack
|
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
|
-
|
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
|
-
#
|
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
|
-
|
27
|
-
|
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
|
-
@
|
34
|
-
@
|
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
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# @param [
|
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 [
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
70
|
-
end
|
61
|
+
do_request(service, request_name, *args, &block)
|
71
62
|
end
|
72
63
|
|
73
64
|
private
|
74
65
|
|
75
|
-
def
|
76
|
-
|
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(
|
83
|
-
|
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
|
-
@
|
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 [
|
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,
|
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 =
|
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
|
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
|
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-
|
11
|
+
date: 2019-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fog-openstack
|