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 +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
|
[![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
|
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
|