ey_stonith 0.3.6 → 0.4.1.pre

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 (42) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +3 -0
  3. data/Rakefile +26 -0
  4. data/ey_stonith.gemspec +36 -0
  5. data/features/check.feature +57 -0
  6. data/features/cron.feature +67 -0
  7. data/features/fixtures/dead.ru +6 -0
  8. data/features/fixtures/healthy.ru +1 -0
  9. data/features/help.feature +7 -0
  10. data/features/not_found.feature +24 -0
  11. data/features/notify.feature +35 -0
  12. data/features/resume.feature +49 -0
  13. data/features/steps/stonith_steps.rb +40 -0
  14. data/features/stop.feature +48 -0
  15. data/features/support/env.rb +77 -0
  16. data/lib/ey_stonith/awsm_notifier.rb +13 -8
  17. data/lib/ey_stonith/commands/abstract.rb +0 -4
  18. data/lib/ey_stonith/commands/check.rb +13 -36
  19. data/lib/ey_stonith/commands/claim.rb +5 -96
  20. data/lib/ey_stonith/commands/cron.rb +3 -5
  21. data/lib/ey_stonith/commands/info.rb +1 -4
  22. data/lib/ey_stonith/commands/not_found.rb +1 -0
  23. data/lib/ey_stonith/commands/notify.rb +16 -55
  24. data/lib/ey_stonith/commands/reset.rb +0 -1
  25. data/lib/ey_stonith/commands/stop.rb +0 -1
  26. data/lib/ey_stonith/commands/takeover.rb +5 -90
  27. data/lib/ey_stonith/commands.rb +1 -1
  28. data/lib/ey_stonith/config.rb +17 -66
  29. data/lib/ey_stonith/rackapp.rb +26 -2
  30. data/lib/ey_stonith.rb +8 -15
  31. data/spec/config_spec.rb +53 -0
  32. data/spec/fixtures/config.yml +11 -0
  33. data/spec/fixtures/empty.yml +1 -0
  34. data/spec/helpers.rb +15 -0
  35. data/spec/history_spec.rb +58 -0
  36. data/spec/rackapp_spec.rb +100 -0
  37. data/spec/spec_helper.rb +24 -0
  38. metadata +240 -60
  39. data/lib/ey_stonith/address_stealer.rb +0 -40
  40. data/lib/ey_stonith/check_recorder.rb +0 -55
  41. data/lib/ey_stonith/data.rb +0 -11
  42. data/lib/ey_stonith/database.rb +0 -78
@@ -2,110 +2,19 @@ module EY
2
2
  module Stonith
3
3
  module Commands
4
4
  class Claim < Abstract
5
-
6
5
  def self.command
7
6
  'claim'
8
7
  end
9
8
 
10
9
  def self.banner
11
- 'Claim the master record in the database'
12
- end
13
-
14
- def claim_path
15
- @claim_path ||= config.claim_path
10
+ "Legacy command. No longer used."
16
11
  end
17
12
 
18
13
  def invoke
