teuton 2.9.5 → 2.10.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 +4 -4
- data/README.md +3 -3
- data/docs/commands/README.md +28 -83
- data/docs/commands/{example_check.md → check-example.md} +2 -6
- data/docs/commands/{example_run.md → howto-run-tests.md} +16 -10
- data/docs/install/README.md +10 -6
- data/docs/install/s-node.md +3 -3
- data/docs/install/t-node.md +75 -6
- data/docs/learn/13-feedback.md +8 -7
- data/lib/teuton/case/case.rb +5 -9
- data/lib/teuton/case/dsl/expect_sequence.rb +2 -2
- data/lib/teuton/case/dsl/send.rb +13 -8
- data/lib/teuton/case_manager/case_manager.rb +1 -0
- data/lib/teuton/case_manager/dsl.rb +24 -17
- data/lib/teuton/case_manager/export_manager.rb +13 -7
- data/lib/teuton/case_manager/report.rb +1 -1
- data/lib/teuton/case_manager/send_manager.rb +22 -6
- data/lib/teuton/case_manager/show_report.rb +0 -1
- data/lib/teuton/readme/readme.rb +1 -0
- data/lib/teuton/report/formatter/formatter.rb +1 -0
- data/lib/teuton/report/report.rb +1 -5
- data/lib/teuton/utils/project.rb +4 -4
- data/lib/teuton/version.rb +1 -1
- metadata +38 -24
- data/docs/changelog/changelog.1.md +0 -119
- data/docs/changelog/changelog.2.md +0 -128
- data/docs/changelog/todo.md +0 -16
- data/docs/install/manual.md +0 -41
- data/docs/install/vagrant_docker.md +0 -56
- data/lib/teuton/deprecated/application.rb +0 -80
- data/lib/teuton/deprecated/application_test.rb +0 -32
- data/lib/teuton/deprecated/runner.rb +0 -190
- data/lib/teuton/deprecated/utils.rb +0 -40
- /data/docs/{diagram.md → devel/diagram.md} +0 -0
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
require "test/unit"
|
|
2
|
-
require_relative "../../lib/teuton/utils/application"
|
|
3
|
-
|
|
4
|
-
class ApplicationTest < Test::Unit::TestCase
|
|
5
|
-
def setup
|
|
6
|
-
@app = Application.instance
|
|
7
|
-
@app.reset
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def test_init_params
|
|
11
|
-
assert_equal ".", @app.letter[:good]
|
|
12
|
-
assert_equal "F", @app.letter[:bad]
|
|
13
|
-
assert_equal "?", @app.letter[:error]
|
|
14
|
-
assert_equal " ", @app.letter[:none]
|
|
15
|
-
assert_equal "var", @app.output_basedir
|
|
16
|
-
assert_equal false, @app.debug
|
|
17
|
-
assert_equal true, @app.verbose
|
|
18
|
-
|
|
19
|
-
assert_equal true, @app.global == {}
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def test_quiet?
|
|
23
|
-
@app.verbose = false
|
|
24
|
-
assert_equal false, @app.verbose
|
|
25
|
-
assert_equal true, Application.instance.quiet?
|
|
26
|
-
@app.verbose = true
|
|
27
|
-
assert_equal true, @app.verbose
|
|
28
|
-
assert_equal false, Application.instance.quiet?
|
|
29
|
-
@app.options["quiet"] = true
|
|
30
|
-
assert_equal true, Application.instance.quiet?
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
require "net/ssh"
|
|
2
|
-
require "net/sftp"
|
|
3
|
-
require "net/telnet"
|
|
4
|
-
require_relative "dsl/log"
|
|
5
|
-
|
|
6
|
-
class Case
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
# READ: @config
|
|
10
|
-
# WRITE: @action, @result, @session
|
|
11
|
-
def run_cmd_on(host)
|
|
12
|
-
protocol = @config.get(:"#{host}_protocol")
|
|
13
|
-
ip = @config.get(:"#{host}_ip")
|
|
14
|
-
|
|
15
|
-
if protocol.to_s.downcase == "local" || host.to_s == "localhost"
|
|
16
|
-
# Protocol force => local
|
|
17
|
-
run_cmd_localhost
|
|
18
|
-
elsif protocol.to_s.downcase == "ssh"
|
|
19
|
-
# Protocol force => ssh
|
|
20
|
-
run_cmd_remote_ssh(host)
|
|
21
|
-
elsif protocol.to_s.downcase == "telnet"
|
|
22
|
-
# Protocol force => telnet
|
|
23
|
-
run_cmd_remote_telnet(host)
|
|
24
|
-
elsif ip.to_s.downcase == "localhost" || ip.to_s.include?("127.0.0.")
|
|
25
|
-
run_cmd_localhost
|
|
26
|
-
elsif ip == "NODATA"
|
|
27
|
-
log("#{host} IP not found!", :error)
|
|
28
|
-
else
|
|
29
|
-
run_cmd_remote_ssh host
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def run_cmd_localhost
|
|
34
|
-
@action[:conn_type] = :local
|
|
35
|
-
resp = my_execute(@action[:command], @action[:encoding])
|
|
36
|
-
@result.exitcode = resp[:exitcode]
|
|
37
|
-
@result.content = resp[:content]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def run_cmd_remote(input_hostname)
|
|
41
|
-
# @param input_hostname (Symbol or String)
|
|
42
|
-
hostname = input_hostname.to_s
|
|
43
|
-
i = (hostname + "_protocol").to_sym
|
|
44
|
-
protocol = @config.get(i) if @config.get(i)
|
|
45
|
-
protocol = :ssh if protocol.nil? || protocol == "NODATA"
|
|
46
|
-
protocol = protocol.to_sym
|
|
47
|
-
case protocol
|
|
48
|
-
when :ssh
|
|
49
|
-
run_cmd_remote_ssh(input_hostname)
|
|
50
|
-
when :telnet
|
|
51
|
-
run_cmd_remote_telnet(input_hostname)
|
|
52
|
-
when :local
|
|
53
|
-
run_cmd_localhost
|
|
54
|
-
else
|
|
55
|
-
log("Protocol #{protocol} unknown! Use ssh or telnet.", :error)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def run_cmd_remote_ssh(input_hostname)
|
|
60
|
-
@action[:conn_type] = :ssh
|
|
61
|
-
hostname = input_hostname.to_s
|
|
62
|
-
ip = @config.get(:"#{hostname}_ip").to_s
|
|
63
|
-
username = @config.get(:"#{hostname}_username").to_s
|
|
64
|
-
password = @config.get(:"#{hostname}_password").to_s
|
|
65
|
-
port = @config.get(:"#{hostname}_port").to_i
|
|
66
|
-
port = 22 if port.zero?
|
|
67
|
-
|
|
68
|
-
unless @config.get(:"#{hostname}_route") == "NODATA"
|
|
69
|
-
# Reconfigure command with gateway. Example host1_route: IP.
|
|
70
|
-
# hostname2 = hostname ¿not used?
|
|
71
|
-
ip2 = ip
|
|
72
|
-
username2 = username
|
|
73
|
-
password2 = password
|
|
74
|
-
command2 = @action[:command]
|
|
75
|
-
hostname = @config.get(:"#{hostname}_route")
|
|
76
|
-
ip = @config.get(:"#{hostname}_ip").to_s
|
|
77
|
-
username = @config.get(:"#{hostname}_username").to_s
|
|
78
|
-
password = @config.get(:"#{hostname}_password").to_s
|
|
79
|
-
ostype = @config.get(:"#{hostname}_ostype").to_s
|
|
80
|
-
|
|
81
|
-
@action[:command] = if ostype.downcase.start_with? "win"
|
|
82
|
-
"echo y | plink #{username2}@#{ip2} -ssh -pw #{password2} \"#{command2}\""
|
|
83
|
-
else
|
|
84
|
-
"sshpass -p #{password2} #{username2}@#{ip2} #{command2}"
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
text = ""
|
|
89
|
-
exitcode = 0
|
|
90
|
-
begin
|
|
91
|
-
if @sessions[hostname].nil?
|
|
92
|
-
@sessions[hostname] = Net::SSH.start(
|
|
93
|
-
ip,
|
|
94
|
-
username,
|
|
95
|
-
port: port,
|
|
96
|
-
password: password,
|
|
97
|
-
keepalive: true,
|
|
98
|
-
timeout: 30,
|
|
99
|
-
non_interactive: true
|
|
100
|
-
)
|
|
101
|
-
end
|
|
102
|
-
text = if @sessions[hostname].instance_of? Net::SSH::Connection::Session
|
|
103
|
-
@sessions[hostname].exec!(@action[:command])
|
|
104
|
-
else
|
|
105
|
-
"SSH: NO CONNECTION!"
|
|
106
|
-
end
|
|
107
|
-
exitcode = text.exitstatus
|
|
108
|
-
rescue Errno::EHOSTUNREACH
|
|
109
|
-
@sessions[hostname] = :nosession
|
|
110
|
-
@conn_status[hostname] = :host_unreachable
|
|
111
|
-
exitcode = -1
|
|
112
|
-
log("Host #{ip} unreachable!", :error)
|
|
113
|
-
rescue Net::SSH::AuthenticationFailed
|
|
114
|
-
@sessions[hostname] = :nosession
|
|
115
|
-
@conn_status[hostname] = :error_authentication_failed
|
|
116
|
-
exitcode = -1
|
|
117
|
-
log("SSH::AuthenticationFailed!", :error)
|
|
118
|
-
rescue Net::SSH::HostKeyMismatch
|
|
119
|
-
@sessions[hostname] = :nosession
|
|
120
|
-
@conn_status[hostname] = :host_key_mismatch
|
|
121
|
-
exitcode = -1
|
|
122
|
-
log("SSH::HostKeyMismatch!", :error)
|
|
123
|
-
log("* The destination server's fingerprint is not matching " \
|
|
124
|
-
"what is in your local known_hosts file.", :error)
|
|
125
|
-
log("* Remove the existing entry in your local known_hosts file", :error)
|
|
126
|
-
log("* Try this => ssh-keygen -f '/home/USERNAME/.ssh/known_hosts' " \
|
|
127
|
-
"-R #{ip}", :error)
|
|
128
|
-
rescue => e
|
|
129
|
-
@sessions[hostname] = :nosession
|
|
130
|
-
@conn_status[hostname] = :error
|
|
131
|
-
exitcode = -1
|
|
132
|
-
log("[#{e.class}] SSH on <#{username}@#{ip}>" \
|
|
133
|
-
" exec: #{@action[:command]}", :error)
|
|
134
|
-
end
|
|
135
|
-
output = encode_and_split(@action[:encoding], text)
|
|
136
|
-
@result.exitcode = exitcode
|
|
137
|
-
@result.content = output
|
|
138
|
-
@result.content.compact!
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def run_cmd_remote_telnet(input_hostname)
|
|
142
|
-
@action[:conn_type] = :telnet
|
|
143
|
-
# app = Application.instance ¿not used?
|
|
144
|
-
hostname = input_hostname.to_s
|
|
145
|
-
ip = @config.get((hostname + "_ip").to_sym)
|
|
146
|
-
username = @config.get((hostname + "_username").to_sym).to_s
|
|
147
|
-
password = @config.get((hostname + "_password").to_sym).to_s
|
|
148
|
-
text = ""
|
|
149
|
-
begin
|
|
150
|
-
if @sessions[hostname].nil? || @sessions[hostname] == :ok
|
|
151
|
-
h = Net::Telnet.new(
|
|
152
|
-
"Host" => ip,
|
|
153
|
-
"Timeout" => 30,
|
|
154
|
-
"Prompt" => /login|teuton|[$%#>]/
|
|
155
|
-
)
|
|
156
|
-
# "Prompt" => Regexp.new(username[1, 40]))
|
|
157
|
-
# "Prompt" => /[$%#>] \z/n)
|
|
158
|
-
h.login(username, password)
|
|
159
|
-
h.cmd(@action[:command]) { |i| text << i }
|
|
160
|
-
h.close
|
|
161
|
-
@sessions[hostname] = :ok
|
|
162
|
-
else
|
|
163
|
-
text = "TELNET: NO CONNECTION!"
|
|
164
|
-
end
|
|
165
|
-
rescue Net::OpenTimeout
|
|
166
|
-
@sessions[hostname] = :nosession
|
|
167
|
-
@conn_status[hostname] = :open_timeout
|
|
168
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
|
169
|
-
log(" ExceptionType=<Net::OpenTimeout> doing <telnet #{ip}>", :error)
|
|
170
|
-
log(" └── Revise host IP!", :warn)
|
|
171
|
-
rescue Net::ReadTimeout
|
|
172
|
-
@sessions[hostname] = :nosession
|
|
173
|
-
@conn_status[hostname] = :read_timeout
|
|
174
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
|
175
|
-
log(" ExceptionType=<Net::ReadTimeout> doing <telnet #{ip}>", :error)
|
|
176
|
-
rescue => e
|
|
177
|
-
@sessions[hostname] = :nosession
|
|
178
|
-
@conn_status[hostname] = :error
|
|
179
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
|
180
|
-
log(" ExceptionType=<#{e.class}> doing telnet on <#{username}@#{ip}>" \
|
|
181
|
-
" exec: #{@action[:command]}", :error)
|
|
182
|
-
log(" └── username=<#{username}>, password=<#{password}>," \
|
|
183
|
-
" ip=<#{ip}>, HOSTID=<#{hostname}>", :warn)
|
|
184
|
-
end
|
|
185
|
-
output = encode_and_split(@action[:encoding], text)
|
|
186
|
-
@result.exitcode = -1
|
|
187
|
-
@result.content = output
|
|
188
|
-
@result.content.compact!
|
|
189
|
-
end
|
|
190
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
require "open3"
|
|
2
|
-
require "rainbow"
|
|
3
|
-
require_relative "../utils/project"
|
|
4
|
-
|
|
5
|
-
module Utils
|
|
6
|
-
def encode_and_split(encoding, text)
|
|
7
|
-
# Convert text to UTF-8 deleting unknown chars
|
|
8
|
-
text ||= "" # Ensure text is not nil
|
|
9
|
-
flag = [:default, "UTF-8"].include? encoding
|
|
10
|
-
return text.encode("UTF-8", invalid: :replace).split("\n") if flag
|
|
11
|
-
|
|
12
|
-
# Convert text from input ENCODING to UTF-8
|
|
13
|
-
ec = Encoding::Converter.new(encoding.to_s, "UTF-8")
|
|
14
|
-
begin
|
|
15
|
-
text = ec.convert(text)
|
|
16
|
-
rescue => e
|
|
17
|
-
warn "[ERROR] #{e}"
|
|
18
|
-
warn " Suggest declare text encoding, for example:"
|
|
19
|
-
warn " run 'command', on: :host, :encoding => 'ISO-8859-1'"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
text.split("\n")
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def my_execute(cmd, encoding = "UTF-8")
|
|
26
|
-
# TODO: mover a la clase ExecuteManager
|
|
27
|
-
return {exitstatus: 0, content: ""} if Project.debug?
|
|
28
|
-
|
|
29
|
-
begin
|
|
30
|
-
text, status = Open3.capture2e(cmd)
|
|
31
|
-
exitstatus = status.exitstatus
|
|
32
|
-
rescue => e
|
|
33
|
-
verbose Rainbow("!").green
|
|
34
|
-
text = e.to_s
|
|
35
|
-
exitstatus = 1
|
|
36
|
-
end
|
|
37
|
-
content = encode_and_split(encoding, text)
|
|
38
|
-
{exitstatus: exitstatus, content: content}
|
|
39
|
-
end
|
|
40
|
-
end
|
|
File without changes
|