health_check 2.5.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +162 -111
  4. data/CHANGELOG +36 -0
  5. data/README.rdoc +109 -43
  6. data/Rakefile +1 -1
  7. data/Vagrantfile +32 -0
  8. data/config/routes.rb +1 -1
  9. data/health_check.gemspec +7 -6
  10. data/lib/health_check.rb +51 -6
  11. data/lib/health_check/elasticsearch_health_check.rb +15 -0
  12. data/lib/health_check/health_check_controller.rb +32 -25
  13. data/lib/health_check/health_check_routes.rb +1 -1
  14. data/lib/health_check/middleware_health_check.rb +6 -1
  15. data/lib/health_check/rabbitmq_health_check.rb +16 -0
  16. data/lib/health_check/redis_health_check.rb +20 -7
  17. data/lib/health_check/s3_health_check.rb +9 -14
  18. data/lib/health_check/utils.rb +55 -33
  19. data/lib/health_check/version.rb +1 -1
  20. data/test/fake_smtp_server +143 -24
  21. data/test/init_variables +19 -1
  22. data/test/migrate/nine/9_create_countries.rb +1 -1
  23. data/test/migrate/twelve/011_create_roles.roles.rb +1 -1
  24. data/test/migrate/twelve/012_create_users.rb +2 -2
  25. data/test/migrate/twelve/9_create_countries.rb +1 -1
  26. data/test/provision_vagrant +103 -0
  27. data/test/rails_5.0.gemfile +10 -7
  28. data/test/rails_5.1.gemfile +34 -0
  29. data/test/rails_5.2.gemfile +34 -0
  30. data/test/rails_6.0.gemfile +30 -0
  31. data/test/rails_6.1.gemfile +29 -0
  32. data/test/rails_6.2.gemfile +30 -0
  33. data/test/rails_edge.gemfile +14 -9
  34. data/test/setup_railsapp +175 -95
  35. data/test/test_with_railsapp +152 -46
  36. data/test/testurl +9 -0
  37. metadata +45 -22
  38. data/test/rails_4.0.gemfile +0 -33
  39. data/test/rails_4.1.gemfile +0 -33
  40. data/test/rails_4.2.gemfile +0 -30
@@ -1,3 +1,3 @@
1
1
  module HealthCheck
2
- VERSION = "2.5.0"
2
+ VERSION = "3.1.0"
3
3
  end
@@ -1,38 +1,157 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'socket'
4
+ require 'openssl'
4
5
 
5
- port = 3555
6
+ class FakeSmtpServer
7
+ def initialize(port)
8
+ @port = port
9
+ @socket = TCPServer.new(@port)
10
+ @client = @orig_client = nil
11
+ end
6
12
 
13
+ def start
14
+ return unless @client.nil?
7
15
 
8
- server = TCPServer.new port
9
- puts "fake_smtp_server: Waiting for one connection to port #{port} ..."
16
+ puts "fake_smtp_server: Waiting for one connection to port #{@port} ..."
17
+ @client = @socket.accept
10
18
 
11
- def send(client, line)
12
- client.puts line
13
- puts "> #{line}"
14
- end
19
+ send '220 dummy-smtp.example.com SMTP'
20
+ cmd = receive
15
21
 
