capistrano-data_plane_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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