rubicante 0.0.3 → 0.0.4
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.
- data/History.txt +4 -0
- data/Manifest.txt +17 -0
- data/lib/rubicante.rb +1 -1
- data/lib/rubicante/host.rb +183 -0
- data/lib/rubicante/host_error.rb +22 -0
- data/lib/rubicante/host_group.rb +18 -0
- data/lib/rubicante/type.rb +20 -0
- data/lib/rubicante/type_group.rb +18 -0
- data/lib/rubicante/website.rb +54 -0
- data/lib/rubicante/website_error.rb +10 -0
- data/spec/environment_spec.rb +84 -0
- data/spec/helper.rb +3 -0
- data/spec/host_error_spec.rb +71 -0
- data/spec/host_group_spec.rb +33 -0
- data/spec/host_spec.rb +159 -0
- data/spec/type_group_spec.rb +35 -0
- data/spec/type_spec.rb +42 -0
- data/spec/website_error_spec.rb +35 -0
- data/spec/website_spec.rb +53 -0
- metadata +18 -1
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -8,3 +8,20 @@ lib/os_functions.rb
|
|
8
8
|
lib/rubicante.rb
|
9
9
|
lib/rubicante/cli.rb
|
10
10
|
lib/rubicante/environment.rb
|
11
|
+
lib/rubicante/host.rb
|
12
|
+
lib/rubicante/host_error.rb
|
13
|
+
lib/rubicante/host_group.rb
|
14
|
+
lib/rubicante/type.rb
|
15
|
+
lib/rubicante/type_group.rb
|
16
|
+
lib/rubicante/website.rb
|
17
|
+
lib/rubicante/website_error.rb
|
18
|
+
spec/environment_spec.rb
|
19
|
+
spec/helper.rb
|
20
|
+
spec/host_error_spec.rb
|
21
|
+
spec/host_group_spec.rb
|
22
|
+
spec/host_spec.rb
|
23
|
+
spec/type_group_spec.rb
|
24
|
+
spec/type_spec.rb
|
25
|
+
spec/website_error_spec.rb
|
26
|
+
spec/website_spec.rb
|
27
|
+
test/test_rubicante.rb
|
data/lib/rubicante.rb
CHANGED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'rubicante/website'
|
2
|
+
require 'rubicante/host_error'
|
3
|
+
|
4
|
+
require 'logging'
|
5
|
+
require 'ping'
|
6
|
+
require 'socket'
|
7
|
+
|
8
|
+
require 'os_functions'
|
9
|
+
include OsFunctions
|
10
|
+
require 'win32ole' if is_windows?
|
11
|
+
|
12
|
+
module Rubicante
|
13
|
+
class Host
|
14
|
+
include OsFunctions
|
15
|
+
|
16
|
+
attr_reader :name
|
17
|
+
attr_accessor :ports, :services, :types, :websites
|
18
|
+
|
19
|
+
def initialize(name)
|
20
|
+
@name = name
|
21
|
+
@ports = []
|
22
|
+
@services = []
|
23
|
+
@types = []
|
24
|
+
@websites = []
|
25
|
+
|
26
|
+
@log = Logging::Logger[self]
|
27
|
+
|
28
|
+
# Prepare Website logger
|
29
|
+
@appender = Logging::Appender['rubicante']
|
30
|
+
Logging::Logger['Rubicante::Website'].add_appenders(Logging::Appender['rubicante']) if not @appender.nil?
|
31
|
+
Logging::Logger['Rubicante::Website'].level = @log.level
|
32
|
+
end
|
33
|
+
|
34
|
+
def ping
|
35
|
+
@log.debug "Performing TCP echo ping on host '#{@name}'"
|
36
|
+
Ping.pingecho @name
|
37
|
+
end
|
38
|
+
|
39
|
+
def port(port_number)
|
40
|
+
@ports << port_number
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def service(service_name)
|
45
|
+
@services << service_name
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def type(type_name)
|
50
|
+
@types << type_name
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def website(website_url)
|
55
|
+
@websites << Website.new(website_url)
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check if the specified port is active by connecting to it
|
60
|
+
def check_port(port)
|
61
|
+
port_output = "#{@name}:#{port}"
|
62
|
+
|
63
|
+
@log.debug "Checking port #{port_output}..."
|
64
|
+
|
65
|
+
begin
|
66
|
+
test = TCPSocket.open(@name, port)
|
67
|
+
@log.debug "Port #{port_output} looks good"
|
68
|
+
return true # if we get here, the socket opened
|
69
|
+
rescue
|
70
|
+
@log.debug "Port #{port_output} raised an exception when opening"
|
71
|
+
return false # if we get here, there are problems with the port
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Iterates through all the ports in the Host and runs check_port(port)
|
76
|
+
# against them.
|
77
|
+
#
|
78
|
+
# == Yields: port, is_alive
|
79
|
+
#
|
80
|
+
# Each registered port is yielded along with the boolean result from
|
81
|
+
# check_port(port).
|
82
|
+
#
|
83
|
+
# == Example:
|
84
|
+
#
|
85
|
+
# host = Rubicante::Host.new("test-host")
|
86
|
+
# host.port(80)
|
87
|
+
# host.port(443)
|
88
|
+
#
|
89
|
+
# host.check_ports do |port, response|
|
90
|
+
# puts "Port #{port} is UP" if response
|
91
|
+
# puts "Port #{port} is DOWN" if not response
|
92
|
+
# end
|
93
|
+
def check_ports
|
94
|
+
@ports.each do |port|
|
95
|
+
yield port, check_port(port)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Iterates through all the websites in the Host and runs
|
100
|
+
# wrong? against them looking for problems. If a problem is
|
101
|
+
# found, a Hash of the URL and the HTTP Status code is yielded.
|
102
|
+
#
|
103
|
+
# == Yields: a Hash
|
104
|
+
#
|
105
|
+
# {
|
106
|
+
# :url => String, # the URL of the current website in the block
|
107
|
+
# :code => String # the HTTP Status code of the check (i.e., 404, 500, etc.)
|
108
|
+
# }
|
109
|
+
#
|
110
|
+
# == Example
|
111
|
+
#
|
112
|
+
# host = Rubicante::Host.new("test-host")
|
113
|
+
# host.website('www.exmaple.com')
|
114
|
+
# host.website('www.rubicante.com')
|
115
|
+
# host.website('www.openbsd.org')
|
116
|
+
#
|
117
|
+
# host.check_websites do |result|
|
118
|
+
# puts "Website #{result[:url]} failed with code #{result[:code]}!"
|
119
|
+
# end
|
120
|
+
def check_websites
|
121
|
+
@log.debug "Checking websites registered to host '#{@name}'"
|
122
|
+
@websites.each do |website|
|
123
|
+
yield website.wrong?
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def wrong?
|
128
|
+
@log.debug "Determing what is wrong with host '#{@name}'"
|
129
|
+
result = HostError.new(@name)
|
130
|
+
result.ping = self.ping
|
131
|
+
|
132
|
+
# If the host is alive, continue testing
|
133
|
+
if result.ping
|
134
|
+
check_ports do |port, response|
|
135
|
+
result.bad_ports << port if not response
|
136
|
+
end
|
137
|
+
|
138
|
+
check_websites do |website_error|
|
139
|
+
result.add(website_error)
|
140
|
+
end
|
141
|
+
|
142
|
+
if is_windows?
|
143
|
+
check_services do |service, response|
|
144
|
+
result.bad_services << service if not response
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
return result
|
150
|
+
end
|
151
|
+
|
152
|
+
###
|
153
|
+
# Windows-specific functions
|
154
|
+
###
|
155
|
+
if is_windows?
|
156
|
+
def get_wmi
|
157
|
+
WIN32OLE.connect("winmgmts://#{@name}")
|
158
|
+
end
|
159
|
+
|
160
|
+
# Checks the host to see if the specified service is running
|
161
|
+
def is_running?(service)
|
162
|
+
query = "SELECT Name, State FROM Win32_Service WHERE Name='#{service}'"
|
163
|
+
|
164
|
+
result = false
|
165
|
+
service_label = "#{@name}->#{service}"
|
166
|
+
|
167
|
+
@log.debug "Checking services #{service_label}..."
|
168
|
+
get_wmi.ExecQuery(query).each do |result|
|
169
|
+
@log.debug "#{service_label}.State == #{result.State}"
|
170
|
+
result = true if result.State = 'Running'
|
171
|
+
end
|
172
|
+
|
173
|
+
return result
|
174
|
+
end
|
175
|
+
|
176
|
+
def check_services
|
177
|
+
@services.each do |service|
|
178
|
+
yield service, is_running?(service)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubicante/website_error'
|
2
|
+
|
3
|
+
module Rubicante
|
4
|
+
class HostError
|
5
|
+
attr_reader :hostname, :website_errors
|
6
|
+
attr_accessor :bad_ports, :bad_services, :ping
|
7
|
+
|
8
|
+
def initialize(hostname)
|
9
|
+
@hostname = hostname
|
10
|
+
@ping = false
|
11
|
+
@bad_ports = []
|
12
|
+
@bad_services = []
|
13
|
+
@website_errors = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(error)
|
17
|
+
if error.kind_of? WebsiteError
|
18
|
+
@website_errors << error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'rubicante/host'
|
3
|
+
|
4
|
+
module Rubicante
|
5
|
+
class HostGroup
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
attr_reader :hosts
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@hosts = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](hostname)
|
15
|
+
@hosts[hostname] ||= Host.new(hostname)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rubicante
|
2
|
+
class Type
|
3
|
+
attr_reader :name
|
4
|
+
attr_accessor :ports, :services
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@ports = []
|
9
|
+
@services = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def port(new_port)
|
13
|
+
@ports << new_port
|
14
|
+
end
|
15
|
+
|
16
|
+
def service(new_service)
|
17
|
+
@services << new_service
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'rubicante/type'
|
3
|
+
|
4
|
+
module Rubicante
|
5
|
+
class TypeGroup
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
attr_accessor :types
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@types = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](type_name)
|
15
|
+
@types[type_name] ||= Type.new(type_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubicante/website_error'
|
2
|
+
|
3
|
+
require 'logging'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module Rubicante
|
7
|
+
class Website
|
8
|
+
attr_reader :url
|
9
|
+
|
10
|
+
def initialize(url)
|
11
|
+
@url = url
|
12
|
+
|
13
|
+
@log = Logging::Logger[self]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Determines whether or not the site OK based on the HTTP Status code
|
17
|
+
#
|
18
|
+
# == DETERMINING IF A SITE IS OK
|
19
|
+
#
|
20
|
+
# When performing an HTTP GET on the root, if a 2xx (HTTP OK) or
|
21
|
+
# 3xx (HTTP Redirect) response is received, the method considers the
|
22
|
+
# site to be workinging nominally and returns *true*
|
23
|
+
#
|
24
|
+
# However, if a 4xx (HTTP Client Error) or 5xx (HTTP Server Error)
|
25
|
+
# response is received, the method considers the site to be working
|
26
|
+
# abnormally and returns *false*
|
27
|
+
def is_ok?
|
28
|
+
result = false
|
29
|
+
|
30
|
+
result = true if response_code.match(/^(2|3)/)
|
31
|
+
|
32
|
+
return result
|
33
|
+
end
|
34
|
+
|
35
|
+
# Performs and HTTP GET on the URL's root ('/') and returns the
|
36
|
+
# HTTP Status code
|
37
|
+
def response_code
|
38
|
+
@log.debug "Retreiving HTTP Code for website '#{@url}'"
|
39
|
+
result = Net::HTTP.get_response(@url, '/').code
|
40
|
+
@log.debug "Received HTTP Code #{result} for website '#{@url}'"
|
41
|
+
|
42
|
+
return result
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks to see if the site is OK. If it is not, it returns
|
46
|
+
# a Rubicante::WebsiteError
|
47
|
+
def wrong?
|
48
|
+
@log.debug "Checking website '#{@url}' for problems"
|
49
|
+
if not self.is_ok?
|
50
|
+
WebsiteError.new(@url, self.response_code)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/environment"
|
3
|
+
|
4
|
+
describe "A Rubicante environment" do
|
5
|
+
before :all do
|
6
|
+
Net::HTTP.stub!(:get_response).and_return(Net::HTTPServerError.new('1', '500', 'Internal Server Error'))
|
7
|
+
end
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
@env = Rubicante::Environment.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should exist" do
|
14
|
+
@env.should_not be_nil
|
15
|
+
@env.should be_an_instance_of(Rubicante::Environment)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have a HostGroup" do
|
19
|
+
@env.host.should be_an_instance_of(Rubicante::HostGroup)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have an empty HostGroup by default" do
|
23
|
+
@env.host.hosts.should == {}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have a wrong? method" do
|
27
|
+
@env.respond_to?('wrong?').should == true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return an array of HostErrors" do
|
31
|
+
@env.wrong? do |result|
|
32
|
+
result.should be_an_instance_of(Array)
|
33
|
+
result[0].should be_an_instance_of(Rubicante::HostError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have an eval_host method" do
|
38
|
+
@env.respond_to?('eval_host').should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should handle 'Host webservice provides website ...'" do
|
42
|
+
hostname = 'webservice'
|
43
|
+
url = 'www.rubicante-example.com'
|
44
|
+
cmd = "Host #{hostname} provides website #{url}"
|
45
|
+
@env.eval_host(cmd)
|
46
|
+
@env.host[hostname].websites[0].url.should == url
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should handle specifying multiple websites" do
|
50
|
+
hostname = 'www2'
|
51
|
+
url0 = 'test1'
|
52
|
+
url1 = 'test2'
|
53
|
+
cmd = "Host #{hostname} provides website #{url0}, provides website #{url1}"
|
54
|
+
@env.eval_host(cmd)
|
55
|
+
@env.host[hostname].websites[0].url.should == url0
|
56
|
+
@env.host[hostname].websites[1].url.should == url1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have an eval_command method" do
|
60
|
+
@env.respond_to?('eval_command').should == true
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should raise a NotImplementedError for unknown commands" do
|
64
|
+
lambda { @env.eval_command('whumpus frumpus') }.should raise_error(NotImplementedError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should handle 'host' commands" do
|
68
|
+
lambda { @env.eval_command('host frank') }.should_not raise_error(NotImplementedError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have an eval_what method" do
|
72
|
+
@env.respond_to?('eval_what').should == true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should handle 'what' commands" do
|
76
|
+
lambda { @env.eval_command('What is wrong') }.should_not raise_error(NotImplementedError)
|
77
|
+
end
|
78
|
+
|
79
|
+
after :each do
|
80
|
+
# Clean up the HostGroup instance's hash so that other specs will
|
81
|
+
# run properly
|
82
|
+
@env.host.hosts.clear
|
83
|
+
end
|
84
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/host_error"
|
3
|
+
|
4
|
+
describe "An error with a host" do
|
5
|
+
before :all do
|
6
|
+
@url = "http://www.rubicante-example.com/"
|
7
|
+
@code = "500"
|
8
|
+
@website_error = Rubicante::WebsiteError.new(@url, @code)
|
9
|
+
end
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
@host_error = Rubicante::HostError.new("test-host")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should exist" do
|
16
|
+
@host_error.should_not be_nil
|
17
|
+
@host_error.should be_an_instance_of(Rubicante::HostError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should require an argument at initialization" do
|
21
|
+
lambda { Rubicante::HostError.new }.should raise_error(ArgumentError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should now allow changing of hostname after initialization" do
|
25
|
+
lambda { @host_error.hostname = "new-host-name" }.should raise_error(NoMethodError)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have an empty array of website errors" do
|
29
|
+
@host_error.website_errors.should == []
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should allow adding of new website errors with add" do
|
33
|
+
@host_error.add(@website_error)
|
34
|
+
@host_error.website_errors.include?(@website_error).should == true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have an ping value" do
|
38
|
+
@host_error.respond_to?('ping').should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "ping should be false by default" do
|
42
|
+
@host_error.ping.should == false
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should allow changin the ping value" do
|
46
|
+
@new_ping = true
|
47
|
+
@host_error.ping.should_not == @new_ping
|
48
|
+
@host_error.ping = @new_ping
|
49
|
+
@host_error.ping.should == @new_ping
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should have an empty array of bad_ports by default" do
|
53
|
+
@host_error.bad_ports.should == []
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should allow appending to bad_ports" do
|
57
|
+
new_bad_port = 80
|
58
|
+
@host_error.bad_ports << new_bad_port
|
59
|
+
@host_error.bad_ports.include?(new_bad_port).should == true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have an empty array of bad_services by default" do
|
63
|
+
@host_error.bad_services.should == []
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should allow appending to bad_services" do
|
67
|
+
new_bad_service = 'W32Time'
|
68
|
+
@host_error.bad_services << new_bad_service
|
69
|
+
@host_error.bad_services.include?(new_bad_service).should == true
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/host_group"
|
3
|
+
|
4
|
+
describe "A group of hosts" do
|
5
|
+
before :each do
|
6
|
+
@host_group = Rubicante::HostGroup.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should exist" do
|
10
|
+
@host_group.should_not be_nil
|
11
|
+
@host_group.should be_an_instance_of(Rubicante::HostGroup)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have an empty hash of hosts by default" do
|
15
|
+
@host_group.hosts.should == {}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should create a new host in hosts if it doesn't exist" do
|
19
|
+
hostname = "new-host"
|
20
|
+
@host_group[hostname].name.should == hostname
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should allow for modifying previously defined hosts" do
|
24
|
+
hostname = "new-host"
|
25
|
+
new_port = 80
|
26
|
+
new_service = "new-service"
|
27
|
+
|
28
|
+
@host_group[hostname].port(new_port).service(new_service)
|
29
|
+
|
30
|
+
@host_group[hostname].ports.include?(new_port).should == true
|
31
|
+
@host_group[hostname].services.include?(new_service).should == true
|
32
|
+
end
|
33
|
+
end
|
data/spec/host_spec.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/host"
|
3
|
+
|
4
|
+
describe "A newtork host" do
|
5
|
+
before :each do
|
6
|
+
@host_name = "spec-host"
|
7
|
+
@host = Rubicante::Host.new(@host_name)
|
8
|
+
|
9
|
+
@host_with_sites = Rubicante::Host.new(@host_name)
|
10
|
+
@sites = [
|
11
|
+
'www.rubicante-good-site.com',
|
12
|
+
'www.rubicante-bad-site.com',
|
13
|
+
'www.rubicante-worse-site.com',
|
14
|
+
'www.rubicante-redirect.com'
|
15
|
+
]
|
16
|
+
@sites.each do |site|
|
17
|
+
@host_with_sites.website(site)
|
18
|
+
end
|
19
|
+
|
20
|
+
@host_with_ports = Rubicante::Host.new(@host_name)
|
21
|
+
@ports = [80, 22, 443]
|
22
|
+
@ports.each do |port|
|
23
|
+
@host_with_ports.port(port)
|
24
|
+
end
|
25
|
+
|
26
|
+
Net::HTTP.stub!(:get_response).and_return(Net::HTTPServerError.new('1', '500', 'Internal Server Error'))
|
27
|
+
Ping.stub!(:pingecho).and_return(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should exist" do
|
31
|
+
@host.should_not be_nil
|
32
|
+
@host.should be_an_instance_of(Rubicante::Host)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should require a name parameter for initialization" do
|
36
|
+
lambda { Host.new.should raise_error(ArgumentError) }
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have an empty array of ports by default" do
|
40
|
+
@host.ports.should == []
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should allow adding more ports with port()" do
|
44
|
+
port = 12345
|
45
|
+
@host.port(port)
|
46
|
+
@host.ports.include?(port).should == true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return self for port()" do
|
50
|
+
@host.port(12345).should be_an_instance_of(Rubicante::Host)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have an empty array of services by default" do
|
54
|
+
@host.services.should == []
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should allow adding more services with service()" do
|
58
|
+
service = "W32Time"
|
59
|
+
@host.service(service)
|
60
|
+
@host.services.include?(service).should == true
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return self for service()" do
|
64
|
+
@host.service("test").should be_an_instance_of(Rubicante::Host)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have an empty array of types" do
|
68
|
+
@host.types.should == []
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should allow adding more types with type()" do
|
72
|
+
type = "SQL Server"
|
73
|
+
@host.type(type)
|
74
|
+
@host.types.include?(type).should == true
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should return self for type()" do
|
78
|
+
@host.type("testing").should be_an_instance_of(Rubicante::Host)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have an empty array of websites by default" do
|
82
|
+
@host.websites.should == []
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should allow adding more webistes with site()" do
|
86
|
+
url = "http://www.example.com/"
|
87
|
+
@host.website(url)
|
88
|
+
@host.websites.size.should == 1
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return self for site()" do
|
92
|
+
@host.website("http://www.example.com/").should be_an_instance_of(Rubicante::Host)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should check all websites" do
|
96
|
+
@host_with_sites.check_websites do |result|
|
97
|
+
@sites.include?(result.url).should == true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return a HostError for wrong?" do
|
102
|
+
@host.wrong?.should be_an_instance_of(Rubicante::HostError)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should return website errors with the HostError" do
|
106
|
+
host_error = @host.wrong?
|
107
|
+
|
108
|
+
host_error.website_errors.should_not be_nil
|
109
|
+
host_error.website_errors.each do |website_error|
|
110
|
+
website_error.should be_an_instance_of(Rubicante::WebsiteError)
|
111
|
+
@sites.include?(website_error.url).should == true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should support pinging" do
|
116
|
+
@host.respond_to?('ping').should == true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should update HostError.ping to true for alive hosts" do
|
120
|
+
host_error = @host.wrong?
|
121
|
+
host_error.ping.should == true
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should update HostError.ping to false for down hosts" do
|
125
|
+
Ping.stub!(:pingecho).and_return(false)
|
126
|
+
host_error = @host.wrong?
|
127
|
+
host_error.ping.should == false
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should skip website processing for downed hosts" do
|
131
|
+
Ping.stub!(:pingecho).and_return(false)
|
132
|
+
host_error = @host_with_sites.wrong?
|
133
|
+
host_error.ping.should == false
|
134
|
+
host_error.website_errors.should == []
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should check a specified port" do
|
138
|
+
@host.respond_to?('check_port').should == true
|
139
|
+
TCPSocket.stub!(:open).and_return(true)
|
140
|
+
@host.check_port(80).should == true
|
141
|
+
TCPSocket.stub!(:open).and_raise(ArgumentError)
|
142
|
+
@host.check_port(443).should == false
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should check all registered ports" do
|
146
|
+
TCPSocket.stub!(:open).and_raise(ArgumentError)
|
147
|
+
@host_with_ports.check_ports do |port, is_alive|
|
148
|
+
@ports.include?(port).should == true
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should update HostError.bad_ports for all down ports" do
|
153
|
+
TCPSocket.stub!(:open).and_raise(ArgumentError)
|
154
|
+
host_error = @host_with_ports.wrong?
|
155
|
+
host_error.bad_ports.each do |bad_port|
|
156
|
+
@ports.include?(bad_port).should == true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/type_group"
|
3
|
+
|
4
|
+
describe "A group of server types" do
|
5
|
+
before :each do
|
6
|
+
@type_group = Rubicante::TypeGroup.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should exist" do
|
10
|
+
@type_group.should_not be_nil
|
11
|
+
@type_group.should be_an_instance_of(Rubicante::TypeGroup)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have an empty hash of types by default" do
|
15
|
+
@type_group.types.should == {}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should create a new type in types if it doesn't exist" do
|
19
|
+
type_name = "new-type"
|
20
|
+
@type_group[type_name].name.should == type_name
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should allow for modifying previously defined types" do
|
24
|
+
type_name = "new-type"
|
25
|
+
new_port = 80
|
26
|
+
new_service = "new-service"
|
27
|
+
@type_group[type_name]
|
28
|
+
|
29
|
+
@type_group[type_name].port(new_port)
|
30
|
+
@type_group[type_name].ports.include?(new_port).should == true
|
31
|
+
|
32
|
+
@type_group[type_name].service(new_service)
|
33
|
+
@type_group[type_name].services.include?(new_service).should == true
|
34
|
+
end
|
35
|
+
end
|
data/spec/type_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/type"
|
3
|
+
|
4
|
+
describe "A server type" do
|
5
|
+
before :each do
|
6
|
+
@type_name = "spec-type"
|
7
|
+
@type = Rubicante::Type.new(@type_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should exist" do
|
11
|
+
@type.should_not be_nil
|
12
|
+
@type.should be_an_instance_of(Rubicante::Type)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should require a name when initializing" do
|
16
|
+
lambda { @new_type = Rubicante::Type.new }.should raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have a name" do
|
20
|
+
@type.name.should == @type_name
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have an empty array of ports by default" do
|
24
|
+
@type.ports.should == []
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have an empty array of services by default" do
|
28
|
+
@type.services.should == []
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow appending of ports" do
|
32
|
+
new_port = 80
|
33
|
+
@type.port(new_port)
|
34
|
+
@type.ports.include?(new_port).should == true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should allow appending of services" do
|
38
|
+
new_service = "W32Time"
|
39
|
+
@type.service(new_service)
|
40
|
+
@type.services.include?(new_service).should == true
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/website_error"
|
3
|
+
|
4
|
+
describe "An error with a website" do
|
5
|
+
before :each do
|
6
|
+
@url = "http://www.rubicante-example.com/"
|
7
|
+
@code = "500"
|
8
|
+
@website_error = Rubicante::WebsiteError.new(@url, @code)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should exist" do
|
12
|
+
@website_error.should_not be_nil
|
13
|
+
@website_error.should be_an_instance_of(Rubicante::WebsiteError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should require parameters to be created" do
|
17
|
+
lambda { Rubicante::WebsiteError.new }.should raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have a URL" do
|
21
|
+
@website_error.url.should == @url
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have an HTTP code" do
|
25
|
+
@website_error.code.should == @code
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not allow modification to the URL" do
|
29
|
+
lambda { @website_error.url = "http://www.rubyforge-example.org/" }.should raise_error(NoMethodError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not allow modification to the HTTP code" do
|
33
|
+
lambda { @website_error.code = "301" }.should raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
|
2
|
+
require "#{LIB_DIR}/website"
|
3
|
+
|
4
|
+
describe "A website" do
|
5
|
+
before :each do
|
6
|
+
@url = 'http://www.rubicante-test.com/'
|
7
|
+
@website = Rubicante::Website.new(@url)
|
8
|
+
|
9
|
+
@http_ok = Net::HTTPOK.new('1', '200', 'OK')
|
10
|
+
@http_redirect = Net::HTTPMovedPermanently.new('1', '301', 'Moved Permanently')
|
11
|
+
@http_client_error = Net::HTTPNotFound.new('1', '404', 'File Not Found')
|
12
|
+
@http_server_error = Net::HTTPInternalServerError.new('1', '500', 'Internal Server Error')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should exist" do
|
16
|
+
@website.should_not be_nil
|
17
|
+
@website.should be_an_instance_of(Rubicante::Website)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should require a name parameter for initialization" do
|
21
|
+
lambda { Website.new.should raise_error(ArgumentError) }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return the HTTP code number for a site" do
|
25
|
+
Net::HTTP.stub!(:get_response).and_return(@http_redirect)
|
26
|
+
@website.response_code.should == "301"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return true for good websites" do
|
30
|
+
Net::HTTP.stub!(:get_response).and_return(@http_ok)
|
31
|
+
@website.is_ok?.should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return true for redirected websites" do
|
35
|
+
Net::HTTP.stub!(:get_response).and_return(@http_redirect)
|
36
|
+
@website.is_ok?.should == true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return false for websites having problems" do
|
40
|
+
Net::HTTP.stub!(:get_response).and_return(@http_server_error)
|
41
|
+
@website.is_ok?.should == false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return false for missing files" do
|
45
|
+
Net::HTTP.stub!(:get_response).and_return(@http_client_error)
|
46
|
+
@website.is_ok?.should == false
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return a WebsiteError for bad sites" do
|
50
|
+
Net::HTTP.stub!(:get_response).and_return(@http_server_error)
|
51
|
+
@website.wrong?.should be_an_instance_of(Rubicante::WebsiteError)
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubicante
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam VanderHook
|
@@ -64,6 +64,23 @@ files:
|
|
64
64
|
- lib/rubicante.rb
|
65
65
|
- lib/rubicante/cli.rb
|
66
66
|
- lib/rubicante/environment.rb
|
67
|
+
- lib/rubicante/host.rb
|
68
|
+
- lib/rubicante/host_error.rb
|
69
|
+
- lib/rubicante/host_group.rb
|
70
|
+
- lib/rubicante/type.rb
|
71
|
+
- lib/rubicante/type_group.rb
|
72
|
+
- lib/rubicante/website.rb
|
73
|
+
- lib/rubicante/website_error.rb
|
74
|
+
- spec/environment_spec.rb
|
75
|
+
- spec/helper.rb
|
76
|
+
- spec/host_error_spec.rb
|
77
|
+
- spec/host_group_spec.rb
|
78
|
+
- spec/host_spec.rb
|
79
|
+
- spec/type_group_spec.rb
|
80
|
+
- spec/type_spec.rb
|
81
|
+
- spec/website_error_spec.rb
|
82
|
+
- spec/website_spec.rb
|
83
|
+
- test/test_rubicante.rb
|
67
84
|
has_rdoc: true
|
68
85
|
homepage: RubyForge http://rubicante.rubyforge.org
|
69
86
|
post_install_message:
|