xlogin 0.6.31 → 0.7.2
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 +4 -4
- data/lib/xlogin/cli.rb +1 -2
- data/lib/xlogin/factory.rb +25 -7
- data/lib/xlogin/rake_task.rb +1 -0
- data/lib/xlogin/session.rb +88 -33
- data/lib/xlogin/telnet.rb +4 -4
- data/lib/xlogin/template.rb +3 -3
- data/lib/xlogin/version.rb +1 -1
- data/lib/xlogin.rb +20 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e52a4f4381c261ea82398f6a6d149b4fd13dd5b7
|
4
|
+
data.tar.gz: f917f99d366e5987dd64927864e4e19b62bbad54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab506f21664b25a45e6af2495ae0086d1b6ec0f13e55470e1464af88abc8813708ed5d0dcb87f1c3876ba59fadd73990c4955ccff25a6e4c5348fe21a61d62a4
|
7
|
+
data.tar.gz: bbb5fc16a1935524cf241994926878480fc97e166215cb25c403f96eb1fed3dc06908f9f100b74596d343b78f0510db7a27ebe23b9b01d0d609dde5f68ddf98a
|
data/lib/xlogin/cli.rb
CHANGED
@@ -116,8 +116,7 @@ module Xlogin
|
|
116
116
|
loggers << File.join(config.logdir, "#{hostname}.log") if config.logdir
|
117
117
|
|
118
118
|
session = Xlogin.factory.build(hostinfo.merge(log: loggers))
|
119
|
-
session.enable
|
120
|
-
session.cmd('')
|
119
|
+
session.enable if session.config.enable
|
121
120
|
|
122
121
|
block.call(session)
|
123
122
|
rescue => e
|
data/lib/xlogin/factory.rb
CHANGED
@@ -9,6 +9,7 @@ module Xlogin
|
|
9
9
|
def initialize
|
10
10
|
@database = Hash.new
|
11
11
|
@templates = Hash.new
|
12
|
+
@pools = Hash.new
|
12
13
|
@group = nil
|
13
14
|
end
|
14
15
|
|
@@ -19,9 +20,9 @@ module Xlogin
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
|
-
def set(**
|
23
|
-
name =
|
24
|
-
@database[name] =
|
23
|
+
def set(**opts)
|
24
|
+
name = opts[:name]
|
25
|
+
@database[name] = opts if name
|
25
26
|
end
|
26
27
|
|
27
28
|
def get(name)
|
@@ -58,6 +59,23 @@ module Xlogin
|
|
58
59
|
@templates.keys
|
59
60
|
end
|
60
61
|
|
62
|
+
def set_pool(args, **opts)
|
63
|
+
name = case args
|
64
|
+
when String then args
|
65
|
+
when Hash then URI(args[:uri]).host
|
66
|
+
end
|
67
|
+
|
68
|
+
@pools[name] = SessionPool.new(args, **opts)
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_pool(name)
|
72
|
+
@pools[name]
|
73
|
+
end
|
74
|
+
|
75
|
+
def list_pools
|
76
|
+
@pools.keys
|
77
|
+
end
|
78
|
+
|
61
79
|
def group(group_name)
|
62
80
|
current_group = @group
|
63
81
|
@group = [current_group, group_name.to_s].compact.join(':')
|
@@ -65,18 +83,18 @@ module Xlogin
|
|
65
83
|
@group = current_group
|
66
84
|
end
|
67
85
|
|
68
|
-
def build(type:, uri:, **
|
86
|
+
def build(type:, uri:, **opts)
|
69
87
|
template = get_template(type)
|
70
88
|
raise Xlogin::TemplateError.new("Template not found: '#{type}'") unless template
|
71
89
|
|
72
|
-
template.build(uri, **
|
90
|
+
template.build(uri, **opts)
|
73
91
|
end
|
74
92
|
|
75
|
-
def build_from_hostname(hostname, **
|
93
|
+
def build_from_hostname(hostname, **opts)
|
76
94
|
hostinfo = get(hostname)
|
77
95
|
raise Xlogin::SessionError.new("Host not found: '#{hostname}'") unless hostinfo
|
78
96
|
|
79
|
-
build(hostinfo.merge(**
|
97
|
+
build(hostinfo.merge(**opts)).tap { |s| s.name = hostname }
|
80
98
|
end
|
81
99
|
|
82
100
|
def method_missing(method_name, *args, &block)
|
data/lib/xlogin/rake_task.rb
CHANGED
data/lib/xlogin/session.rb
CHANGED
@@ -1,23 +1,26 @@
|
|
1
|
+
require 'connection_pool'
|
2
|
+
require 'delegate'
|
1
3
|
require 'fileutils'
|
2
4
|
require 'net/ssh/gateway'
|
3
5
|
require 'ostruct'
|
4
6
|
require 'stringio'
|
7
|
+
require 'thread'
|
5
8
|
|
6
9
|
module Xlogin
|
7
10
|
module SessionModule
|
8
11
|
|
9
12
|
attr_accessor :name
|
10
|
-
attr_accessor :
|
13
|
+
attr_accessor :config
|
11
14
|
|
12
|
-
def initialize(template, uri, **
|
15
|
+
def initialize(template, uri, **opts)
|
13
16
|
@template = template
|
14
|
-
@
|
15
|
-
@opts = OpenStruct.new(params)
|
17
|
+
@config = OpenStruct.new(opts)
|
16
18
|
|
19
|
+
@uri = uri
|
17
20
|
@host = uri.host
|
18
21
|
@name = uri.host
|
19
22
|
@port = uri.port
|
20
|
-
@port ||= case @scheme
|
23
|
+
@port ||= case @uri.scheme
|
21
24
|
when 'ssh' then 22
|
22
25
|
when 'telnet' then 23
|
23
26
|
end
|
@@ -25,23 +28,27 @@ module Xlogin
|
|
25
28
|
@username, @password = uri.userinfo.to_s.split(':')
|
26
29
|
raise ArgumentError.new("Invalid URI - '#{uri}'") unless @host && @port
|
27
30
|
|
28
|
-
@
|
29
|
-
|
31
|
+
ssh_tunnel(@config.via) if @config.via
|
32
|
+
max_retry = @config.retry || 1
|
30
33
|
|
31
|
-
|
32
|
-
|
34
|
+
@mutex = Mutex.new
|
35
|
+
@closed = false
|
36
|
+
@output_logs = [@config.log]
|
37
|
+
@output_loggers = build_loggers
|
33
38
|
|
34
39
|
begin
|
35
|
-
|
40
|
+
super(
|
36
41
|
'Host' => @host,
|
37
42
|
'Port' => @port,
|
38
43
|
'Username' => @username,
|
39
44
|
'Password' => @password,
|
40
|
-
'Timeout' => @
|
45
|
+
'Timeout' => @config.timeout || @template.timeout || false,
|
41
46
|
'Prompt' => Regexp.union(*@template.prompt.map(&:first)),
|
47
|
+
'FailEOF' => true,
|
42
48
|
)
|
43
49
|
rescue => e
|
44
50
|
retry if (max_retry -= 1) > 0
|
51
|
+
@closed = true
|
45
52
|
raise e
|
46
53
|
end
|
47
54
|
end
|
@@ -54,47 +61,51 @@ module Xlogin
|
|
54
61
|
cmd('').lines.last.chomp
|
55
62
|
end
|
56
63
|
|
57
|
-
def
|
58
|
-
|
59
|
-
super(line, &block)
|
64
|
+
def cmd(*args)
|
65
|
+
@mutex.synchronize { super(*args) }
|
60
66
|
end
|
61
67
|
|
62
|
-
def
|
63
|
-
args
|
64
|
-
super(args)
|
68
|
+
def puts(*args, &block)
|
69
|
+
args = instance_exec(*args, &@template.interrupt) if @template.interrupt
|
70
|
+
super(*args, &block)
|
65
71
|
end
|
66
72
|
|
67
|
-
def waitfor(*
|
68
|
-
return waitfor(Regexp.union(*@template.prompt.map(&:first)), &block) if
|
73
|
+
def waitfor(*args, &block)
|
74
|
+
return waitfor(Regexp.union(*@template.prompt.map(&:first)), &block) if args.empty?
|
69
75
|
|
70
|
-
line = super(*
|
76
|
+
line = super(*args) do |recvdata|
|
71
77
|
output_log(recvdata, &block)
|
72
78
|
end
|
73
79
|
|
74
80
|
_, process = @template.prompt.find { |r, p| r =~ line && p }
|
75
81
|
if process
|
76
82
|
instance_eval(&process)
|
77
|
-
line += waitfor(*
|
83
|
+
line += waitfor(*args, &block)
|
78
84
|
end
|
79
85
|
|
80
86
|
line
|
87
|
+
rescue EOFError
|
88
|
+
@closed = true
|
81
89
|
end
|
82
90
|
|
83
|
-
def close
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
91
|
+
def close
|
92
|
+
@mutex.synchronize do
|
93
|
+
@output_loggers.each do |output_log, logger|
|
94
|
+
next unless logger
|
95
|
+
logger.close if output_log.kind_of?(String)
|
96
|
+
end
|
97
|
+
@gateway.shutdown! if @gateway
|
98
|
+
super
|
99
|
+
@closed = true
|
89
100
|
end
|
90
|
-
rescue
|
91
|
-
ensure
|
92
|
-
super
|
93
101
|
end
|
94
102
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
103
|
+
def closed?
|
104
|
+
@closed
|
105
|
+
end
|
106
|
+
|
107
|
+
def duplicate
|
108
|
+
@template.build(@uri, **config.to_h)
|
98
109
|
end
|
99
110
|
|
100
111
|
def enable_log(out = $stdout)
|
@@ -155,4 +166,48 @@ module Xlogin
|
|
155
166
|
end
|
156
167
|
end
|
157
168
|
end
|
169
|
+
|
170
|
+
class SessionPool
|
171
|
+
def initialize(args, **opts)
|
172
|
+
temp = case args
|
173
|
+
when Hash then args
|
174
|
+
when String then opts
|
175
|
+
end
|
176
|
+
|
177
|
+
@opts = temp.select { |k, v| %i(size timeout).member?(k) && !v.nil? }
|
178
|
+
@pool = ConnectionPool.new(**@opts) { Wrapper.new(args, **opts) }
|
179
|
+
end
|
180
|
+
|
181
|
+
def with(**opts)
|
182
|
+
@pool.with(**opts) do |session|
|
183
|
+
session.repair if session.closed?
|
184
|
+
session.aging_time(opts[:aging]) if opts[:aging]
|
185
|
+
|
186
|
+
yield session
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class Wrapper
|
191
|
+
def initialize(*args)
|
192
|
+
@session = Xlogin.get(*args)
|
193
|
+
@agetime = nil
|
194
|
+
end
|
195
|
+
|
196
|
+
def repair
|
197
|
+
@session = @session.duplicate
|
198
|
+
end
|
199
|
+
|
200
|
+
def aging_time(time = @session.config.timeout)
|
201
|
+
@agetime = Time.now + time
|
202
|
+
Thread.start do
|
203
|
+
sleep(time)
|
204
|
+
@session.close if Time.now > @agetime
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def method_missing(name, *args, &block)
|
209
|
+
@session.send(name, *args, &block)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
158
213
|
end
|
data/lib/xlogin/telnet.rb
CHANGED
@@ -10,10 +10,10 @@ module Xlogin
|
|
10
10
|
alias_method :telnet_login, :login
|
11
11
|
undef_method :login
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
username =
|
15
|
-
password =
|
16
|
-
super(
|
13
|
+
def initialize(args)
|
14
|
+
username = args.delete('Username')
|
15
|
+
password = args.delete('Password')
|
16
|
+
super(args)
|
17
17
|
|
18
18
|
if username || password
|
19
19
|
return login(*[username, password].compact) if respond_to?(:login)
|
data/lib/xlogin/template.rb
CHANGED
@@ -40,21 +40,21 @@ module Xlogin
|
|
40
40
|
@interrupt = block
|
41
41
|
end
|
42
42
|
|
43
|
-
def build(uri, **
|
43
|
+
def build(uri, **opts)
|
44
44
|
uri = URI(uri.to_s)
|
45
45
|
klass = Class.new(Xlogin.const_get(uri.scheme.capitalize))
|
46
46
|
klass.class_exec(@methods) do |methods|
|
47
47
|
methods.each do |name, block|
|
48
48
|
case name
|
49
49
|
when :enable
|
50
|
-
define_method(name) { |
|
50
|
+
define_method(name) { |password = opts[:enable]| instance_exec(password, &block) }
|
51
51
|
else
|
52
52
|
define_method(name, &block)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
klass.new(self, uri, **
|
57
|
+
klass.new(self, uri, **opts)
|
58
58
|
end
|
59
59
|
|
60
60
|
def method_missing(name, *, &block)
|
data/lib/xlogin/version.rb
CHANGED
data/lib/xlogin.rb
CHANGED
@@ -19,18 +19,30 @@ module Xlogin
|
|
19
19
|
@factory ||= Xlogin::Factory.instance
|
20
20
|
end
|
21
21
|
|
22
|
-
def get(
|
23
|
-
session =
|
22
|
+
def get(args, **opts, &block)
|
23
|
+
session = case args
|
24
|
+
when Hash then factory.build(**args.merge(**opts))
|
25
|
+
when String then factory.build_from_hostname(args, **opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
return session unless block
|
29
|
+
begin block.call(session) ensure session.close end
|
30
|
+
end
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
32
|
+
def get_pool(args, **opts, &block)
|
33
|
+
pool = factory.set_template(args, **opts)
|
34
|
+
|
35
|
+
return pool unless block
|
36
|
+
block.call(pool)
|
30
37
|
end
|
31
38
|
|
32
39
|
def configure(&block)
|
33
|
-
|
40
|
+
if block
|
41
|
+
instance_eval(&block)
|
42
|
+
else
|
43
|
+
source
|
44
|
+
template_dir
|
45
|
+
end
|
34
46
|
end
|
35
47
|
|
36
48
|
def authorized?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xlogin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- haccht
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-telnet
|