19
- claim_path.exist?? invoke_with_claim_file : invoke_without_claim_file
20
- end
21
-
22
- def invoke_with_claim_file
23
- abort_on_existing_data
24
-
25
- attempts = (claim_path.read || 0).to_i.succ
26
-
27
- if @force || attempts >= 6
28
- reclaim!
29
- else
30
- persist_reclaim_attempt(attempts)
31
- end
32
- end
33
-
34
- def abort_on_existing_data
35
- return unless master_hostname
36
-
37
- if config.meta_data_hostname == master_hostname
38
- abort "Already claimed, not claiming."
39
- else
40
- claim_path.delete
41
- abort "#{master_hostname} is master, not claiming.\nRemoving stale claim file."
42
- end
43
- end
44
-
45
- def reclaim!
46
- Stonith.logger.info @force ? "Reclaim forced." : "Reclaim after 6 consecutive checks."
47
- claim_path.delete
48
- invoke_without_claim_file
49
- end
50
-
51
- def persist_reclaim_attempt(attempts)
52
- claim_path.open("w") { |f| f << attempts }
53
-
54
- abort <<-ERROR
55
- Master unknown and claim file exists, not claiming.
56
- Reclaim at 6th attempt or use --force
57
-
58
- Failed attempts: #{attempts}
59
- ERROR
60
- end
61
-
62
- def invoke_without_claim_file
63
- @force ? database.reset : confirm_master!
64
-
65
- data = Data.new(config.meta_data_hostname, config.meta_data_id, config.meta_data_ip)
66
- database.set data
67
- claim_path.open('w') {}
68
-
69
- Stonith.logger.info "Claimed with data: #{data}"
70
- history << :claim
71
- end
72
-
73
- def confirm_master!
74
- # TODO: Only claim if the master has an IP?
75
- # if fog.servers.get(config.meta_data_id).addresses.empty?
76
- # abort "No IP, not claiming." + (@force ? "\nIgnoring --force" : "")
77
- # end
78
-
79
- confirm_master_with_database
80
- confirm_master_with_config
81
- end
82
-
83
- def confirm_master_with_database
84
- return unless master_hostname
85
-
86
- if config.meta_data_hostname == master_hostname
87
- claim_path.open('w') {}
88
- abort "Already claimed, not claiming. Touching claim file."
89
- else
90
- abort "#{master_hostname} is master, not claiming."
91
- end
92
- end
93
-
94
- def confirm_master_with_config
95
- if config.meta_data_hostname != config.monitor_host
96
- abort "#{config.monitor_host} is master, not claiming."
97
- end
98
- end
99
-
100
- def master_hostname
101
- @master_hostname ||= database.with_data { |data| data.hostname }
102
- end
103
-
104
- def parser
105
- super.on('-f', '--force', "Force the command (only applicable to claim currently)") do |f|
106
- @force = f
107
- end
108
- super
14
+ puts <<-HELP
15
+ Yo Dawg, I heard you like Claim, but we removed it because we don't do that anymore, so stop using it.
16
+ There is no replacement command needed. Just update instances to update the master.
17
+ HELP
109
18
  end
110
19
  end
111
20
  end
@@ -13,7 +13,7 @@ module EY
13
13
  def invoke
14
14
  Stonith.logger.info "Stonith started"
15
15
  heartbeat_loop do |beat|
16
- unless_stopped { run_commands if beat.zero? }
16
+ unless_stopped { run_command if beat.zero? }
17
17
  sleep 1
18
18
  end
19
19
  end
@@ -30,10 +30,8 @@ module EY
30
30
  end
31
31
  end
32
32
 
33
- def run_commands
34
- %w[claim notify check].each do |cmd|
35
- system("#{script} #{cmd}#{command_options}")
36
- end
33
+ def run_command
34
+ system("#{script} check#{command_options}")
37
35
  end
38
36
  end
39
37
  end
@@ -7,14 +7,11 @@ module EY
7
7
  end
8
8
 
9
9
  def self.banner
10
- "Print the full config file and database contents"
10
+ "Print the full config file"
11
11
  end
12
12
 
13
13
  def invoke
14
14
  puts config
15
- puts "Database:"
16
- data = database.with_data { |data| data }
17
- puts " #{data}"
18
15
  end
19
16
  end
20
17
  end
@@ -3,6 +3,7 @@ module EY
3
3
  module Commands
4
4
  class NotFound < Abstract
5
5
  def invoke
6
+ Stonith.logger.error "Command not found: #{@argv.inspect}"
6
7
  abort "Command not found #{@argv.first.inspect}.\n#{parser}"
7
8
  end
8
9
  end
@@ -7,7 +7,7 @@ module EY
7
7
  end
8
8
 
9
9
  def self.banner
10
- 'Notify the provisioning server about a takeover'
10
+ 'Notify the provisioning server that master is down.'
11
11
  end
12
12
 
13
13
  def notify_path
@@ -15,70 +15,31 @@ module EY
15
15
  end
16
16
 
17
17
  def invoke
18
- abort_if_unintentional
19
-
20
- notify_path.delete if notify_path.exist?
21
-
22
- database.with_data do |data|
23
- abort_if_master data.hostname
24
- notify!
25
- end
26
-
27
- abort_no_data
28
- end
29
-
30
- def abort_if_unintentional
31
- return if @force || notify_path.exist?
32
-
33
- abort <<-ERROR
34
- Cannot notify, #{notify_path} does not exist.
35
- If you want to (destructively) notify AWSM that this instance is master, call with --force.
36
- ERROR
37
- end
38
-
39
- def abort_if_master(hostname)
40
- if config.meta_data_hostname != hostname
41
- Stonith.logger.error "Cannot notify, I am not master. Master is #{hostname}. Cancelling notify."
42
- abort "Cannot notify, I am not master."
43
- end
44
- end
45
-
46
- def abort_no_data
47
- msg = "Cannot notify, there is no master in the database. Giving up."
48
- Stonith.logger.error msg
49
- abort msg
18
+ Stonith.logger.warn "Notifying provisioning server that master is down."
19
+ history << :notify
20
+ notify!
21
+ exit
50
22
  end