16
- def receive(client)
17
- line = client.gets
18
- puts "< #{line}"
19
- line
20
- end
22
+ while cmd !~ /^QUIT\r/
23
+ if cmd =~ /^HELO(.*)\r/
24
+ if ENV['FAIL_SMTP'] == 'HELO'
25
+ send '550 Access Denied – Invalid HELO name'
26
+ else
27
+ send '250-Welcome to a dummy smtp server'
28
+ unless ENV['SMTP_STARTTLS'] == 'DISABLED'
29
+ send '250-STARTTLS'
30
+ end
31
+ send '250-AUTH PLAIN LOGIN'
32
+ send '250 Ok'
33
+ end
34
+ elsif cmd =~ /^AUTH(.*)\r/
35
+ if ENV['FAIL_SMTP'] == 'AUTH'
36
+ send '535 5.7.8 Authentication credentials invalid'
37
+ else
38
+ send '235 2.7.0 Authentication successful'
39
+ end
40
+ elsif cmd =~ /^STARTTLS\r/
41
+ if ENV['SMTP_STARTTLS'] == 'DISABLED'
42
+ send '502 STARTTLS is disabled!'
43
+ end
44
+ send '220 Ready to start TLS'
45
+ if ENV['FAIL_SMTP'] == 'STARTTLS'
46
+ cmd = receive
47
+ return close
48
+ end
49
+ @orig_client = @client
50
+ @client = tlsconnect(@client)
51
+ else
52
+ send '502 I am so dumb I only understand HELO, AUTH, STARTTLS and QUIT which always return a success status'
53
+ end
54
+
55
+ cmd = receive
56
+ end
57
+ send '221 Bye Bye'
58
+
59
+ close
60
+ end
61
+
62
+ private
63
+
64
+ def close
65
+ @client.close unless @client.nil?
66
+ @orig_client.close unless @orig_client.nil?
67
+ end
68
+
69
+ def send(line)
70
+ @client.puts line
71
+ puts "-> #{line}"
72
+ end
73
+
74
+ def receive
75
+ line = @client.gets
76
+ puts "<- #{line}"
77
+ line
78
+ end
79
+
80
+ def ssl_socket(client, context)
81
+ OpenSSL::SSL::SSLSocket.new(client, context)
82
+ end
83
+
84
+ def ssl_context
85
+ @_ssl_context ||= begin
86
+ key, cert = generate_certificate
87
+
88
+ context = OpenSSL::SSL::SSLContext.new
89
+ context.key = key
90
+ context.cert = cert
91
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
92
+ context.min_version = nil
93
+ context
94
+ end
95
+ end
96
+
97
+ # Pass socket from TCPServer.new accept
98
+ def tlsconnect(client)
99
+ ssl_client = ssl_socket(client, ssl_context)
100
+ puts '=> TLS connection started'
101
+ ssl_client.accept
102
+ puts '=> TLS connection established'
103
+
104
+ ssl_client
105
+ end
21
106
 
22
- client = server.accept # Wait for a client to connect
23
- send(client, "220 dummy-smtp.example.com SMTP")
24
- cmd = receive(client)
107
+ def generate_certificate
108
+ key = OpenSSL::PKey::RSA.new(2048)
109
+ name = OpenSSL::X509::Name.parse('CN=localhost')
25
110
 
