dd_spacecadet 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +14 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +247 -0
- data/LICENSE +169 -0
- data/README.md +49 -0
- data/Rakefile +31 -0
- data/dd_spacecadet.gemspec +40 -0
- data/lib/dd_spacecadet.rb +27 -0
- data/lib/dd_spacecadet/config.rb +57 -0
- data/lib/dd_spacecadet/error.rb +24 -0
- data/lib/dd_spacecadet/lb.rb +194 -0
- data/lib/dd_spacecadet/node_ip.rb +104 -0
- data/lib/dd_spacecadet/util.rb +43 -0
- data/lib/dd_spacecadet/version.rb +19 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/dd_spacecadet/config_spec.rb +75 -0
- data/spec/unit/dd_spacecadet/lb_spec.rb +390 -0
- data/spec/unit/dd_spacecadet/node_ip_spec.rb +77 -0
- data/spec/unit/dd_spacecadet/util_spec.rb +66 -0
- metadata +138 -0
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# SpaceCadet
|
2
|
+
SpaceCadet is a library written in Ruby for interacting with the Rackspace Cloud Load Balancers.
|
3
|
+
The library itself uses the `fog` gem, which is a very popular Ruby library for interacting with
|
4
|
+
all of the different cloud providers (including Rackspace).
|
5
|
+
|
6
|
+
## License
|
7
|
+
SpaceCadet is released under the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) license. See the [LICENSE](https://github.com/doubledutch/spacecadet/blob/master/LICENSE) file for full the full details of the license.
|
8
|
+
|
9
|
+
## Why SpaceCadet?
|
10
|
+
Because this library is meant to speed up deploys, and it's a little "special"...
|
11
|
+
|
12
|
+
It's not meant to be pretty, clean, or re-usable. This library was written with one purpose in mind:
|
13
|
+
being able to change a single backend node from `ENABLED` to `DRAINING` within multiple LBs.
|
14
|
+
|
15
|
+
Also: `(Rack)space`.
|
16
|
+
|
17
|
+
## Including in Gemfile
|
18
|
+
|
19
|
+
```Ruby
|
20
|
+
gem 'dd_spacecadet', git: 'git@ddgit.me:EngOps/spacecadet.git'
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
Here's an example of using the library while interacting with the `DFW` region:
|
25
|
+
|
26
|
+
```Ruby
|
27
|
+
require 'dd_spacecadet'
|
28
|
+
|
29
|
+
env = 'dfw-prod'
|
30
|
+
region = 'DFW'
|
31
|
+
|
32
|
+
DoubleDutch::SpaceCadet::Config.register(
|
33
|
+
env, ENV['RS_CLOUD_USERNAME'], ENV['RS_CLOUD_KEY'], region
|
34
|
+
)
|
35
|
+
|
36
|
+
dfw_prod = DoubleDutch::SpaceCadet::LB.new(env)
|
37
|
+
|
38
|
+
# search for an LB by its label, in this example "prod-lb"
|
39
|
+
# if multiple LBs match it will use *ALL* of them
|
40
|
+
dfw_prod.find_lb_and_use('prod-lb')
|
41
|
+
|
42
|
+
# gets the status of each LB and its nodes
|
43
|
+
# you can use dfw.print_status to print the info to stdout with formatting
|
44
|
+
dfw.status
|
45
|
+
|
46
|
+
dfw.update_node('node01', :draining)
|
47
|
+
|
48
|
+
dfw.update_node('node01', :enabled)
|
49
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'rubocop/rake_task'
|
16
|
+
require 'rspec/core/rake_task'
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
RSpec::Core::RakeTask.new(:spec)
|
20
|
+
|
21
|
+
desc 'Run RuboCop'
|
22
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
23
|
+
t.options = %w(-D)
|
24
|
+
t.fail_on_error = true
|
25
|
+
t.patterns = %w(
|
26
|
+
Rakefile Gemfile *.gemspec
|
27
|
+
lib/**/*.rb spec/**/*.rb
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
task default: [:rubocop, :spec]
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
|
16
|
+
|
17
|
+
require 'dd_spacecadet/version'
|
18
|
+
|
19
|
+
Gem::Specification.new do |s|
|
20
|
+
s.name = 'dd_spacecadet'
|
21
|
+
s.summary = 'Library for manipulating Rackspace Cloud Load Balancers'
|
22
|
+
s.author = 'DoubleDutch Engineering Operations'
|
23
|
+
s.email = 'engops@doubledutch.me'
|
24
|
+
s.license = 'Apache 2.0'
|
25
|
+
s.version = DoubleDutch::SpaceCadet::VERSION
|
26
|
+
s.required_ruby_version = '~> 2.3'
|
27
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
28
|
+
s.homepage = 'https://github.com/DoubleDutch/spacecadet'
|
29
|
+
s.description = 'Rubygem for safely managing Rackspace Cloud Load Balancer backend servers'
|
30
|
+
|
31
|
+
s.test_files = `git ls-files spec/*`.split
|
32
|
+
s.files = `git ls-files`.split
|
33
|
+
|
34
|
+
s.add_development_dependency 'rake', '~> 11.2.2'
|
35
|
+
s.add_development_dependency 'rspec', '~> 3.5.0'
|
36
|
+
s.add_development_dependency 'rubocop', '~> 0.42.0'
|
37
|
+
s.add_development_dependency 'irbtools', '~> 2.0.1'
|
38
|
+
|
39
|
+
s.add_runtime_dependency 'fog', '~> 1.38.0'
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'dd_spacecadet/version'
|
16
|
+
require 'dd_spacecadet/util'
|
17
|
+
require 'dd_spacecadet/error'
|
18
|
+
require 'dd_spacecadet/config'
|
19
|
+
require 'dd_spacecadet/node_ip'
|
20
|
+
require 'dd_spacecadet/lb'
|
21
|
+
|
22
|
+
# DoubleDutch is the top-level module for
|
23
|
+
# internal DoubleDutch modules and classes
|
24
|
+
module DoubleDutch
|
25
|
+
# SpaceCadet is a module for configuring the Rackspace Cloud Load Balancers
|
26
|
+
module SpaceCadet; end
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'fog'
|
16
|
+
|
17
|
+
module DoubleDutch
|
18
|
+
module SpaceCadet
|
19
|
+
# Class Config is used to configure a client for a specific Rackspace account
|
20
|
+
# You provide the `env`, usually for format is <geo>-<env> (e.g., dfw-prod)
|
21
|
+
class Config
|
22
|
+
@@servers_client = {}
|
23
|
+
@@lbs_client = {}
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def register(env, username, key, region)
|
27
|
+
# init servers_client if it is nil
|
28
|
+
@@servers_client[env] ||= Fog::Compute.new(
|
29
|
+
provider: 'rackspace',
|
30
|
+
rackspace_username: username,
|
31
|
+
rackspace_api_key: key,
|
32
|
+
rackspace_region: region
|
33
|
+
)
|
34
|
+
|
35
|
+
# init lbs_client if it is nil
|
36
|
+
@@lbs_client[env] ||= Fog::Rackspace::LoadBalancers.new(
|
37
|
+
rackspace_username: username,
|
38
|
+
rackspace_api_key: key,
|
39
|
+
rackspace_region: region
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
# DoubleDutch::SpaceCadet::Config.servers.client
|
44
|
+
# returns @@servers_client
|
45
|
+
def servers_client
|
46
|
+
@@servers_client
|
47
|
+
end
|
48
|
+
|
49
|
+
# DoubleDutch::SpaceCadet::Config.lbs.client
|
50
|
+
# returns @@lbs_client
|
51
|
+
def lbs_client
|
52
|
+
@@lbs_client
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module DoubleDutch
|
16
|
+
module SpaceCadet
|
17
|
+
class Error < StandardError; end
|
18
|
+
class ServerNotFound < DoubleDutch::SpaceCadet::Error; end
|
19
|
+
class LBNotFound < DoubleDutch::SpaceCadet::Error; end
|
20
|
+
class LBInconsistentState < DoubleDutch::SpaceCadet::Error; end
|
21
|
+
class LBUnsafe < DoubleDutch::SpaceCadet::Error; end
|
22
|
+
class MalformedNodeObject < DoubleDutch::SpaceCadet::Error; end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'dd_spacecadet/error'
|
16
|
+
require 'dd_spacecadet/util'
|
17
|
+
|
18
|
+
module DoubleDutch
|
19
|
+
module SpaceCadet
|
20
|
+
# LB is the class used for manging the Load Balancer configs
|
21
|
+
class LB
|
22
|
+
attr_reader :env, :lbs
|
23
|
+
|
24
|
+
def initialize(env)
|
25
|
+
@env = env
|
26
|
+
@lbs = []
|
27
|
+
end
|
28
|
+
|
29
|
+
# reset the class (clear the added LBs)
|
30
|
+
def reset
|
31
|
+
@lbs.clear
|
32
|
+
end
|
33
|
+
|
34
|
+
# add an LB, by ID, to be managed by this class
|
35
|
+
def add_lb(lb_id)
|
36
|
+
@lbs = (@lbs << lb_id).uniq
|
37
|
+
end
|
38
|
+
|
39
|
+
# find an LB using a search string
|
40
|
+
def find_lb(search)
|
41
|
+
DoubleDutch::SpaceCadet::Util.find_lb(@env, search)
|
42
|
+
end
|
43
|
+
|
44
|
+
# the same as find_lb, but it adds each to the classs
|
45
|
+
def find_lb_and_use(search)
|
46
|
+
find_lb(search).each { |lb| add_lb(lb[:id]) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# gets the status of managed LBs
|
50
|
+
def status
|
51
|
+
details = @lbs.map { |lb_id| get_lb_details(lb_id) }
|
52
|
+
|
53
|
+
parse_lb_details(details)
|
54
|
+
end
|
55
|
+
|
56
|
+
# updates the condition of a node with the Load Balancer
|
57
|
+
# this is used to move from :enabled => :draining
|
58
|
+
def update_node(name, condition)
|
59
|
+
# check whether the condition is valid
|
60
|
+
unless [:enabled, :draining].include?(condition)
|
61
|
+
raise ArgumentError, 'Invalid condition (can be :enabled or :draining)'
|
62
|
+
end
|
63
|
+
|
64
|
+
lb_details = status
|
65
|
+
|
66
|
+
raise LoadBalancerNotFound, 'No LB details found!' if lb_details.empty?
|
67
|
+
|
68
|
+
to_update = calculate_update(name.downcase, lb_details, condition)
|
69
|
+
|
70
|
+
if to_update.size != lb_details.size
|
71
|
+
raise LBInconsistentState, "We only found #{to_update.size} nodes across #{lb_details.size} LBs"
|
72
|
+
end
|
73
|
+
|
74
|
+
flush_updates(to_update)
|
75
|
+
end
|
76
|
+
|
77
|
+
# this does the same thing as status
|
78
|
+
# put it prints it the information to stdout
|
79
|
+
def render_status
|
80
|
+
status.each do |st|
|
81
|
+
puts "#{st[:name]} (#{st[:id]})"
|
82
|
+
st[:nodes].each { |n| puts " #{n[:name]} #{n[:condition]} #{n[:id]} #{n[:ip]}" }
|
83
|
+
puts '---'
|
84
|
+
end
|
85
|
+
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def lbs_client
|
92
|
+
DoubleDutch::SpaceCadet::Config.lbs_client[@env]
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_lb_details(lb_id)
|
96
|
+
lbs_client.get_load_balancer(lb_id).data[:body]
|
97
|
+
end
|
98
|
+
|
99
|
+
def flush_updates(to_update)
|
100
|
+
to_update.each do |update|
|
101
|
+
flush_update(update)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# safety check before taking actions
|
106
|
+
# this makes sure we cannot set more than one node to draining
|
107
|
+
def safe?(lbd, condition)
|
108
|
+
# if it's a draining operation
|
109
|
+
# check for safety
|
110
|
+
if condition == :draining
|
111
|
+
# this inverts the result of the boolean statement
|
112
|
+
# if these conditions are met, we are *NOT* safe
|
113
|
+
# if there is onle one mode enabled: NOT SAFE
|
114
|
+
# if any node is disabled/draining: NOT SAFE
|
115
|
+
return !(lbd[:nodes_enabled] == 1 || lbd[:nodes_enabled] != lbd[:nodes].size)
|
116
|
+
end
|
117
|
+
|
118
|
+
# otherwise, it's safe
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
# calculate which node IDs need to be updated
|
123
|
+
def calculate_update(name, details, condition)
|
124
|
+
to_update = []
|
125
|
+
|
126
|
+
# loop over the individual load balancers
|
127
|
+
details.each do |lbd|
|
128
|
+
# make sure this LB is in a safe state to mutate
|
129
|
+
unless safe?(lbd, condition)
|
130
|
+
raise LBUnsafe, "#{lbd[:name]} LB unsafe for draining"
|
131
|
+
end
|
132
|
+
|
133
|
+
# loop over the registered nodes to find the ID
|
134
|
+
# of the one we want to update the condition of
|
135
|
+
lbd[:nodes].each do |lbn|
|
136
|
+
to_update << { lb_id: lbd[:id], node_id: lbn[:id], condition: condition } if lbn[:name] == name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
to_update
|
141
|
+
end
|
142
|
+
|
143
|
+
def flush_update(update)
|
144
|
+
call_update(update)
|
145
|
+
# immediately after updating an LB config, Rackspace marks the LB
|
146
|
+
# as being immutable (meaning no further config changes can happen)
|
147
|
+
# this exception below is what is thrown by Fog if we hit that situation
|
148
|
+
rescue Fog::Rackspace::LoadBalancers::ServiceError
|
149
|
+
# the LB is currently marked as being immutable
|
150
|
+
# wait N arbitrary seconds before trying again
|
151
|
+
sleep(5)
|
152
|
+
call_update(update)
|
153
|
+
end
|
154
|
+
|
155
|
+
def call_update(update)
|
156
|
+
lbs_client.update_node(
|
157
|
+
update[:lb_id],
|
158
|
+
update[:node_id],
|
159
|
+
condition: update[:condition].to_s.upcase
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
def parse_lb_details(details)
|
164
|
+
details.map do |lb|
|
165
|
+
detail = {
|
166
|
+
name: lb['loadBalancer']['name'].downcase,
|
167
|
+
id: lb['loadBalancer']['id']
|
168
|
+
}
|
169
|
+
|
170
|
+
detail[:nodes], detail[:nodes_enabled] = parse_nodes(lb['loadBalancer']['nodes'])
|
171
|
+
|
172
|
+
detail
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def parse_nodes(nodes)
|
177
|
+
enabled_count = 0
|
178
|
+
|
179
|
+
n = nodes.map do |node|
|
180
|
+
enabled_count += 1 if node['condition'].casecmp('enabled').zero?
|
181
|
+
|
182
|
+
{
|
183
|
+
name: DoubleDutch::SpaceCadet::NodeIP.get_name_for(@env, node['address']),
|
184
|
+
ip: node['address'],
|
185
|
+
id: node['id'],
|
186
|
+
condition: node['condition']
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
[n.sort { |x, y| x[:name] <=> y[:name] }, enabled_count]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# Copyright 2016 DoubleDutch, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'dd_spacecadet/error'
|
16
|
+
require 'dd_spacecadet/config'
|
17
|
+
|
18
|
+
module DoubleDutch
|
19
|
+
module SpaceCadet
|
20
|
+
# NodeIP is a class of helper methods to find a node
|
21
|
+
# based on its name or IP address
|
22
|
+
class NodeIP
|
23
|
+
# internal data structures
|
24
|
+
@@nodes_by_name = {}
|
25
|
+
@@nodes_by_ip = {}
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# get the IP address for a node
|
29
|
+
# based on its label (name)
|
30
|
+
def get_ip_for(env, name)
|
31
|
+
refresh_nodes(env)
|
32
|
+
|
33
|
+
ip = @@nodes_by_name.dig(env, name)
|
34
|
+
|
35
|
+
raise ServerNotFound, "unable to locate #{name} in #{env} data" if ip.nil?
|
36
|
+
|
37
|
+
ip
|
38
|
+
end
|
39
|
+
|
40
|
+
# get the label (name) for a node
|
41
|
+
# based on its IP address
|
42
|
+
def get_name_for(env, ip)
|
43
|
+
refresh_nodes(env)
|
44
|
+
|
45
|
+
name = @@nodes_by_ip.dig(env, ip)
|
46
|
+
|
47
|
+
raise ServerNotFound, "unable to locate #{ip} in #{env} data" if name.nil?
|
48
|
+
|
49
|
+
name
|
50
|
+
end
|
51
|
+
|
52
|
+
# clear flushes all cached data
|
53
|
+
def clear(env)
|
54
|
+
@@nodes_by_name.delete(env)
|
55
|
+
@@nodes_by_ip.delete(env)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# if any of the internal structures are nil or empty
|
61
|
+
# we should probably try to do an update
|
62
|
+
def needs_refresh?(env)
|
63
|
+
(@@nodes_by_name[env].nil? || @@nodes_by_name[env].empty?) ||
|
64
|
+
(@@nodes_by_ip[env].nil? || @@nodes_by_ip[env].empty?)
|
65
|
+
end
|
66
|
+
|
67
|
+
# this gets the details of the nodes we care about:
|
68
|
+
# name and IP
|
69
|
+
def get_details(server)
|
70
|
+
priv_addresses = server.dig('addresses', 'private')
|
71
|
+
|
72
|
+
raise MailformedNodeObject, 'Node missing private addresses' if priv_addresses.nil? || priv_addresses.empty?
|
73
|
+
|
74
|
+
[server['name'].downcase, priv_addresses[0]['addr']]
|
75
|
+
end
|
76
|
+
|
77
|
+
# refresh the information we have by pulling down a listing of all
|
78
|
+
# nodes from Rackspace
|
79
|
+
def refresh_nodes(env)
|
80
|
+
# only refresh if a refresh is needed
|
81
|
+
if needs_refresh?(env)
|
82
|
+
# get an Array of all of the servers
|
83
|
+
servers = DoubleDutch::SpaceCadet::Config.servers_client[env].list_servers.data[:body]['servers']
|
84
|
+
|
85
|
+
# hbn: HashByName
|
86
|
+
# hbi: HashByIp
|
87
|
+
hbn = {}
|
88
|
+
hbi = {}
|
89
|
+
|
90
|
+
servers.each do |server|
|
91
|
+
name, ip = get_details(server)
|
92
|
+
|
93
|
+
hbn[name] = ip
|
94
|
+
hbi[ip] = name
|
95
|
+
end
|
96
|
+
|
97
|
+
@@nodes_by_name[env] = hbn
|
98
|
+
@@nodes_by_ip[env] = hbi
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|