51
23
 
52
24
  def notify!
53
- notifier = AwsmNotifier.new config.meta_data_id, config.takeover_uri, config.endpoint_token
54
- notifier.notify method(:success), method(:unreachable), method(:refused)
25
+ notifier = AwsmNotifier.new(config.notify_uri, config.endpoint_id, config.endpoint_token, {
26
+ 'monitor_host' => config.monitor_host
27
+ })
28
+
29
+ notifier.notify method(:success), method(:unreachable)
55
30
  end
56
31
 
57
- def success
58
- Stonith.logger.info "AWSM notified!"
32
+ def success(data)
59
33
  history << :notified
60
- exit
34
+ count = data['notification_count'] || 'N/A'
35
+ takeover = data['takeover'].inspect
36
+ Stonith.logger.info "Provisioning server notified: (notification_count: #{count}, takeover: #{takeover})"
61
37
  end
62
38
 
63
39
  def unreachable
64
- notify_path.open('w') {}
65
- msg = "Unable to reach AWSM for promotion to master."
40
+ msg = "Unable to notify provisioning server that master is down."
66
41
  Stonith.logger.warn msg
67
- abort "#{msg}\nIf you're running this from the command line, you should run ey-monitor-notify again."
68
- end
69
-
70
- def refused(response_body)
71
- msg = "Notify refused by endpoint. Giving up.\nResponse: #{response_body}"
72
- Stonith.logger.error msg
73
- history << :refused
74
- abort msg
75
- end
76
-
77
- def parser
78
- super.on '-f', '--force', "Force the command (only applicable to claim currently)" do |f|
79
- @force = f
80
- end
81
- super
42
+ abort "#{msg}\nIf you're running this from the command line, you should run `stonith notify` again."
82
43
  end
83
44
  end
84
45
  end
@@ -11,7 +11,6 @@ module EY
11
11
  end
12
12
 
13
13
  def invoke
14
- database.reset
15
14
  config.state_path.rmtree
16
15
  Stonith.logger.info "All state and database reset!"
17
16
  end
@@ -15,7 +15,6 @@ module EY
15
15
  sleep(0.5) until history.last == "stop"
16
16
 
17
17
  Stonith.logger.info "Stonith stopped"
18
- puts "takeover" if history.include?(:takeover)
19
18
  end
20
19
  end
21
20
  end
@@ -1,5 +1,3 @@
1
- require 'pathname'
2
-
3
1
  module EY
4
2
  module Stonith
5
3
  module Commands
@@ -9,97 +7,14 @@ module EY
9
7
  end
10
8
 
11
9
  def self.banner
12
- 'Cause a takeover of the specified master'
10
+ "Legacy command. No longer used. Run this command for more info."
13
11
  end
14
12
 
15
13
  def invoke
