igp 0.0.2 → 1.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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +36 -0
- data/.gitignore +55 -0
- data/.rubocop.yml +35 -0
- data/.rubocop_todo.yml +89 -0
- data/CHANGELOG +18 -0
- data/Gemfile +2 -10
- data/Guardfile +16 -0
- data/Rakefile +11 -42
- data/bin/igp +3 -4
- data/igp.gemspec +31 -73
- data/lib/igp/base.rb +16 -20
- data/lib/igp/shell.rb +35 -34
- data/lib/igp/version.rb +1 -1
- data/lib/igp.rb +1 -0
- data/lib/net/ping/ldap.rb +105 -0
- data/spec/base_spec.rb +37 -38
- data/spec/format_spec.rb +24 -26
- data/spec/net/ping/ldap_spec.rb +193 -0
- data/spec/shell_spec.rb +72 -74
- data/spec/spec_helper.rb +4 -4
- metadata +195 -96
- data/Gemfile.lock +0 -34
- data/init.rb +0 -1
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'net/ping'
|
2
|
+
require 'net/ldap'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
# The Net module serves as a namespace only.
|
6
|
+
module Net
|
7
|
+
# The Ping::LDAP class encapsulates methods for LDAP pings.
|
8
|
+
class Ping::LDAP < Ping
|
9
|
+
# uri contains the URI object for the request
|
10
|
+
#
|
11
|
+
attr_accessor :uri
|
12
|
+
|
13
|
+
# username and password may be set for ping using
|
14
|
+
# an authenticated LDAP bind
|
15
|
+
#
|
16
|
+
attr_accessor :username
|
17
|
+
attr_accessor :password
|
18
|
+
|
19
|
+
# set/get the encryption method. By default nil,
|
20
|
+
# but may be set to :simple_tls
|
21
|
+
#
|
22
|
+
attr_reader :encryption
|
23
|
+
|
24
|
+
def encryption=(value)
|
25
|
+
@encryption = value.is_a?(Symbol) ? value : value.to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates and returns a new Ping::LDAP object.
|
29
|
+
# The default +timeout+ is 5 seconds.
|
30
|
+
#
|
31
|
+
# +uri+ string is expected to be a full URI with scheme (ldap/ldaps)
|
32
|
+
# and optionally the port (else default port is assumed) e.g.
|
33
|
+
# ldap://my.ldap.host.com
|
34
|
+
# ldap://my.ldap.host.com:1389
|
35
|
+
# ldaps://my.ldap.host.com
|
36
|
+
# ldaps://my.ldap.host.com:6636
|
37
|
+
#
|
38
|
+
# If a plain hostname is provided as the +uri+, a default port of 389 is assumed
|
39
|
+
#
|
40
|
+
def initialize(uri = nil, timeout = 5)
|
41
|
+
host, port = decode_uri(uri)
|
42
|
+
super(host, port, timeout)
|
43
|
+
end
|
44
|
+
|
45
|
+
# method used to decode uri string
|
46
|
+
#
|
47
|
+
def decode_uri(value)
|
48
|
+
@uri = URI.parse(value)
|
49
|
+
if uri.scheme =~ /ldap/
|
50
|
+
p = @port = uri.port
|
51
|
+
h = @host = uri.host
|
52
|
+
@encryption = uri.scheme == 'ldaps' ? :simple_tls : nil
|
53
|
+
else
|
54
|
+
h = value
|
55
|
+
p = 389
|
56
|
+
end
|
57
|
+
[h, p]
|
58
|
+
end
|
59
|
+
|
60
|
+
# constructs the LDAP configuration structure
|
61
|
+
#
|
62
|
+
def config
|
63
|
+
{
|
64
|
+
host: uri.host,
|
65
|
+
port: uri.port,
|
66
|
+
encryption: encryption
|
67
|
+
}.merge(
|
68
|
+
if username && password
|
69
|
+
{ auth: { method: :simple, username: username, password: password } }
|
70
|
+
else
|
71
|
+
{ auth: { method: :anonymous } }
|
72
|
+
end
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# perform ping, optionally providing the ping destination uri
|
77
|
+
#
|
78
|
+
def ping(host = nil)
|
79
|
+
decode_uri(host) if host
|
80
|
+
super(@host)
|
81
|
+
|
82
|
+
bool = false
|
83
|
+
|
84
|
+
start_time = Time.now
|
85
|
+
|
86
|
+
begin
|
87
|
+
Timeout.timeout(@timeout) do
|
88
|
+
Net::LDAP.new(config).bind
|
89
|
+
end
|
90
|
+
rescue StandardError => e
|
91
|
+
@exception = e.message
|
92
|
+
else
|
93
|
+
bool = true
|
94
|
+
end
|
95
|
+
|
96
|
+
# There is no duration if the ping failed
|
97
|
+
@duration = Time.now - start_time if bool
|
98
|
+
|
99
|
+
bool
|
100
|
+
end
|
101
|
+
|
102
|
+
alias ping? ping
|
103
|
+
alias pingecho ping
|
104
|
+
end
|
105
|
+
end
|
data/spec/base_spec.rb
CHANGED
@@ -2,65 +2,64 @@ require 'spec_helper'
|
|
2
2
|
require 'getoptions'
|
3
3
|
|
4
4
|
describe Igp::Base do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
subject.ping_handler.should be_nil
|
5
|
+
describe 'base initialization without options' do
|
6
|
+
it 'should not set ping_handler' do
|
7
|
+
expect(subject.ping_handler).to be_nil
|
9
8
|
end
|
10
|
-
it
|
11
|
-
subject.limit.
|
9
|
+
it 'should not set limit' do
|
10
|
+
expect(subject.limit).to be_nil
|
12
11
|
end
|
13
|
-
it
|
14
|
-
subject.interval.
|
12
|
+
it 'should default interval to 5 sec' do
|
13
|
+
expect(subject.interval).to eql(5)
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
|
-
describe
|
19
|
-
it
|
20
|
-
options = { :
|
16
|
+
|
17
|
+
describe 'ping_handler configuration' do
|
18
|
+
it 'should be Net::Ping::External for :icmp' do
|
19
|
+
options = { type: :icmp, host: 'localhost', port: nil }
|
21
20
|
base = Igp::Base.new(options)
|
22
|
-
base.ping_handler.
|
21
|
+
expect(base.ping_handler).to be_a(Net::Ping::External)
|
23
22
|
end
|
24
|
-
it
|
25
|
-
options = { :
|
23
|
+
it 'should be Net::Ping::UDP for :tcp' do
|
24
|
+
options = { type: :udp, host: 'localhost', port: 22 }
|
26
25
|
base = Igp::Base.new(options)
|
27
|
-
base.ping_handler.
|
26
|
+
expect(base.ping_handler).to be_a(Net::Ping::UDP)
|
28
27
|
end
|
29
|
-
it
|
30
|
-
options = { :
|
28
|
+
it 'should be Net::Ping::TCP for :tcp' do
|
29
|
+
options = { type: :tcp, host: 'localhost', port: 22 }
|
31
30
|
base = Igp::Base.new(options)
|
32
|
-
base.ping_handler.
|
31
|
+
expect(base.ping_handler).to be_a(Net::Ping::TCP)
|
33
32
|
end
|
34
|
-
it
|
35
|
-
options = { :
|
33
|
+
it 'should be Net::Ping::HTTP for :http' do
|
34
|
+
options = { type: :http, url: 'http://localhost' }
|
36
35
|
base = Igp::Base.new(options)
|
37
|
-
base.ping_handler.
|
36
|
+
expect(base.ping_handler).to be_a(Net::Ping::HTTP)
|
38
37
|
end
|
39
|
-
it
|
40
|
-
options = { :
|
38
|
+
it 'should be Net::Ping::HTTP for :https' do
|
39
|
+
options = { type: :https, url: 'https://localhost' }
|
41
40
|
base = Igp::Base.new(options)
|
42
|
-
base.ping_handler.
|
41
|
+
expect(base.ping_handler).to be_a(Net::Ping::HTTP)
|
43
42
|
end
|
44
|
-
it
|
45
|
-
options = { :
|
43
|
+
it 'should be Net::Ping::LDAP for :ldap' do
|
44
|
+
options = { type: :ldap, url: 'ldap://localhost' }
|
46
45
|
base = Igp::Base.new(options)
|
47
|
-
base.ping_handler.
|
46
|
+
expect(base.ping_handler).to be_a(Net::Ping::LDAP)
|
48
47
|
end
|
49
|
-
it
|
50
|
-
options = { :
|
48
|
+
it 'should be Net::Ping::LDAP for :ldaps' do
|
49
|
+
options = { type: :ldaps, url: 'ldaps://localhost' }
|
51
50
|
base = Igp::Base.new(options)
|
52
|
-
base.ping_handler.
|
51
|
+
expect(base.ping_handler).to be_a(Net::Ping::LDAP)
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
describe
|
55
|
+
describe '#run' do
|
57
56
|
before do
|
58
|
-
@good = Igp::Base.new({ :
|
57
|
+
@good = Igp::Base.new({ type: :icmp, host: 'localhost', port: nil, limit: 1 })
|
59
58
|
end
|
60
|
-
it
|
61
|
-
@good.formatter.
|
62
|
-
@good.formatter.
|
63
|
-
capture(:stdout
|
59
|
+
it 'should print header and log a ping result' do
|
60
|
+
expect(@good.formatter).to receive(:header)
|
61
|
+
expect(@good.formatter).to receive(:log)
|
62
|
+
capture(:stdout, :stderr) { @good.run }
|
64
63
|
end
|
65
64
|
end
|
66
|
-
end
|
65
|
+
end
|
data/spec/format_spec.rb
CHANGED
@@ -2,47 +2,45 @@ require 'spec_helper'
|
|
2
2
|
require 'getoptions'
|
3
3
|
|
4
4
|
describe Igp::Base::Format do
|
5
|
-
|
6
5
|
describe '#duration' do
|
7
|
-
it
|
8
|
-
subject.duration(nil).
|
6
|
+
it 'should return nil for nil duration' do
|
7
|
+
expect(subject.duration(nil)).to be_nil
|
9
8
|
end
|
10
|
-
it
|
9
|
+
it 'should return string to 6 decimal places for non-nil duration' do
|
11
10
|
result = subject.duration(1.0)
|
12
|
-
result.
|
13
|
-
result.to_f.
|
11
|
+
expect(result).to match(/^\d+\.\d{6}$/)
|
12
|
+
expect(result.to_f).to eql(1.0)
|
14
13
|
end
|
15
|
-
it
|
14
|
+
it 'should handle integer parameter' do
|
16
15
|
result = subject.duration(1)
|
17
|
-
result.
|
18
|
-
result.to_f.
|
16
|
+
expect(result).to match(/^\d+\.\d{6}$/)
|
17
|
+
expect(result.to_f).to eql(1.0)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
21
|
describe '#header' do
|
23
|
-
it
|
24
|
-
result = capture(:stderr){ subject.header(nil) }
|
25
|
-
result.
|
22
|
+
it 'should output a blank line for nil parameters' do
|
23
|
+
result = capture(:stderr) { subject.header(nil) }
|
24
|
+
expect(result).to eql("\n")
|
26
25
|
end
|
27
|
-
it
|
28
|
-
result = capture(:stderr){ subject.header(
|
29
|
-
result.
|
26
|
+
it 'should convert an arbitrary array of strings and numbers to a space-delimited output to stderr' do
|
27
|
+
result = capture(:stderr) { subject.header('string', 1.0, 'another string', 2.0) }
|
28
|
+
expect(result).to eql("string 1.0 another string 2.0\n")
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
32
|
describe '#log' do
|
34
|
-
it
|
35
|
-
result = capture(:stdout){ subject.log(nil) }
|
36
|
-
result.
|
33
|
+
it 'should output time only for nil parameters' do
|
34
|
+
result = capture(:stdout) { subject.log(nil) }
|
35
|
+
expect(result).to match(/^.+Z,$/)
|
37
36
|
end
|
38
|
-
it
|
39
|
-
result = capture(:stdout){ subject.log(true,1.0,nil) }
|
40
|
-
result.
|
37
|
+
it 'should log successful message (boolean,float,nil) to stdout' do
|
38
|
+
result = capture(:stdout) { subject.log(true, 1.0, nil) }
|
39
|
+
expect(result).to match(/^.+Z,true,1.0,$/)
|
41
40
|
end
|
42
|
-
it
|
43
|
-
result = capture(:stdout){ subject.log(false,nil,
|
44
|
-
result.
|
41
|
+
it 'should log unsuccessful message (boolean,nil,string) to stdout' do
|
42
|
+
result = capture(:stdout) { subject.log(false, nil, 'message') }
|
43
|
+
expect(result).to match(/^.+Z,false,,message$/)
|
45
44
|
end
|
46
45
|
end
|
47
|
-
|
48
|
-
end
|
46
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fakeldap'
|
3
|
+
|
4
|
+
describe Net::Ping::LDAP do
|
5
|
+
before :all do
|
6
|
+
@ldap_server = FakeLDAP::Server.new(port: 2389)
|
7
|
+
@ldap_server.run_tcpserver
|
8
|
+
@ldap_server.add_user('cn=el.Daper,ou=USERS,dc=example,dc=com', 'ldappassword')
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
@ldap_server.stop
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when valid ldap url' do
|
16
|
+
let(:timeout) { 30 }
|
17
|
+
let(:cn) { 'el.Daper' }
|
18
|
+
let(:password) { 'ldappassword' }
|
19
|
+
let(:uri) { 'ldap://localhost:2389' }
|
20
|
+
subject(:ldap) do
|
21
|
+
ldap = Net::Ping::LDAP.new(uri, timeout)
|
22
|
+
ldap.username = cn
|
23
|
+
ldap.password = password
|
24
|
+
ldap
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#ping' do
|
28
|
+
subject { ldap.ping }
|
29
|
+
it 'ping basic functionality' do
|
30
|
+
expect { subject }.to_not raise_error
|
31
|
+
expect(subject).to eql(true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
describe '#ping?' do
|
35
|
+
subject { ldap.ping? }
|
36
|
+
it 'returns a boolean' do
|
37
|
+
expect(subject).to eql(true)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
describe '#pingecho' do
|
41
|
+
subject { ldap.pingecho }
|
42
|
+
it 'returns a boolean' do
|
43
|
+
expect(subject).to eql(true)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
describe '#duration' do
|
47
|
+
subject { ldap.duration }
|
48
|
+
before { ldap.ping }
|
49
|
+
it 'returns a float' do
|
50
|
+
expect(subject).to be_a(Float)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when bad ldap url' do
|
56
|
+
let(:uri) { 'ldap://blabfoobarurghxxxx.com' }
|
57
|
+
subject(:ldap) { Net::Ping::LDAP.new(uri) }
|
58
|
+
describe '#ping' do
|
59
|
+
subject { ldap.ping }
|
60
|
+
it 'ping basic functionality' do
|
61
|
+
expect { subject }.to_not raise_error
|
62
|
+
expect(subject).to eql(false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
describe '#ping?' do
|
66
|
+
subject { ldap.ping? }
|
67
|
+
it 'returns a boolean' do
|
68
|
+
expect(subject).to eql(false)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
describe '#pingecho' do
|
72
|
+
subject { ldap.pingecho }
|
73
|
+
it 'returns a boolean' do
|
74
|
+
expect(subject).to eql(false)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
describe '#duration' do
|
78
|
+
subject { ldap.duration }
|
79
|
+
before { ldap.ping }
|
80
|
+
it 'returns nil' do
|
81
|
+
expect(subject).to be_nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# test 'host attribute basic functionality' do
|
87
|
+
# assert_respond_to(@ldap, :host)
|
88
|
+
# assert_respond_to(@ldap, :host=)
|
89
|
+
# assert_equal(@@host, @ldap.host)
|
90
|
+
# end
|
91
|
+
|
92
|
+
# test 'port attribute basic functionality' do
|
93
|
+
# assert_respond_to(@ldap, :port)
|
94
|
+
# assert_respond_to(@ldap, :port=)
|
95
|
+
# end
|
96
|
+
|
97
|
+
# test 'port attribute expected value' do
|
98
|
+
# assert_equal(@@port, @ldap.port)
|
99
|
+
# end
|
100
|
+
|
101
|
+
# test 'timeout attribute basic functionality' do
|
102
|
+
# assert_respond_to(@ldap, :timeout)
|
103
|
+
# assert_respond_to(@ldap, :timeout=)
|
104
|
+
# end
|
105
|
+
|
106
|
+
# test 'timeout attribute expected values' do
|
107
|
+
# assert_equal(@@timeout, @ldap.timeout)
|
108
|
+
# assert_equal(5, @bad.timeout)
|
109
|
+
# end
|
110
|
+
|
111
|
+
# test 'exception attribute basic functionality' do
|
112
|
+
# assert_respond_to(@ldap, :exception)
|
113
|
+
# assert_nil(@ldap.exception)
|
114
|
+
# end
|
115
|
+
|
116
|
+
# test 'exception attribute is nil if the ping is successful' do
|
117
|
+
# assert_true(@ldap.ping)
|
118
|
+
# assert_nil(@ldap.exception)
|
119
|
+
# end
|
120
|
+
|
121
|
+
# test 'exception attribute is not nil if the ping is unsuccessful' do
|
122
|
+
# assert_false(@bad.ping)
|
123
|
+
# assert_not_nil(@bad.exception)
|
124
|
+
# end
|
125
|
+
|
126
|
+
# test 'warning attribute basic functionality' do
|
127
|
+
# assert_respond_to(@ldap, :warning)
|
128
|
+
# assert_nil(@ldap.warning)
|
129
|
+
# end
|
130
|
+
|
131
|
+
# test 'uri attribute basic functionality' do
|
132
|
+
# assert_respond_to(@ldap, :uri)
|
133
|
+
# assert_respond_to(@ldap, :uri=)
|
134
|
+
# end
|
135
|
+
|
136
|
+
# test 'username attribute basic functionality' do
|
137
|
+
# assert_respond_to(@ldap, :username)
|
138
|
+
# assert_respond_to(@ldap, :username=)
|
139
|
+
# end
|
140
|
+
|
141
|
+
# test 'password attribute basic functionality' do
|
142
|
+
# assert_respond_to(@ldap, :password)
|
143
|
+
# assert_respond_to(@ldap, :password=)
|
144
|
+
# end
|
145
|
+
|
146
|
+
# test 'encryption attribute basic functionality' do
|
147
|
+
# assert_respond_to(@ldap, :encryption)
|
148
|
+
# assert_respond_to(@ldap, :encryption=)
|
149
|
+
# end
|
150
|
+
|
151
|
+
# test 'encryption defaults to nil for ldap' do
|
152
|
+
# assert_nil(Net::Ping::LDAP.new('ldap://somehost.example.net').encryption)
|
153
|
+
# end
|
154
|
+
|
155
|
+
# test 'encryption defaults to simple_tls for ldaps' do
|
156
|
+
# assert_equal(:simple_tls, Net::Ping::LDAP.new('ldaps://somehost.example.net').encryption)
|
157
|
+
# end
|
158
|
+
|
159
|
+
# test 'port defaults to 389 for ldap' do
|
160
|
+
# assert_equal(389, Net::Ping::LDAP.new('ldap://somehost.example.net').port)
|
161
|
+
# end
|
162
|
+
|
163
|
+
# test 'port defaults to 636 for ldaps' do
|
164
|
+
# assert_equal(636, Net::Ping::LDAP.new('ldaps://somehost.example.net').port)
|
165
|
+
# end
|
166
|
+
|
167
|
+
# test 'port extracted from uri if provided' do
|
168
|
+
# assert_equal(12345, Net::Ping::LDAP.new('ldap://somehost.example.net:12345').port)
|
169
|
+
# assert_equal(12345, Net::Ping::LDAP.new('ldaps://somehost.example.net:12345').port)
|
170
|
+
# end
|
171
|
+
|
172
|
+
# test 'encryption setting is forced to symbol' do
|
173
|
+
# @ldap.encryption = 'simple_tls'
|
174
|
+
# assert_true( @ldap.encryption.is_a? Symbol )
|
175
|
+
# assert_true( @ldap.config[:encryption].is_a? Symbol )
|
176
|
+
# end
|
177
|
+
|
178
|
+
# test 'username/password set in config auth section' do
|
179
|
+
# @ldap.username, @ldap.password = 'fred', 'derf'
|
180
|
+
# assert_equal('fred', @ldap.config[:auth][:username] )
|
181
|
+
# assert_equal('derf', @ldap.config[:auth][:password] )
|
182
|
+
# end
|
183
|
+
|
184
|
+
# test 'auth method defaults to simple if username/password set' do
|
185
|
+
# @ldap.username, @ldap.password = 'fred', 'derf'
|
186
|
+
# assert_equal(:simple, @ldap.config[:auth][:method] )
|
187
|
+
# end
|
188
|
+
|
189
|
+
# test 'if no username/password then defaults to auth anonymous' do
|
190
|
+
# @ldap.username = @ldap.password = nil
|
191
|
+
# assert_equal({:method => :anonymous}, @ldap.config[:auth] )
|
192
|
+
# end
|
193
|
+
end
|