capistrano-data_plane_api 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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +5 -0
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +128 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +197 -0
  9. data/Rakefile +16 -0
  10. data/capistrano-data_plane_api.gemspec +41 -0
  11. data/exe/cap_data_plane_api +37 -0
  12. data/lib/capistrano/data_plane_api/configuration/backend.rb +18 -0
  13. data/lib/capistrano/data_plane_api/configuration/server.rb +22 -0
  14. data/lib/capistrano/data_plane_api/configuration/symbol.rb +16 -0
  15. data/lib/capistrano/data_plane_api/configuration.rb +33 -0
  16. data/lib/capistrano/data_plane_api/deploy/args.rb +241 -0
  17. data/lib/capistrano/data_plane_api/deploy/deployment_stats.rb +117 -0
  18. data/lib/capistrano/data_plane_api/deploy/group.rb +100 -0
  19. data/lib/capistrano/data_plane_api/deploy/helper.rb +51 -0
  20. data/lib/capistrano/data_plane_api/deploy/server_stats.rb +110 -0
  21. data/lib/capistrano/data_plane_api/deploy.rb +27 -0
  22. data/lib/capistrano/data_plane_api/diggable.rb +31 -0
  23. data/lib/capistrano/data_plane_api/equatable.rb +32 -0
  24. data/lib/capistrano/data_plane_api/helper.rb +56 -0
  25. data/lib/capistrano/data_plane_api/hooks.rb +7 -0
  26. data/lib/capistrano/data_plane_api/show_state.rb +86 -0
  27. data/lib/capistrano/data_plane_api/tasks.rb +30 -0
  28. data/lib/capistrano/data_plane_api/terminal_print_loop.rb +43 -0
  29. data/lib/capistrano/data_plane_api/type.rb +29 -0
  30. data/lib/capistrano/data_plane_api/version.rb +8 -0
  31. data/lib/capistrano/data_plane_api.rb +296 -0
  32. data/readme/failed_deployment_summary.png +0 -0
  33. data/readme/haproxy_state.png +0 -0
  34. data/sig/capistrano/data_plane_api.rbs +6 -0
  35. data/templates/bin/deploy +5 -0
  36. data/templates/bin/deploy.rb +6 -0
  37. data/templates/config/data_plane_api.rb +6 -0
  38. data/templates/config/data_plane_api.yml +51 -0
  39. metadata +177 -0
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module DataPlaneApi
5
+ # Provides helper methods
6
+ module Helper
7
+ # @return [Hash{String => Symbol}]
8
+ ADMIN_STATE_COLORS = {
9
+ 'drain' => :on_blue,
10
+ 'ready' => :on_green,
11
+ 'maint' => :on_yellow
12
+ }.freeze
13
+
14
+ # @return [Hash{String => Symbol}]
15
+ OPERATIONAL_STATE_COLORS = {
16
+ 'up' => :on_green,
17
+ 'down' => :on_red,
18
+ 'stopping' => :on_yellow
19
+ }.freeze
20
+
21
+ # @return [Boolean]
22
+ def no_haproxy?
23
+ !::ENV['NO_HAPROXY'].nil? && !::ENV['NO_HAPROXY'].empty?
24
+ end
25
+
26
+ # @return [Boolean]
27
+ def force_haproxy?
28
+ !::ENV['FORCE_HAPROXY'].nil? && !::ENV['FORCE_HAPROXY'].empty?
29
+ end
30
+
31
+ # @param state [String, Symbol, nil]
32
+ # @return [String, nil]
33
+ def humanize_admin_state(state)
34
+ return unless state
35
+
36
+ state = state.to_s
37
+ COLORS.decorate(" #{state.upcase} ", :bold, ADMIN_STATE_COLORS[state.downcase])
38
+ end
39
+
40
+ # @param state [String, Symbol, nil]
41
+ # @return [String, nil]
42
+ def humanize_operational_state(state)
43
+ return unless state
44
+
45
+ state = state.to_s
46
+ COLORS.decorate(" #{state.upcase} ", :bold, OPERATIONAL_STATE_COLORS[state.downcase])
47
+ end
48
+
49
+ # @param backend [Capistrano::DataPlaneApi::Configuration::Backend]
50
+ # @return [String]
51
+ def humanize_backend_name(backend)
52
+ COLORS.decorate(" #{backend.name} ", *backend.styles)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../data_plane_api'
4
+
5
+ after 'deploy:started', 'data_plane_api:server:set_drain'
6
+ before 'deploy:publishing', 'data_plane_api:server:set_maint'
7
+ after 'deploy:finished', 'data_plane_api:server:set_ready'
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pastel'
4
+ require 'tty/box'
5
+ require 'data_plane_api'
6
+
7
+ module Capistrano
8
+ module DataPlaneApi
9
+ # Creates a human readable summary of the state of
10
+ # HAProxy backends and servers to stdout.
11
+ module ShowState
12
+ class << self
13
+ # @return [String]
14
+ def call # rubocop:disable Metrics/MethodLength
15
+ pastel = ::Pastel.new
16
+ result = ::String.new
17
+
18
+ result << pastel.blue.bold('HAProxy State')
19
+ result << "\n"
20
+ result << pastel.bold.yellow(::Time.now.to_s)
21
+ result << "\n\n"
22
+ config = ::DataPlaneApi::Configuration.new.tap do |c|
23
+ c.logger = ::Logger.new($stdout)
24
+ c.logger.level = ::Logger::FATAL
25
+ c.timeout = 2
26
+ end
27
+
28
+ ::Capistrano::DataPlaneApi.configuration.backends.each do |backend|
29
+ result << ::TTY::Box.frame(title: { top_left: backend_name(backend) }) do
30
+ b = ::String.new
31
+ servers = ::Capistrano::DataPlaneApi.get_backend_servers_settings(backend.name, config: config).body
32
+ servers.each do |server|
33
+ operational_state = operational_state(server)
34
+ admin_state = admin_state(server)
35
+ b << ::TTY::Box.frame(title: { top_left: server_name(server) }, border: :thick) do
36
+ s = ::String.new
37
+ s << " admin_state: #{admin_state}\n"
38
+ s << "operational_state: #{operational_state}\n"
39
+ s
40
+ end
41
+ end
42
+ b
43
+
44
+ rescue Error, ::Faraday::ConnectionFailed, ::Faraday::TimeoutError
45
+ b << pastel.bold.bright_red('Unavailable!')
46
+ b << "\n"
47
+ b
48
+ end
49
+ end
50
+
51
+ result
52
+ end
53
+
54
+ private
55
+
56
+ # @param server [Hash{String => Object}]
57
+ # @return [String]
58
+ def operational_state(server)
59
+ ::Capistrano::DataPlaneApi.humanize_operational_state(server['operational_state'])
60
+ end
61
+
62
+ # @param server [Hash{String => Object}]
63
+ # @return [String]
64
+ def admin_state(server)
65
+ ::Capistrano::DataPlaneApi.humanize_admin_state(server['admin_state'])
66
+ end
67
+
68
+ # @param server [Hash{String => Object}]
69
+ # @return [String]
70
+ def server_name(server)
71
+ pastel = ::Pastel.new
72
+ pastel.bold server['name']
73
+ end
74
+
75
+ # @param backend [Capistrano::DataPlaneApi::Configuration::Backend]
76
+ # @return [String]
77
+ def backend_name(backend)
78
+ pastel = ::Pastel.new
79
+ pastel.decorate(" #{backend.name} ", *backend.styles)
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+
5
+ namespace :data_plane_api do
6
+ namespace :server do
7
+ desc "Set the server's admin state to DRAIN through the HAProxy Data Plane API"
8
+ task :set_drain do
9
+ next if no_haproxy?
10
+
11
+ ::Capistrano::DataPlaneApi.server_set_drain fetch(:stage), force: force_haproxy?
12
+ end
13
+
14
+ desc "Set the server's admin state to READY through the HAProxy Data Plane API"
15
+ task :set_ready do
16
+ next if no_haproxy?
17
+
18
+ sleep 3
19
+ ::Capistrano::DataPlaneApi.server_set_ready fetch(:stage)
20
+ end
21
+
22
+ desc "Set the server's admin state to MAINT through the HAProxy Data Plane API"
23
+ task :set_maint do
24
+ next if no_haproxy?
25
+
26
+ sleep 3
27
+ ::Capistrano::DataPlaneApi.server_set_maint fetch(:stage), force: true
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tty/cursor'
4
+
5
+ module Capistrano
6
+ module DataPlaneApi
7
+ module TerminalPrintLoop
8
+ class << self
9
+ # Calls the passed block in an endless loop with a given interval
10
+ # between calls.
11
+ # It prints the `String` returned from the block and clears it
12
+ # before another frame is printed.
13
+ #
14
+ # @yieldparam content [String]
15
+ # @param interval [Integer] Number of seconds between each screen refresh
16
+ def call(interval: 2)
17
+ previous_line_count = 0
18
+ previous_max_line_length = 0
19
+ loop do
20
+ content = ::String.new
21
+ yielded = yield(content)
22
+
23
+ print ::TTY::Cursor.clear_lines(previous_line_count + 1)
24
+
25
+ content = yielded if yielded.is_a?(::String) && content.length.zero?
26
+ line_count = 0
27
+ max_line_length = 0
28
+ content.each_line do |line|
29
+ line_count += 1
30
+ max_line_length = line.length if line.length > max_line_length
31
+ end
32
+ previous_line_count = line_count
33
+ previous_max_line_length = max_line_length
34
+
35
+ puts(content)
36
+ sleep(interval)
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shale'
4
+
5
+ require_relative 'diggable'
6
+ require_relative 'equatable'
7
+
8
+ module Capistrano
9
+ module DataPlaneApi
10
+ class Type < ::Shale::Mapper
11
+ include Diggable
12
+ include Equatable
13
+
14
+ alias to_h to_hash
15
+
16
+ # @param key [Symbol, String]
17
+ # @return [Object, nil]
18
+ def [](key)
19
+ public_send(key) if respond_to?(key)
20
+ end
21
+
22
+ # @param key [Symbol, String]
23
+ # @param val [Object]
24
+ def []=(key, val)
25
+ public_send(:"#{key}=", val)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module DataPlaneApi
5
+ # @return [String]
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
@@ -0,0 +1,296 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'data_plane_api'
4
+ require 'pastel'
5
+ require 'pathname'
6
+ require 'json'
7
+ require 'logger'
8
+
9
+ require_relative 'data_plane_api/version'
10
+ require_relative 'data_plane_api/helper'
11
+ require_relative 'data_plane_api/terminal_print_loop'
12
+ require_relative 'data_plane_api/configuration'
13
+ require_relative 'data_plane_api/show_state'
14
+
15
+ module Capistrano
16
+ # Main module/namespace of the `capistrano-data_plane_api` gem.
17
+ module DataPlaneApi
18
+ extend Helper
19
+
20
+ class Error < ::StandardError; end
21
+ class NotConfiguredError < Error; end
22
+ class QueryError < Error; end
23
+ class NoOtherServerReadyError < Error; end
24
+ class UpdateServerStateError < Error; end
25
+ class NoSuchBackendError < Error; end
26
+ class NoBackendForThisStageError < Error; end
27
+
28
+ # @return [Pastel::Delegator]
29
+ COLORS = ::Pastel.new
30
+
31
+ class << self
32
+ # @return [Capistrano::DataPlaneApi::Configuration]
33
+ def configuration
34
+ raise NotConfiguredError, <<~ERR unless @configuration
35
+ `Capistrano::DataPlaneApi` is not configured!
36
+ You should register a configuration file like so:
37
+ Capistrano::DataPlaneApi.configuration = '/path/to/your/file.yaml'
38
+ ERR
39
+
40
+ @configuration
41
+ end
42
+
43
+ # @param val [Capistrano::DataPlaneApi::Configuration, Hash{String, Symbol => Object}, String, Pathname]
44
+ def configuration=(val)
45
+ case val
46
+ when ::Hash
47
+ # as of now `shale` does not support
48
+ # symbol keys in hashes, so
49
+ # we convert it to JSON an back
50
+ # to a Hash to convert all Symbols
51
+ # to Strings
52
+ @configuration = Configuration.from_json(val.to_json)
53
+ when Configuration
54
+ @configuration = val
55
+ when ::String, ::Pathname
56
+ @configuration = Configuration.from_file(val.to_s)
57
+ @configuration.file_path = val
58
+ else
59
+ raise ::ArgumentError,
60
+ "Configuration should be a `#{::Hash}`, `#{Configuration}`, #{::String} or #{::Pathname}" \
61
+ ", received: #{val.inspect} (#{val.class.inspect})"
62
+ end
63
+ end
64
+
65
+ # Prints the current configuration in a human readable format.
66
+ #
67
+ # @return [void]
68
+ def show_config
69
+ puts ::JSON.pretty_generate(configuration.to_h)
70
+ end
71
+
72
+ # Prints the current state of all backends and
73
+ # their servers in a human readable format.
74
+ #
75
+ # @return [void]
76
+ def show_state
77
+ TerminalPrintLoop.call do
78
+ ShowState.call
79
+ end
80
+ end
81
+
82
+ # Set server's admin_state to `drain`.
83
+ #
84
+ # @param deployment_stage [Symbol]
85
+ # @param force [Boolean] Change the server's state even when no other server is `up`
86
+ # @param config [::DataPlaneApi::Configuration, nil]
87
+ # @return [Hash, FalseClass] Server state after the change, or `false`
88
+ # when no change happened
89
+ # @raise [Error] The process failed due to some reason
90
+ def server_set_drain(deployment_stage, force: false, config: nil)
91
+ haproxy_server, haproxy_backend = find_server_and_backend(deployment_stage)
92
+ return false if haproxy_backend.servers.length < 2 # skip HAProxy if there is only a single server
93
+
94
+ validate_backend_state(haproxy_backend, haproxy_server) unless force
95
+
96
+ conf = ::DataPlaneApi::Configuration.new(
97
+ basic_user: haproxy_backend.basic_user || @configuration.basic_user,
98
+ basic_password: haproxy_backend.basic_password || @configuration.basic_password,
99
+ parent: config,
100
+ url: configuration.api_url
101
+ )
102
+
103
+ # set the target server's state to `drain`
104
+ response =
105
+ ::DataPlaneApi::Server.update_transient_settings(
106
+ backend: haproxy_backend.name,
107
+ name: haproxy_server.name,
108
+ settings: { admin_state: :drain },
109
+ config: conf
110
+ )
111
+
112
+ unless response.status.between?(200, 299) && response.body['admin_state'] == 'drain'
113
+ raise UpdateServerStateError,
114
+ "HAProxy mutation failed! Couldn't set server's `admin_state` to `drain`."
115
+ end
116
+
117
+ response.body
118
+ end
119
+
120
+ # Set server's admin_state to `maint`.
121
+ #
122
+ # @param deployment_stage [Symbol]
123
+ # @param force [Boolean] Change the server's state even when no other server is `up`
124
+ # @param config [::DataPlaneApi::Configuration, nil]
125
+ # @return [Hash, FalseClass] Server state after the change, or `false`
126
+ # when no change happened
127
+ # @raise [Error] The process failed due to some reason
128
+ def server_set_maint(deployment_stage, force: false, config: nil)
129
+ haproxy_server, haproxy_backend = find_server_and_backend(deployment_stage)
130
+ return false if haproxy_backend.servers.length < 2 # skip HAProxy if there is only a single server
131
+
132
+ validate_backend_state(haproxy_backend, haproxy_server) unless force
133
+
134
+ conf = ::DataPlaneApi::Configuration.new(
135
+ basic_user: haproxy_backend.basic_user || @configuration.basic_user,
136
+ basic_password: haproxy_backend.basic_password || @configuration.basic_password,
137
+ parent: config,
138
+ url: configuration.api_url
139
+ )
140
+
141
+ # set the target server's state to `maint`
142
+ response =
143
+ ::DataPlaneApi::Server.update_transient_settings(
144
+ backend: haproxy_backend.name,
145
+ name: haproxy_server.name,
146
+ settings: { admin_state: :maint },
147
+ config: conf
148
+ )
149
+
150
+ unless response.status.between?(200, 299) && response.body['admin_state'] == 'maint'
151
+ raise UpdateServerStateError,
152
+ "HAProxy mutation failed! Couldn't set server's `admin_state` to `drain`."
153
+ end
154
+
155
+ response.body
156
+ end
157
+
158
+ # Set server's admin_state to `ready`
159
+ #
160
+ # @param deployment_stage [Symbol]
161
+ # @param config [::DataPlaneApi::Configuration, nil]
162
+ # @return [Hash, FalseClass] Server state after the change, or `false`
163
+ # when no change happened
164
+ # @raise [Error] The process failed due to some reason
165
+ def server_set_ready(deployment_stage, config: nil)
166
+ haproxy_server, haproxy_backend = find_server_and_backend(deployment_stage)
167
+ return false if haproxy_backend.servers.length < 2 # skip HAProxy if there is only a single server
168
+
169
+ conf = ::DataPlaneApi::Configuration.new(
170
+ basic_user: haproxy_backend.basic_user || @configuration.basic_user,
171
+ basic_password: haproxy_backend.basic_password || @configuration.basic_password,
172
+ parent: config,
173
+ url: configuration.api_url
174
+ )
175
+
176
+ # set the target server's state to `drain`
177
+ response =
178
+ ::DataPlaneApi::Server.update_transient_settings(
179
+ backend: haproxy_backend.name,
180
+ name: haproxy_server.name,
181
+ settings: { admin_state: :ready },
182
+ config: conf
183
+ )
184
+
185
+ unless response.status.between?(200, 299) &&
186
+ response.body['admin_state'] == 'ready' &&
187
+ response.body['operational_state'] == 'up'
188
+
189
+ raise UpdateServerStateError,
190
+ "HAProxy mutation failed! Couldn't set server's `admin_state` to `ready`."
191
+ end
192
+
193
+ response.body
194
+ end
195
+
196
+ # Find the HAProxy backend config with a particular name.
197
+ #
198
+ # @param backend_name [String]
199
+ # @return [Capistrano::DataPlaneApi::Configuration::Backend] HAProxy backend config.
200
+ # @raise [NoSuchBackendError] There is no backend with this name.
201
+ def find_backend(backend_name)
202
+ backend = configuration.backends.find { _1.name == backend_name }
203
+ if backend.nil?
204
+ raise NoSuchBackendError,
205
+ 'There is no HAProxy backend with this name! ' \
206
+ "`#{backend_name.inspect}`"
207
+ end
208
+
209
+ backend
210
+ end
211
+
212
+ # Find the server and backend config for a particular
213
+ # deployment stage.
214
+ #
215
+ # @param deployment_stage [Symbol, String]
216
+ # @return [Capistrano::DataPlaneApi::Configuration::Server, Capistrano::DataPlaneApi::Configuration::Backend]
217
+ # Two-element Array
218
+ # where the first element is the HAProxy server config and the second one
219
+ # is the HAProxy backend config
220
+ def find_server_and_backend(deployment_stage)
221
+ # @type [Capistrano::DataPlaneApi::Configuration::Server, nil]
222
+ haproxy_server = nil
223
+ deployment_stage_str = deployment_stage.to_s
224
+ # find the HAProxy backend that the
225
+ # current deployment target is a part of
226
+ # @type [Capistrano::DataPlaneApi::Configuration::Backend]
227
+ haproxy_backend =
228
+ configuration.backends.each do |backend|
229
+ haproxy_server = backend.servers.find { _1.stage == deployment_stage_str }
230
+ break backend if haproxy_server
231
+ end
232
+
233
+ unless haproxy_backend.is_a?(Configuration::Backend)
234
+ raise NoBackendForThisStageError,
235
+ 'There are no HAProxy backends for this deployment stage! ' \
236
+ "#{deployment_stage.inspect} `#{configuration.file_path.inspect}`"
237
+ end
238
+
239
+ [haproxy_server, haproxy_backend]
240
+ end
241
+
242
+ # @param backend_name [String]
243
+ # @param config [::DataPlaneApi::Configuration, nil]
244
+ # @return [Faraday::Response]
245
+ def get_backend_servers_settings(backend_name, config: nil)
246
+ haproxy_backend = find_backend(backend_name)
247
+ conf = ::DataPlaneApi::Configuration.new(
248
+ basic_user: haproxy_backend.basic_user || @configuration.basic_user,
249
+ basic_password: haproxy_backend.basic_password || @configuration.basic_password,
250
+ parent: config,
251
+ url: configuration.api_url
252
+ )
253
+ response = ::DataPlaneApi::Server.get_runtime_settings(backend: backend_name, config: conf)
254
+ unless response.status.between?(200, 299)
255
+ raise QueryError,
256
+ "HAProxy query failed! Couldn't fetch servers' states"
257
+ end
258
+
259
+ response
260
+ end
261
+
262
+ private
263
+
264
+ # @param haproxy_backend [Capistrano::DataPlaneApi::Configuration::Backend]
265
+ # @param haproxy_server [Capistrano::DataPlaneApi::Configuration::Server]
266
+ # @return [void]
267
+ def validate_backend_state(haproxy_backend, haproxy_server)
268
+ response = get_backend_servers_settings(haproxy_backend.name)
269
+ unless haproxy_backend.servers.length == response.body.length
270
+ raise QueryError,
271
+ 'HAProxy query failed! Configured servers for this backend' \
272
+ "don't match the configuration file! `#{configuration.file_path}`"
273
+ end
274
+
275
+ # @type [Array<Hash>]
276
+ server_statuses = response.body
277
+ # check if there are any servers other than this one that are `ready` and `up`
278
+ other_servers_ready = server_statuses.any? do |server_status|
279
+ server_status['admin_state'] == 'ready' &&
280
+ server_status['operational_state'] == 'up' &&
281
+ server_status['name'] != haproxy_server.name
282
+ end
283
+
284
+ unless other_servers_ready # rubocop:disable Style/GuardClause
285
+ raise NoOtherServerReadyError,
286
+ 'No other server is `ready`' \
287
+ "in this backend `#{haproxy_backend.name}`"
288
+ end
289
+ end
290
+
291
+ end
292
+
293
+ end
294
+ end
295
+
296
+ require_relative 'data_plane_api/tasks' if defined?(::Rake)
Binary file
@@ -0,0 +1,6 @@
1
+ module Capistrano
2
+ module DataPlaneApi
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+
3
+ BIN_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4
+
5
+ bundle exec ruby $BIN_DIR/deploy.rb $@
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../config/data_plane_api'
4
+ require 'capistrano/data_plane_api/deploy'
5
+
6
+ ::Capistrano::DataPlaneApi::Deploy.call
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capistrano/data_plane_api'
4
+
5
+ ::Capistrano::DataPlaneApi.configuration =
6
+ ::File.expand_path('data_plane_api.yml', __dir__)
@@ -0,0 +1,51 @@
1
+ # We recommend to keep your credentials outside of Git.
2
+ # You can achieve that by reading ENV variables using ERB in this file,
3
+ # or add this file to .gitignore and provide an example file with fake data
4
+ # called `config/data_plane_api.yml.example` which will serve as
5
+ # an example of how it should be configured.
6
+
7
+ # Root URL of the HAProxy Data Plane API
8
+ api_url: http://example.com/haproxy-data-plane-api
9
+ logger_level: <%= Logger::DEBUG %>
10
+ # Default Data Plane API BasicAuth credentials
11
+ basic_user: my_user # Data Plane API BasicAuth username
12
+ basic_password: my_password # Data Plane API BasicAuth password
13
+
14
+ # List of HAProxy backends
15
+ backends:
16
+ - name: back_production # your HAProxy backend name
17
+ # styles defined in the `Pastel` gem, used in the terminal to uniquely identify this backend
18
+ # by coloring its name.
19
+ # Read more: https://github.com/piotrmurach/pastel#3-supported-colors
20
+ styles:
21
+ - :bold
22
+ - :on_red
23
+ # List of servers under this backend
24
+ servers:
25
+ - name: production1 # HAProxy server name and Capistrano stage name (config/deploy/production1.rb)
26
+ - name: production2
27
+ # when the HAProxy server name is different from the Capistrano stage name.
28
+ - name: production3_haproxy_server # HAProxy server name
29
+ stage: production3_capistrano_stage # Capistrano stage name (config/deploy/production3_capistrano_stage.rb)
30
+
31
+ - name: back_staging
32
+ styles:
33
+ - :bold
34
+ - :on_blue
35
+ # This backend has its own credentials
36
+ basic_user: some_other_user # Data Plane API BasicAuth user for this password
37
+ basic_password: some_other_password # Data Plane API BasicAuth password for this backend
38
+ servers:
39
+ - name: staging1
40
+ - name: staging2
41
+
42
+ - name: back_edge
43
+ styles:
44
+ - :bold
45
+ - :on_green
46
+ # You can use ERB to read data from Environment Variables.
47
+ basic_user: <%= ENV['USER'] %>
48
+ basic_password: <%= ENV['PASS'] %>
49
+ servers:
50
+ - name: edge1
51
+ stage: edge2