16
- abort_if_no_instance_id
17
- abort_if_self
18
-
19
- abort_if_takeover_lock
20
- set_takeover_lock
21
-
22
- database.with_locked_data do |data|
23
- restore_data_on_fail(data)
24
-
25
- if instance_id == data.instance_id
26
- locked!(data.instance_id, data.ip)
27
- else
28
- relent!
29
- end
30
- end
31
- end
32
-
33
- def abort_if_no_instance_id
34
- if !instance_id || instance_id == ""
35
- abort "Please call with the instance_id of the master to takeover.\n\n#{parser}"
36
- end
37
- end
38
-
39
- def abort_if_self
40
- if instance_id == config.meta_data_id
41
- abort "Cannot takeover self!"
42
- end
43
- end
44
-
45
- def abort_if_takeover_lock
46
- if config.takeover_path.exist?
47
- abort "Already attempting takeover!\n#{config.takeover_path.read}"
48
- end
49
- end
50
-
51
- def takeover_path
52
- @takeover_path ||= config.takeover_path
53
- end
54
-
55
- def set_takeover_lock
56
- at_exit { takeover_path.delete if takeover_path.exist? }
57
- takeover_path.open('w') { |f| f << "Takeover started at #{Time.now}" }
58
- end
59
-
60
- def restore_data_on_fail(data)
61
- at_exit do
62
- if database.set(data) # always replace the data if it wasn't set
63
- Stonith.logger.error("Emergency replacement of redis data #{data.inspect} occurred.")
64
- end
65
- end
66
- end
67
-
68
- def locked!(instance_id, master_ip)
69
- Stonith.logger.info "Locked! Taking over #{instance_id}."
70
- history << :takeover
71
-
72
- ip = steal_address(instance_id, master_ip)
73
- data = Data.new(config.meta_data_hostname, config.meta_data_id, ip)
74
- database.set data
75
-
76
- takeover_path.delete
77
- execute :notify, "--force"
78
- end
79
-
80
- def relent!
81
- history << :relent
82
- msg = "Failed to grab lock, relenting."
83
- Stonith.logger.info msg
84
- abort msg
85
- end
86
-
87
- def steal_address(instance_id, ip)
88
- Stonith.logger.info "Stealing IP #{ip} from #{instance_id}."
89
- address = AddressStealer.new(instance_id, ip, config.fog_credentials)
90
- address.associate(config.meta_data_id)
91
- address.ip
92
- end
93
-
94
- def instance_id
95
- @instance_id
96
- end
97
-
98
- def parser
99
- super.on('-i', '--instance INSTANCE_ID', "Amazon Instance ID of the failing master") do |instance|
100
- @instance_id = instance
101
- end
102
- super
14
+ puts <<-HELP
15
+ Takeovers are no longer performed from the instance side directly.
16
+ You can cause a takeover by running `stonith notify` 6 times quickly if you really need to.
17
+ HELP
103
18
  end
104
19
  end
105
20
  end
@@ -14,8 +14,8 @@ module EY
14
14
  'help' => :Help,
15
15
  'info' => :Info,
16
16
  'notify' => :Notify,
17
- 'reset' => :Reset,
18
17
  'resume' => :Resume,
18
+ 'reset' => :Reset,
19
19
  'status' => :Status,
20
20
  'stop' => :Stop,
21
21
  'takeover' => :Takeover,
@@ -1,6 +1,5 @@
1
1
  require 'yaml'
2
2
  require 'json'
3
- require 'open-uri'
4
3
 
5
4
  module EY
6
5
  module Stonith
@@ -24,24 +23,15 @@ module EY
24
23
  end
25
24
 
26
25
  DEFAULT = {
27
- 'log' => '/var/log/stonith.log',
28
- 'state_dir' => '/var/run/stonith',
29
- 'heartbeat' => 10,
30
- 'endpoint_uri' => nil,
31
- 'endpoint_token' => nil,
32
-
33
- 'monitor_host' => nil,
34
- 'monitor_path' => '/haproxy/monitor',
26
+ 'log' => '/var/log/stonith.log',
27
+ 'state_dir' => '/var/run/stonith',
28
+ 'heartbeat' => 10,
29
+ 'endpoint_uri' => nil,
30
+ 'endpoint_token' => nil,
31
+ 'endpoint_id' => nil,
32
+ 'monitor_host' => nil,
33
+ 'monitor_path' => '/haproxy/monitor',
35
34
  'monitor_timeout' => 5,
36
-
37
- 'redis_host' => nil,
38
- 'redis_port' => 6379,
39
- 'redis_key' => 'stonith',
40
- 'redis_db' => 14,
41
- 'redis_timeout' => 60 * 5,
42
-
43
- 'aws_secret_id' => nil,
44
- 'aws_secret_key' => nil,
45
35
  }
46
36
 
47
37
  def initialize(config_path)
@@ -65,71 +55,36 @@ Config:
65
55
 
66
56
  state_path: #{state_path}
67
57
  stop_path: #{stop_path}
68
- claim_path: #{claim_path}
69
- checks_path: #{checks_path}
70
- notify_path: #{notify_path}
71
58
  history_path: #{history_path}
72
- takeover_path: #{takeover_path}
59
+ success_path: #{success_path}
73
60
 
74
- endpoint_uri: #{endpoint_uri}
61
+ endpoint_uri: #{endpoint_uri}
75
62
  endpoint_token: #{endpoint_token}
76
- takeover_uri: #{takeover_uri}
77
- fog_credentials: #{fog_credentials.inspect}
78
- awsm_credentials: #{awsm_credentials.inspect}
79
-
80
- meta_data_hostname: #{meta_data_hostname}
81
- meta_data_id: #{meta_data_id}
82
- meta_data_ip: #{meta_data_ip}
63
+ endpoint_id: #{endpoint_id}
64
+ notify_uri: #{notify_uri}
83
65
 