26
- while cmd !~ /^QUIT\r/
27
- if cmd =~ /^HELO(.*)\r/
28
- send(client, "250 Welcome to a dummy smtp server")
29
- else
30
- send(client, "502 I am so dumb I only understand HELO and QUIT")
111
+ cert = OpenSSL::X509::Certificate.new
112
+ cert.version = 2
113
+ cert.serial = 0
114
+ cert.not_before = Time.now
115
+ cert.not_after = Time.now + 3600
116
+
117
+ cert.public_key = key.public_key
118
+ cert.subject = name
119
+
120
+ extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
121
+
122
+ cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)
123
+ cert.add_extension extension_factory.create_extension('keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
124
+ cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')
125
+
126
+ cert.issuer = name
127
+ cert.sign key, OpenSSL::Digest::SHA256.new
128
+
129
+ [key, cert]
31
130
  end
32
- cmd = receive(client)
33
131
  end
34
- send(client, "221 Bye Bye")
35
132
 
36
- client.close
37
- puts "fake_smtp_server: Exiting now the conversation has finished."
133
+ FakeSmtpServer.new(3555).start
134
+
135
+ puts 'fake_smtp_server: Exiting now the conversation has finished.'
38
136
  exit 0
137
+
138
+ # Tested with irb script:
139
+ # require 'net/smtp'
140
+ #
141
+ # status = ''
142
+ # begin
143
+ # if @skip_external_checks
144
+ # status = '250'
145
+ # else
146
+ # smtp = Net::SMTP.new('localhost', 3555)
147
+ # smtp.enable_starttls
148
+ # smtp.open_timeout = 10
149
+ # smtp.read_timeout = 10
150
+ # smtp.start('domain', 'user_name', 'password', :plain) do
151
+ # status = smtp.helo('domain').status
152
+ # end
153
+ # end
154
+ # rescue Exception => ex
155
+ # status = ex.to_s
156
+ # end
157
+ # (status =~ /^250/) ? 'PASS' : "FAILED SMTP: #{status || 'unexpected error'}. "
data/test/init_variables CHANGED
@@ -1,7 +1,25 @@
1
1
  #!/bin/bash
2
2
 
3
3
  # Any failure causes exit
4
- set -e
4
+ set -eE -o functrace
5
+
6
+ report_failure() {
7
+ local lineno=$2
8
+ local fn=$3
9
+ local exitstatus=$4
10
+ local msg=$5
11
+ local lineno_fns=${1% 0}
12
+ if [[ $lineno_fns != "0" ]] ; then
13
+ lineno="${lineno} ${lineno_fns}"
14
+ fi
15
+ if [[ $exitstatus == 0 ]] ; then
16
+ echo "${BASH_SOURCE[1]}: Finished!"
17
+ else
18
+ echo "${BASH_SOURCE[1]}:${fn}[${lineno}] Failed with status ${exitstatus}: $msg"
19
+ fi
20
+ }
21
+
22
+ trap 'report_failure "${BASH_LINENO[*]}" "$LINENO" "${FUNCNAME[*]:-script}" "$?" "$BASH_COMMAND"' ERR
5
23
 
6
24
  echo Setting RAILS_ENV=test RACK_ENV=test
7
25
  export RAILS_ENV=test RACK_ENV=test
@@ -1,4 +1,4 @@
1
- class CreateCountries < ActiveRecord::Migration
1
+ class CreateCountries < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  create_table :countries do |t|
4
4
  t.column :name, :string
@@ -1,4 +1,4 @@
1
- class CreateRoles < ActiveRecord::Migration
1
+ class CreateRoles < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  create_table :roles do |t|
4
4
  t.column :name, :string
@@ -1,6 +1,6 @@
1
- class CreateUsers < ActiveRecord::Migration
1
+ class CreateUsers < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
- create_table "users", :force => true do |t|
3
+ create_table "users", force: true do |t|
4
4
  t.column :name, :string
5
5
  end
6
6
  end
@@ -1,4 +1,4 @@
1
- class CreateCountries < ActiveRecord::Migration
1
+ class CreateCountries < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  create_table :countries do |t|
4
4
  t.column :name, :string
@@ -0,0 +1,103 @@
1
+ #!/bin/bash
2
+
3
+ case `id` in
4
+ *root*)
5
+ ;;
6
+ *)
7
+ exec echo Must be run as root
8
+ ;;
9
+ esac
10
+
11
+ chruby_version=0.3.9
12
+ chruby=chruby-${chruby_version}
13
+ set -x
14
+ set -eE -o functrace
15
+
16
+ report_failure() {
17
+ local lineno=$2
18
+ local fn=$3
19
+ local exitstatus=$4
20
+ local msg=$5
21
+ local lineno_fns=${1% 0}
22
+ if [[ $lineno_fns != "0" ]] ; then
23
+ lineno="${lineno} ${lineno_fns}"
24
+ fi
25
+ if [[ $exitstatus == 0 ]] ; then
26
+ echo "${BASH_SOURCE[1]}: Finished!"
27
+ else
28
+ echo "${BASH_SOURCE[1]}:${fn}[${lineno}] Failed with status ${exitstatus}: $msg"
29
+ fi
30
+ }
31
+
32
+ trap 'report_failure "${BASH_LINENO[*]}" "$LINENO" "${FUNCNAME[*]:-script}" "$?" "$BASH_COMMAND"' ERR
33
+
34
+
35
+ id
36
+ pwd
37
+ export DEBIAN_FRONTEND=noninteractive
38
+ find /tmp/got-apt-update -mtime -1 || ( apt-get update && touch /tmp/got-apt-update )
39
+ apt install --yes -q build-essential ruby ruby-dev sqlite3 libsqlite3-dev nodejs git git-core
40
+ apt install --yes -q gcc autoconf bison libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev
41
+ apt install --yes -q libgdbm3
42
+ # useful when debugging
43
+ apt install --yes -q silversearcher-ag vim exuberant-ctags
44
+ apt install --yes -q unattended-upgrades
45
+ unattended-upgrade
46
+ # The following is not required for testing, install if you are doing manual tests with extra gems
47
+ # apt install --yes -q mysql-client mysql-server libmysqlclient-dev
48
+ # apt install --yes -q libcurl4-openssl-dev libncurses5-dev libxml2-dev libxslt1-dev
49
+ (
50
+ echo Install chruby
51
+ [ -s ${chruby}.tar.gz ] || wget -q -O ${chruby}.tar.gz https://github.com/postmodern/chruby/archive/v${chruby_version}.tar.gz
52
+ [ -d ${chruby} ] || tar -xzf ${chruby}.tar.gz
53
+ cd ${chruby}/
54
+ ./scripts/setup.sh
55
+ cat > /etc/profile.d/chruby.sh <<'EOF'
56
+ if [ -n "$BASH_VERSION" ] || [ -n "$ZSH_VERSION" ]; then
57
+ source /usr/local/share/chruby/chruby.sh
58
+ #source /usr/local/share/chruby/auto
59
+ fi
60
+ EOF
61
+ chmod a+r /etc/profile.d/chruby.sh
62
+ )
63
+
64
+ (
65
+ [ -d ruby-build ] || git clone https://github.com/rbenv/ruby-build.git
66
+ which ruby-build || PREFIX=/usr/local ./ruby-build/install.sh
67
+
68
+ mkdir -p /opt/rubies
69
+ for v in 2.2.2
70
+ do
71
+ [ -x /opt/rubies/$v/bin/ruby ] || ( ruby-build $v /opt/rubies/$v )
72
+ [ -x /opt/rubies/${v}/bin/bundle ] || ( /opt/rubies/${v}/bin/gem install bundler -v '<2.0' )
73
+ done
74
+
75
+ for v in 2.3.8 2.4.10 2.5.9 2.5.0 2.6.6 2.6.7 2.7.1 2.7.3 3.0.1
76
+ do
77
+ [ -x /opt/rubies/$v/bin/ruby ] || ( ruby-build $v /opt/rubies/$v )
78
+ [ -x /opt/rubies/$v/bin/bundle ] || ( /opt/rubies/$v/bin/gem install bundler )
79
+ done
80
+ )
81
+
82
+ echo Setup system ruby
83
+ which bundle || gem install bundler || gem install bundler -v '<2.0'
84
+ which bundle || gem install bundler -v '< 2.0'
85
+ bundle --version
86
+ set +x
87
+ cat <<EOF
88
+
89
+ Now test by running the following commands:
90
+
91
+ vagrant ssh
92
+ cd /vagrant
93
+
94
+ chruby RUBY_VERSION
95
+ or
96
+ chruby system # for system version 2.3.1
97
+
98
+ ./test/test_with_railsapp
99
+
100
+ exit
101
+
102
+ EOF
103
+ exit
@@ -7,6 +7,8 @@ ruby RUBY_VERSION < '2.2.2' ? '2.2.2' : RUBY_VERSION
7
7
  gem 'rails', '~> 5.0.0'