84
- monitor_host: #{monitor_host}
85
- monitor_path: #{monitor_path}
66
+ monitor_host: #{monitor_host}
67
+ monitor_path: #{monitor_path}
86
68
  monitor_timeout: #{monitor_timeout}
87
-
88
- redis_host: #{redis_host}
89
- redis_port: #{redis_port}
90
- redis_key: #{redis_key}
91
- redis_db: #{redis_db}
92
- redis_timeout: #{redis_timeout}
93
69
  STRING
94
70
  end
95
71
 
96
72
  def log_path() pathname(log) end
97
73
  def state_path() ensure_exists(pathname(state_dir)) end
98
74
  def stop_path() state_path + 'stop' end
99
- def claim_path() state_path + 'claim' end
100
- def checks_path() state_path + 'checks' end
101
- def notify_path() state_path + 'notify' end
102
75
  def history_path() state_path + 'history' end
103
- def takeover_path() state_path + 'takeover' end
76
+ def success_path() state_path + 'success' end
104
77
  def endpoint_uri() URI.parse(method_missing('endpoint_uri')) end
105
- def takeover_uri
78
+ def notify_uri
106
79
  result = endpoint_uri
107
- result.path << TAKEOVER_PATH
80
+ result.path << NOTIFY_PATH
108
81
  result
109
82
  end
110
83
 
111
- def meta_data_hostname() @data['meta_data_hostname'] ||= meta_data('local-hostname') end
112
- def meta_data_id() @data['meta_data_id'] ||= meta_data('instance-id') end
113
- def meta_data_ip() @data['meta_data_ip'] || meta_data('public-ipv4') end # don't cache
114
-
115
84
  def respond_to?(meth)
116
85
  @data.key?(meth) || super
117
86
  end
118
87
 
119
- def awsm_credentials
120
- {
121
- 'aws_secret_id' => aws_secret_id,
122
- 'aws_secret_key' => aws_secret_key,
123
- }
124
- end
125
-
126
- def fog_credentials
127
- {
128
- :aws_access_key_id => aws_secret_id,
129
- :aws_secret_access_key => aws_secret_key,
130
- }
131
- end
132
-
133
88
  private
134
89
 
135
90
  def self.secret_hack
@@ -139,10 +94,6 @@ Config:
139
94
  def self.pwned?
140
95
  @secret_hack
141
96
  end
142
-
143
- def meta_data(key)
144
- open("http://169.254.169.254/latest/meta-data/#{key}").read
145
- end
146
97
 
147
98
  def pathname(path) path && Pathname.new(path) end
148
99
 
@@ -4,8 +4,12 @@ require 'json'
4
4
  module EY
5
5
  module Stonith
6
6
  class Rackapp < Sinatra::Base
7
+ enable :raise_errors
8
+ disable :dump_errors
9
+ disable :show_exceptions
10
+
7
11
  before { content_type :json }
8
- get('/') { {}.to_json }
12
+ get('/') { '' }
9
13
 
10
14
  get HEALTH_PATH do
11
15
  unless EY::Stonith.healthy?
@@ -15,14 +19,34 @@ module EY
15
19
  end
16
20
 
17
21
  post TAKEOVER_PATH do
18
- unless EY::Stonith.takeover(label, token)
22
+ if valid?
23
+ unless EY::Stonith.takeover(label)
24
+ status 410
25
+ end
26
+ else
19
27
  status 410
20
28
  end
21
29
  {}.to_json
22
30
  end
23
31
 
32
+ post NOTIFY_PATH do
33
+ if valid?
34
+ EY::Stonith.notify(label, params[:monitor_host])
35
+ {
36
+ 'notification_count' => '1',
37
+ 'takeover' => false
38
+ }.to_json
39
+ else
40
+ status 403
41
+ end
42
+ end
43
+
24
44
  private
25
45
 
46
+ def valid?
47
+ EY::Stonith.valid?(label, token)
48
+ end
49
+
26
50
  def label() params['label'] end
27
51
  def token() params['token'] end
28
52
  end
data/lib/ey_stonith.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'logger'
2
+ require 'open-uri'
2
3
 
3
4
  $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
4
5
 
@@ -6,25 +7,15 @@ module EY
6
7
  module Stonith
7
8
  class Error < StandardError; end
8
9
 
9
- autoload :AbstractMaster, 'ey_stonith/abstract_master'
10
10
  autoload :AwsmNotifier, 'ey_stonith/awsm_notifier'
11
- autoload :AddressStealer, 'ey_stonith/address_stealer'
12
- autoload :Box, 'ey_stonith/box'
13
- autoload :CheckRecorder, 'ey_stonith/check_recorder'
14
11
  autoload :Commands, 'ey_stonith/commands'
15
- autoload :CLI, 'ey_stonith/cli'
16
12
  autoload :Config, 'ey_stonith/config'
17
- autoload :Data, 'ey_stonith/data'
18
- autoload :Database, 'ey_stonith/database'
19
13
  autoload :History, 'ey_stonith/history'
20
- autoload :LocalMaster, 'ey_stonith/local_master'
21
- autoload :Master, 'ey_stonith/master'
22
- autoload :MetaData, 'ey_stonith/meta_data'
23
14
  autoload :Rackapp, 'ey_stonith/rackapp'
24
- autoload :Slave, 'ey_stonith/slave'
25
15
 
26
16
  HEALTH_PATH = '/health' unless defined? HEALTH_PATH
27
17
  TAKEOVER_PATH = '/takeover' unless defined? TAKEOVER_PATH
18
+ NOTIFY_PATH = '/notify' unless defined? NOTIFY_PATH
28
19
 
29
20
  def self.log_to(io)
30
21
  @@logger = Logger.new io
@@ -38,10 +29,12 @@ module EY
38
29
 
39
30
  def self.healthy?() callback_module.healthy? end
40
31
 
41
- def self.takeover(label, token)
42
- if valid? label, token
43
- callback_module.takeover label
44
- end
32
+ def self.takeover(label)
33
+ callback_module.takeover label
34
+ end
35
+
36
+ def self.notify(label, monitor_host)
37
+ callback_module.notify label, monitor_host
45
38
  end
46
39
 
47
40
  def self.valid?(label, token)
@@ -0,0 +1,53 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require 'pathname'
3
+
4
+ describe EY::Stonith::Config do
5
+ before { described_class.send(:secret_hack) }
6
+ def fixture_path(file)
7
+ Pathname.new(File.expand_path(File.join('../fixtures', file), __FILE__))
8
+ end
9
+
10
+ describe "default" do
11
+ subject { described_class.new(fixture_path('empty.yml')) }
12
+
13
+ def self.it_requires(key)
14
+ it(key) { lambda { subject.send(key) }.should raise_error(EY::Stonith::Config::RequiredSetting) }
15
+ end
16
+
17
+ its(:path) { should == fixture_path('empty.yml') }
18
+ its(:log_path) { should == Pathname.new('/var/log/stonith.log') }
19
+ its(:state_path) { should == Pathname.new('/var/run/stonith') }
20
+ its(:stop_path) { should == Pathname.new('/var/run/stonith/stop') }
21
+ its(:history_path) { should == Pathname.new('/var/run/stonith/history') }
22
+ its(:success_path) { should == Pathname.new('/var/run/stonith/success') }
23
+ its(:heartbeat) { should == 10 }
24
+
25
+ it_requires(:monitor_host)
26
+ its(:monitor_path) { should == '/haproxy/monitor' }
27
+ its(:monitor_timeout) { should == 5 }
28
+
29
+ it_requires(:endpoint_uri)
30
+ it_requires(:endpoint_token)
31
+ it_requires(:endpoint_id)
32
+ end
33
+
34
+ describe "overridden" do
35
+ subject { described_class.new(fixture_path('config.yml')) }
36
+
37
+ its(:path) { should == fixture_path('config.yml') }
38
+ its(:log_path) { should == Pathname.new('var/log/stonith.log') }
39
+ its(:state_path) { should == Pathname.new('var/run/stonith') }
40
+ its(:stop_path) { should == Pathname.new('var/run/stonith/stop') }
41
+ its(:history_path) { should == Pathname.new('var/run/stonith/history') }
42
+ its(:success_path) { should == Pathname.new('var/run/stonith/success') }
43
+ its(:heartbeat) { should == 1 }
44
+
45
+ its(:monitor_host) { should == 'localhost' }
46
+ its(:monitor_path) { should == '/chickity/check' }
47
+ its(:monitor_timeout) { should == 10 }
48
+
49
+ its(:endpoint_uri) { should == URI.parse('http://example.com/stonith') }
50
+ its(:endpoint_token) { should == 'i-87654321' }
51
+ its(:endpoint_id) { should == "i-87654321" }
52
+ end
53
+ end