8
8
  gem 'rake', '>= 0.8.7'
9
9
 
10
+ gem 'listen', '<3.1.2' # REQUIRED
11
+
10
12
  group :development, :test do
11
13
  if defined?(JRUBY_VERSION)
12
14
  gem 'jruby-openssl'
@@ -15,12 +17,13 @@ group :development, :test do
15
17
  gem 'sqlite3', "~> 1.3.7"
16
18
  end
17
19
  gem 'shoulda'
18
-
19
- # redis based checks
20
- gem 'sidekiq', :require => !ENV['SIDEKIQ'].nil?
21
- gem 'redis', :require => !ENV['REDIS_URL'].nil?
22
- gem 'resque', :require => !ENV['RESQUE'].nil?
23
- # s3 check
24
- gem 'aws-sdk', :require => !ENV['AWS_ACCESS_KEY_ID'].nil?
25
20
  end
21
+
22
+ # redis based checks
23
+ gem 'sidekiq', '~> 5.2.9', require: !ENV['SIDEKIQ'].nil? # REQUIRED
24
+ gem 'redis', '~> 4.0.3', require: !ENV['REDIS_URL'].nil? # REQUIRED
25
+ gem 'resque', '~> 1.27.4', require: !ENV['RESQUE'].nil? # REQUIRED
26
+ gem 'elasticsearch', '~> 6.3.1', require: !ENV['ELASTICSEARCH_URL'].nil? # REQUIRED
27
+ # s3 check
28
+ gem 'aws-sdk-s3', require: !ENV['AWS_ACCESS_KEY_ID'].nil? # REQUIRED
26
29
 
@@ -0,0 +1,34 @@
1
+ # Gemfile for health_test testing
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ ruby RUBY_VERSION < '2.2.2' ? '2.2.2' : RUBY_VERSION
6
+
7
+ gem 'rails', '~> 5.1.0'
8
+ gem 'rake', '>= 0.8.7'
9
+
10
+ # spring-watcher-listen was resolved to 2.0.1, which depends on
11
+ # listen was resolved to 3.1.5, which depends on
12
+ # ruby_dep
13
+ # and ruby_dep 1.5 requires 2.2.3 or later
14
+ gem 'ruby_dep', '~> 1.3.0' # REQUIRED
15
+
16
+ gem 'listen', '<3.1.2' # REQUIRED
17
+
18
+ group :development, :test do
19
+ if defined?(JRUBY_VERSION)
20
+ gem 'jruby-openssl'
21
+ gem 'activerecord-jdbcsqlite3-adapter'
22
+ else
23
+ gem 'sqlite3', "~> 1.3.7"
24
+ end
25
+ gem 'shoulda'
26
+ end
27
+
28
+ # redis based checks
29
+ gem 'sidekiq', '~> 5.2.9', require: !ENV['SIDEKIQ'].nil? # REQUIRED
30
+ gem 'redis', '~> 4.0.3', require: !ENV['REDIS_URL'].nil? # REQUIRED
31
+ gem 'resque', '~> 1.27.4', require: !ENV['RESQUE'].nil? # REQUIRED
32
+ gem 'elasticsearch', '~> 6.3.1', require: !ENV['ELASTICSEARCH_URL'].nil? # REQUIRED
33
+ # s3 check
34
+ gem 'aws-sdk', require: !ENV['AWS_ACCESS_KEY_ID'].nil? # REQUIRED
@@ -0,0 +1,34 @@
1
+ # Gemfile for health_test testing
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ ruby RUBY_VERSION < '2.2.2' ? '2.2.2' : RUBY_VERSION
6
+
7
+ gem 'rails', '~> 5.2.0'
8
+ gem 'rake', '>= 0.8.7'
9
+
10
+ # spring-watcher-listen was resolved to 2.0.1, which depends on
11
+ # listen was resolved to 3.1.5, which depends on
12
+ # ruby_dep
13
+ # and ruby_dep 1.5 requires 2.2.3 or later
14
+ gem 'ruby_dep', '~> 1.3.0' # REQUIRED
15
+
16
+ gem 'listen', '<3.1.2' # REQUIRED
17
+
18
+ group :development, :test do
19
+ if defined?(JRUBY_VERSION)
20
+ gem 'jruby-openssl'
21
+ gem 'activerecord-jdbcsqlite3-adapter'
22
+ else
23
+ gem 'sqlite3', "~> 1.3.7"
24
+ end
25
+ gem 'shoulda'
26
+ end
27
+
28
+ # redis based checks
29
+ gem 'sidekiq', '~> 5.2.9', require: !ENV['SIDEKIQ'].nil? # REQUIRED
30
+ gem 'redis', '~> 4.0.3', require: !ENV['REDIS_URL'].nil? # REQUIRED
31
+ gem 'resque', '~> 1.27.4', require: !ENV['RESQUE'].nil? # REQUIRED
32
+ gem 'elasticsearch', '~> 6.3.1', require: !ENV['ELASTICSEARCH_URL'].nil? # REQUIRED
33
+ # s3 check
34
+ gem 'aws-sdk', require: !ENV['AWS_ACCESS_KEY_ID'].nil? # REQUIRED