teuton 0.0.1
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/bin/teuton +4 -0
- data/lib/teuton/application.rb +53 -0
- data/lib/teuton/case_manager/case/builtin/main.rb +24 -0
- data/lib/teuton/case_manager/case/builtin/package.rb +20 -0
- data/lib/teuton/case_manager/case/builtin/service.rb +32 -0
- data/lib/teuton/case_manager/case/builtin/user.rb +20 -0
- data/lib/teuton/case_manager/case/case.rb +114 -0
- data/lib/teuton/case_manager/case/close.rb +29 -0
- data/lib/teuton/case_manager/case/config.rb +76 -0
- data/lib/teuton/case_manager/case/dsl/check.rb +24 -0
- data/lib/teuton/case_manager/case/dsl/deprecated.rb +14 -0
- data/lib/teuton/case_manager/case/dsl/expect.rb +78 -0
- data/lib/teuton/case_manager/case/dsl/getset.rb +22 -0
- data/lib/teuton/case_manager/case/dsl/goto.rb +35 -0
- data/lib/teuton/case_manager/case/dsl/log.rb +14 -0
- data/lib/teuton/case_manager/case/dsl/main.rb +11 -0
- data/lib/teuton/case_manager/case/dsl/missing.rb +12 -0
- data/lib/teuton/case_manager/case/dsl/send.rb +69 -0
- data/lib/teuton/case_manager/case/dsl/target.rb +16 -0
- data/lib/teuton/case_manager/case/dsl/unique.rb +11 -0
- data/lib/teuton/case_manager/case/main.rb +7 -0
- data/lib/teuton/case_manager/case/play.rb +59 -0
- data/lib/teuton/case_manager/case/result/ext_array.rb +43 -0
- data/lib/teuton/case_manager/case/result/ext_compare.rb +147 -0
- data/lib/teuton/case_manager/case/result/ext_filter.rb +68 -0
- data/lib/teuton/case_manager/case/result/result.rb +73 -0
- data/lib/teuton/case_manager/case/runner.rb +134 -0
- data/lib/teuton/case_manager/case_manager.rb +76 -0
- data/lib/teuton/case_manager/check_cases.rb +73 -0
- data/lib/teuton/case_manager/dsl.rb +31 -0
- data/lib/teuton/case_manager/export_manager.rb +20 -0
- data/lib/teuton/case_manager/hall_of_fame.rb +28 -0
- data/lib/teuton/case_manager/main.rb +6 -0
- data/lib/teuton/case_manager/report.rb +52 -0
- data/lib/teuton/case_manager/show.rb +19 -0
- data/lib/teuton/case_manager/utils.rb +57 -0
- data/lib/teuton/command/create.rb +20 -0
- data/lib/teuton/command/download.rb +26 -0
- data/lib/teuton/command/main.rb +9 -0
- data/lib/teuton/command/play.rb +34 -0
- data/lib/teuton/command/readme.rb +23 -0
- data/lib/teuton/command/test.rb +35 -0
- data/lib/teuton/command/update.rb +27 -0
- data/lib/teuton/command/version.rb +13 -0
- data/lib/teuton/files/start.rb +13 -0
- data/lib/teuton/project/configfile_reader.rb +49 -0
- data/lib/teuton/project/laboratory/builtin.rb +23 -0
- data/lib/teuton/project/laboratory/dsl.rb +117 -0
- data/lib/teuton/project/laboratory/laboratory.rb +55 -0
- data/lib/teuton/project/laboratory/show.rb +161 -0
- data/lib/teuton/project/name_file_finder.rb +129 -0
- data/lib/teuton/project/project.rb +62 -0
- data/lib/teuton/project/project_creator.rb +79 -0
- data/lib/teuton/project/readme/dsl.rb +109 -0
- data/lib/teuton/project/readme/lang.rb +30 -0
- data/lib/teuton/project/readme/readme.rb +156 -0
- data/lib/teuton/rake_function/check.rb +39 -0
- data/lib/teuton/rake_function/install.rb +36 -0
- data/lib/teuton/report/close.rb +34 -0
- data/lib/teuton/report/formatter/array_formatter.rb +84 -0
- data/lib/teuton/report/formatter/base_formatter.rb +33 -0
- data/lib/teuton/report/formatter/csv_formatter.rb +31 -0
- data/lib/teuton/report/formatter/formatter_factory.rb +73 -0
- data/lib/teuton/report/formatter/html_formatter.rb +81 -0
- data/lib/teuton/report/formatter/json_formatter.rb +17 -0
- data/lib/teuton/report/formatter/list_formatter.rb +71 -0
- data/lib/teuton/report/formatter/moodle_csv_formatter.rb +28 -0
- data/lib/teuton/report/formatter/resume_array_formatter.rb +49 -0
- data/lib/teuton/report/formatter/resume_json_formatter.rb +16 -0
- data/lib/teuton/report/formatter/resume_list_formatter.rb +62 -0
- data/lib/teuton/report/formatter/resume_txt_formatter.rb +102 -0
- data/lib/teuton/report/formatter/resume_yaml_formatter.rb +16 -0
- data/lib/teuton/report/formatter/txt_formatter.rb +102 -0
- data/lib/teuton/report/formatter/xml_formatter.rb +42 -0
- data/lib/teuton/report/formatter/yaml_formatter.rb +18 -0
- data/lib/teuton/report/report.rb +55 -0
- data/lib/teuton/report/show.rb +111 -0
- data/lib/teuton/utils/verbose.rb +15 -0
- data/lib/teuton.rb +17 -0
- metadata +263 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require 'terminal-table'
|
|
2
|
+
require 'rainbow'
|
|
3
|
+
|
|
4
|
+
require_relative '../../application'
|
|
5
|
+
require_relative '../configfile_reader'
|
|
6
|
+
|
|
7
|
+
# Laboratory
|
|
8
|
+
# * show_dsl
|
|
9
|
+
# * show_stats
|
|
10
|
+
# * show_config
|
|
11
|
+
class Laboratory
|
|
12
|
+
def show_dsl
|
|
13
|
+
@verbose = true
|
|
14
|
+
process_content
|
|
15
|
+
show_stats
|
|
16
|
+
show_config
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def show_stats
|
|
20
|
+
@stats[:hosts] = 0
|
|
21
|
+
@hosts.each_pair { |_k, v| @stats[:hosts] += v }
|
|
22
|
+
|
|
23
|
+
my_screen_table = Terminal::Table.new do |st|
|
|
24
|
+
st.add_row ['DSL Stats', 'Count']
|
|
25
|
+
st.add_separator
|
|
26
|
+
st.add_row ['Groups', @stats[:groups]]
|
|
27
|
+
st.add_row ['Targets', @stats[:targets]]
|
|
28
|
+
st.add_row ['Goto', @stats[:hosts]]
|
|
29
|
+
@hosts.each_pair { |k, v| st.add_row [" * #{k}", v] }
|
|
30
|
+
st.add_row ['Uniques', @stats[:uniques]]
|
|
31
|
+
st.add_row ['Logs', @stats[:uniques]]
|
|
32
|
+
st.add_row [' ', ' ']
|
|
33
|
+
|
|
34
|
+
st.add_row ['Gets', @stats[:gets]]
|
|
35
|
+
if @gets.count > 0
|
|
36
|
+
list = @gets.sort_by { |_k, v| v }
|
|
37
|
+
list.reverse_each { |item| st.add_row [" * #{item[0]}", item[1].to_s] }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
st.add_row ['Sets', @stats[:sets]]
|
|
41
|
+
if @sets.count > 0
|
|
42
|
+
@sets.each_pair { |k, v| st.add_row [" * #{k}", v.to_s] }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
verboseln my_screen_table.to_s + "\n"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def show_config
|
|
49
|
+
@verbose = false
|
|
50
|
+
process_content
|
|
51
|
+
@verbose = true
|
|
52
|
+
revise_config_content
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def show_requests
|
|
56
|
+
@verbose = false
|
|
57
|
+
process_content
|
|
58
|
+
@verbose = true
|
|
59
|
+
my_screen_table = Terminal::Table.new do |st|
|
|
60
|
+
st.add_row ['Lines', 'REQUEST description']
|
|
61
|
+
st.add_separator
|
|
62
|
+
@requests.each_with_index do |line, index|
|
|
63
|
+
st.add_row ['%03d' % index, line]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
verboseln my_screen_table
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def verbose(text)
|
|
72
|
+
print text if @verbose
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def verboseln(text)
|
|
76
|
+
puts text if @verbose
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def process_content
|
|
80
|
+
groups = Application.instance.groups
|
|
81
|
+
verboseln ''
|
|
82
|
+
groups.each do |t|
|
|
83
|
+
@stats[:groups] += 1
|
|
84
|
+
|
|
85
|
+
msg = "GROUP: #{t[:name]}"
|
|
86
|
+
my_screen_table = Terminal::Table.new { |st| st.add_row [msg] }
|
|
87
|
+
verboseln my_screen_table
|
|
88
|
+
|
|
89
|
+
instance_eval(&t[:block])
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def find_script_vars
|
|
94
|
+
script_vars = [:tt_members]
|
|
95
|
+
@hosts.each_key do |k|
|
|
96
|
+
next if k == :localhost
|
|
97
|
+
|
|
98
|
+
if k.class == Symbol
|
|
99
|
+
script_vars << (k.to_s + '_ip').to_sym
|
|
100
|
+
script_vars << (k.to_s + '_username').to_sym
|
|
101
|
+
script_vars << (k.to_s + '_password').to_sym
|
|
102
|
+
else
|
|
103
|
+
script_vars << k.to_s + '_ip'
|
|
104
|
+
script_vars << k.to_s + '_username'
|
|
105
|
+
script_vars << k.to_s + '_password'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
@gets.each_key { |k| script_vars << k }
|
|
109
|
+
script_vars
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def recomended_config_content
|
|
113
|
+
verbose Rainbow('[WARN] File ').yellow
|
|
114
|
+
verbose Rainbow(@path[:config]).yellow.bright
|
|
115
|
+
verboseln Rainbow(' not found!').yellow
|
|
116
|
+
verboseln '[INFO] Recomended content:'
|
|
117
|
+
output = { global: nil, cases: [] }
|
|
118
|
+
output[:cases][0] = {}
|
|
119
|
+
script_vars = find_script_vars
|
|
120
|
+
script_vars.each { |i| output[:cases][0][i] = 'VALUE' }
|
|
121
|
+
verboseln YAML.dump(output)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def revise_config_content
|
|
125
|
+
@verbose = true
|
|
126
|
+
my_screen_table = Terminal::Table.new do |st|
|
|
127
|
+
st.add_row ['Revising CONFIG file']
|
|
128
|
+
end
|
|
129
|
+
verboseln my_screen_table
|
|
130
|
+
|
|
131
|
+
unless File.exist?(@path[:config])
|
|
132
|
+
recomended_config_content
|
|
133
|
+
return
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
script_vars = find_script_vars
|
|
137
|
+
config_vars = ConfigFileReader.read(@path[:config])
|
|
138
|
+
unless config_vars[:global].nil?
|
|
139
|
+
config_vars[:global].each_key { |k| script_vars.delete(k) }
|
|
140
|
+
end
|
|
141
|
+
unless config_vars[:alias].nil?
|
|
142
|
+
config_vars[:alias].each_key { |k| script_vars.delete(k) }
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
config_vars[:cases].each_with_index do |item, index|
|
|
146
|
+
next if item[:tt_skip] == true
|
|
147
|
+
|
|
148
|
+
script_vars.each do |value|
|
|
149
|
+
next unless item[value].nil?
|
|
150
|
+
|
|
151
|
+
next unless @sets[':' + value.to_s].nil?
|
|
152
|
+
|
|
153
|
+
verbose Rainbow(' * Define ').red
|
|
154
|
+
verbose Rainbow(value).red.bright
|
|
155
|
+
verbose Rainbow(' value for Case[').red
|
|
156
|
+
verbose Rainbow(index).red.bright
|
|
157
|
+
verboseln Rainbow('] or set tt_skip = true').red
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rainbow'
|
|
4
|
+
require_relative '../application'
|
|
5
|
+
|
|
6
|
+
# Project:
|
|
7
|
+
# * find_filenames_for, verbose, verboseln
|
|
8
|
+
module NameFileFinder
|
|
9
|
+
def self.find_filenames_for(relpathtofile)
|
|
10
|
+
pathtofile = File.absolute_path(relpathtofile)
|
|
11
|
+
|
|
12
|
+
# Define:
|
|
13
|
+
# script_path, must contain fullpath to DSL script file
|
|
14
|
+
# config_path, must contain fullpath to YAML config file
|
|
15
|
+
if File.directory?(pathtofile)
|
|
16
|
+
# COMPLEX MODE: We use start.rb as main RB file
|
|
17
|
+
find_filenames_from_directory(pathtofile)
|
|
18
|
+
else
|
|
19
|
+
# SIMPLE MODE: We use pathtofile as main RB file
|
|
20
|
+
find_filenames_from_rb(pathtofile)
|
|
21
|
+
end
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.find_filenames_from_directory(pathtodir)
|
|
26
|
+
# COMPLEX MODE: We use start.rb as main RB file
|
|
27
|
+
script_path = File.join(pathtodir, 'start.rb')
|
|
28
|
+
unless File.exist? script_path
|
|
29
|
+
print Rainbow('[ERROR] File ').red
|
|
30
|
+
print Rainbow(script_path).bright.red
|
|
31
|
+
puts Rainbow(' not found!').red
|
|
32
|
+
exit 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
app = Application.instance
|
|
36
|
+
app.project_path = pathtodir
|
|
37
|
+
app.script_path = script_path
|
|
38
|
+
app.test_name = pathtodir.split(File::SEPARATOR)[-1]
|
|
39
|
+
|
|
40
|
+
find_configfilename_from_directory(pathtodir)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.find_configfilename_from_directory(pathtodir)
|
|
44
|
+
# COMPLEX MODE: We use config.yaml by default
|
|
45
|
+
app = Application.instance
|
|
46
|
+
|
|
47
|
+
config_path = ''
|
|
48
|
+
if app.options['cpath'].nil?
|
|
49
|
+
config_name = 'config'
|
|
50
|
+
# Config name file is introduced by cname arg option from teuton command
|
|
51
|
+
config_name = app.options['cname'] unless app.options['cname'].nil?
|
|
52
|
+
config_path = File.join(pathtodir, "#{config_name}.json")
|
|
53
|
+
unless File.exist? config_path
|
|
54
|
+
config_path = File.join(pathtodir, "#{config_name}.yaml")
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
# Config path file is introduced by cpath arg option from teuton command
|
|
58
|
+
config_path = app.options['cpath']
|
|
59
|
+
end
|
|
60
|
+
app.config_path = config_path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.find_filenames_from_rb(script_path)
|
|
64
|
+
# SIMPLE MODE: We use script_path as main RB file
|
|
65
|
+
# This must be fullpath to DSL script file
|
|
66
|
+
if File.extname(script_path) != '.rb'
|
|
67
|
+
print Rainbow('[ERROR] Script ').red
|
|
68
|
+
print Rainbow(script_path).bright.red
|
|
69
|
+
puts Rainbow(' must have rb extension').red
|
|
70
|
+
exit 1
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
app = Application.instance
|
|
74
|
+
app.project_path = File.dirname(script_path)
|
|
75
|
+
app.script_path = script_path
|
|
76
|
+
app.test_name = File.basename(script_path, '.rb')
|
|
77
|
+
|
|
78
|
+
find_configfilenames_from_rb(script_path)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.find_configfilenames_from_rb(script_path)
|
|
82
|
+
# SIMPLE MODE: We use script_path as main RB file
|
|
83
|
+
# This must be fullpath to DSL script file
|
|
84
|
+
app = Application.instance
|
|
85
|
+
|
|
86
|
+
config_path = ''
|
|
87
|
+
if app.options['cpath'].nil?
|
|
88
|
+
config_name = File.basename(script_path, '.rb')
|
|
89
|
+
# Config name file is introduced by cname arg option from teuton command
|
|
90
|
+
config_name = app.options['cname'] unless app.options['cname'].nil?
|
|
91
|
+
|
|
92
|
+
config_path = File.join(app.project_path, config_name + '.json')
|
|
93
|
+
unless File.exist? config_path
|
|
94
|
+
config_path = File.join(app.project_path, config_name + '.yaml')
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
# Config path file is introduced by cpath arg option from teuton command
|
|
98
|
+
config_path = app.options['cpath']
|
|
99
|
+
end
|
|
100
|
+
app.config_path = config_path
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.puts_input_info_on_screen
|
|
104
|
+
app = Application.instance
|
|
105
|
+
|
|
106
|
+
verbose Rainbow('[INFO] ScriptPath => ').blue
|
|
107
|
+
verboseln Rainbow(trim(app.script_path)).blue.bright
|
|
108
|
+
verbose Rainbow('[INFO] ConfigPath => ').blue
|
|
109
|
+
verboseln Rainbow(trim(app.config_path)).blue.bright
|
|
110
|
+
verbose Rainbow('[INFO] TestName => ').blue
|
|
111
|
+
verboseln Rainbow(trim(app.test_name)).blue.bright
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def self.trim(input)
|
|
115
|
+
output = input.to_s
|
|
116
|
+
output = "...#{input[input.size - 50, input.size]}" if output.size > 65
|
|
117
|
+
output.to_s
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.verboseln(text)
|
|
121
|
+
verbose(text + "\n")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def self.verbose(text)
|
|
125
|
+
return unless Application.instance.verbose
|
|
126
|
+
return if Application.instance.options['quiet']
|
|
127
|
+
print text
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../application'
|
|
4
|
+
require_relative 'name_file_finder'
|
|
5
|
+
|
|
6
|
+
# Project functions invoked by CLI project tool
|
|
7
|
+
# * test
|
|
8
|
+
# * play
|
|
9
|
+
# * process_input_case_option
|
|
10
|
+
# * readme
|
|
11
|
+
# * require_dsl_and_script
|
|
12
|
+
module Project
|
|
13
|
+
def self.test(pathtofile, options)
|
|
14
|
+
Application.instance.options.merge! options
|
|
15
|
+
NameFileFinder.find_filenames_for(pathtofile)
|
|
16
|
+
NameFileFinder.puts_input_info_on_screen
|
|
17
|
+
require_dsl_and_script('laboratory/laboratory') # Define DSL keywords
|
|
18
|
+
|
|
19
|
+
app = Application.instance
|
|
20
|
+
lab = Laboratory.new(app.script_path, app.config_path)
|
|
21
|
+
# lab.show_requests if options[:r]
|
|
22
|
+
lab.show_config if options[:c]
|
|
23
|
+
lab.show_dsl unless options[:r] || options[:c]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.play(pathtofile, options)
|
|
27
|
+
Application.instance.options.merge! options
|
|
28
|
+
process_input_case_option
|
|
29
|
+
NameFileFinder.find_filenames_for(pathtofile)
|
|
30
|
+
NameFileFinder.puts_input_info_on_screen
|
|
31
|
+
require_dsl_and_script('../case_manager/dsl') # Define DSL keywords
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.process_input_case_option
|
|
35
|
+
options = Application.instance.options
|
|
36
|
+
unless options['case'].nil?
|
|
37
|
+
a = options['case'].split(',')
|
|
38
|
+
options['case'] = a.collect! { |i| i.to_i }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.readme(pathtofile, options)
|
|
43
|
+
Application.instance.options.merge! options
|
|
44
|
+
NameFileFinder.find_filenames_for(pathtofile)
|
|
45
|
+
require_dsl_and_script('readme/readme') # Define DSL keywords
|
|
46
|
+
|
|
47
|
+
app = Application.instance
|
|
48
|
+
readme = Readme.new(app.script_path, app.config_path)
|
|
49
|
+
readme.show
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.require_dsl_and_script(dslpath)
|
|
53
|
+
app = Application.instance
|
|
54
|
+
require_relative dslpath
|
|
55
|
+
begin
|
|
56
|
+
require_relative app.script_path
|
|
57
|
+
rescue SyntaxError => e
|
|
58
|
+
puts e.to_s
|
|
59
|
+
puts Rainbow.new("[ERROR] SyntaxError into file #{app.script_path}").red
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'rainbow'
|
|
5
|
+
|
|
6
|
+
# Project#create
|
|
7
|
+
# * create
|
|
8
|
+
# * create_main_dir_and_files
|
|
9
|
+
# * create_assets_dir_and_files
|
|
10
|
+
# * create_dir
|
|
11
|
+
# * create_dirs
|
|
12
|
+
# * copyfile
|
|
13
|
+
module ProjectCreator
|
|
14
|
+
def self.create(project_dir)
|
|
15
|
+
project_name = File.basename(project_dir)
|
|
16
|
+
puts "\n[INFO] Creating #{Rainbow(project_name).bright} project skeleton"
|
|
17
|
+
|
|
18
|
+
source_basedir = File.join(File.dirname(__FILE__), '../..')
|
|
19
|
+
create_dir project_dir
|
|
20
|
+
|
|
21
|
+
create_main_dir_and_files(project_dir, source_basedir)
|
|
22
|
+
create_assets_dir_and_files(project_dir, source_basedir)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.create_main_dir_and_files(project_dir, source_basedir)
|
|
26
|
+
# Directory and files: Ruby script, Configfile, gitignore
|
|
27
|
+
items = [
|
|
28
|
+
{ source: 'lib/files/config.yaml', target: 'config.yaml' },
|
|
29
|
+
{ source: 'lib/files/start.rb', target: 'start.rb' },
|
|
30
|
+
{ source: 'lib/files/README.md', target: 'README.md' },
|
|
31
|
+
{ source: 'lib/files/gitignore', target: '.gitignore' }
|
|
32
|
+
]
|
|
33
|
+
items.each do |item|
|
|
34
|
+
source = File.join(source_basedir, item[:source])
|
|
35
|
+
target = File.join(project_dir, item[:target])
|
|
36
|
+
copyfile(source, target)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.create_assets_dir_and_files(project_dir, source_basedir)
|
|
41
|
+
# Assets Directory and files
|
|
42
|
+
project_assets_dir = File.join(project_dir, 'assets')
|
|
43
|
+
create_dir project_assets_dir
|
|
44
|
+
# source = File.join(source_basedir, 'lib/files/README.md')
|
|
45
|
+
# target = File.join(project_dir, 'README.md')
|
|
46
|
+
# copyfile(source, target) # README.md
|
|
47
|
+
puts ''
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.create_dir(dirpath)
|
|
51
|
+
if Dir.exist? dirpath
|
|
52
|
+
puts "* Exists dir! => #{Rainbow(dirpath).yellow}"
|
|
53
|
+
else
|
|
54
|
+
begin
|
|
55
|
+
FileUtils.mkdir_p(dirpath)
|
|
56
|
+
puts "* Create dir => #{Rainbow(dirpath).green}"
|
|
57
|
+
rescue StandarError
|
|
58
|
+
puts "* Create dir ERROR => #{Rainbow(dirpath).red}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.create_dirs(*args)
|
|
64
|
+
args.each { |arg| create_dir arg }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.copyfile(target, dest)
|
|
68
|
+
if File.exist? dest
|
|
69
|
+
puts "* Exists file! => #{Rainbow(dest).yellow}"
|
|
70
|
+
else
|
|
71
|
+
begin
|
|
72
|
+
FileUtils.cp(target, dest)
|
|
73
|
+
puts "* Create file => #{Rainbow(dest).green}"
|
|
74
|
+
rescue StandarError
|
|
75
|
+
puts "* Create file ERROR => #{Rainbow(dest).red}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Readme
|
|
4
|
+
# * target
|
|
5
|
+
# * goto
|
|
6
|
+
# * run
|
|
7
|
+
# * expect
|
|
8
|
+
# * unique
|
|
9
|
+
# * log
|
|
10
|
+
class Readme
|
|
11
|
+
def readme(text)
|
|
12
|
+
if @action[:target].nil?
|
|
13
|
+
# It's a group readme
|
|
14
|
+
@current[:readme] << text
|
|
15
|
+
else
|
|
16
|
+
# It's a target readme
|
|
17
|
+
@action[:readme] << text
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def target(desc, args = {})
|
|
22
|
+
previous_host = @action[:host]
|
|
23
|
+
@action = { target: desc, host: previous_host, readme: [] }
|
|
24
|
+
weight = 1.0
|
|
25
|
+
weight = args[:weight].to_f if args[:weight]
|
|
26
|
+
@action[:weight] = weight
|
|
27
|
+
end
|
|
28
|
+
alias goal target
|
|
29
|
+
|
|
30
|
+
def goto(host = :localhost, args = {})
|
|
31
|
+
unless host == :localhost
|
|
32
|
+
b = {}
|
|
33
|
+
a = "#{host}_ip".to_sym
|
|
34
|
+
if @config[:global][a].nil? && (not @setted_params.include?(a))
|
|
35
|
+
@cases_params << a
|
|
36
|
+
end
|
|
37
|
+
b[:ip] = @config[:global][a] if @config[:global][a]
|
|
38
|
+
b[:ip] = @setted_params[a] if @setted_params[a]
|
|
39
|
+
|
|
40
|
+
a = "#{host}_username".to_sym
|
|
41
|
+
if @config[:global][a].nil? && (not @setted_params.include?(a))
|
|
42
|
+
@cases_params << a
|
|
43
|
+
end
|
|
44
|
+
b[:username] = @config[:global][a] if @config[:global][a]
|
|
45
|
+
b[:username] = @setted_params[a] if @setted_params[a]
|
|
46
|
+
|
|
47
|
+
a = "#{host}_password".to_sym
|
|
48
|
+
if @config[:global][a].nil? && (not @setted_params.include?(a))
|
|
49
|
+
@cases_params << a
|
|
50
|
+
end
|
|
51
|
+
b[:password] = @config[:global][a] if @config[:global][a]
|
|
52
|
+
b[:password] = @setted_params[a] if @setted_params[a]
|
|
53
|
+
|
|
54
|
+
@required_hosts[host.to_s] = b
|
|
55
|
+
end
|
|
56
|
+
@action[:host] = host
|
|
57
|
+
@action[:exec] = args[:exec] || 'noexec'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def run(command, args = {})
|
|
61
|
+
args[:exec] = command
|
|
62
|
+
goto(:localhost, args)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def expect(_cond, args = {})
|
|
66
|
+
@current[:actions] << @action
|
|
67
|
+
result.reset
|
|
68
|
+
end
|
|
69
|
+
alias expect_any expect
|
|
70
|
+
alias expect_none expect
|
|
71
|
+
alias expect_one expect
|
|
72
|
+
|
|
73
|
+
def get(value)
|
|
74
|
+
unless @config[:global][value].nil?
|
|
75
|
+
@global_params[value] = @config[:global][value]
|
|
76
|
+
return @config[:global][value]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
return value.to_s.upcase if @setted_params.include? value
|
|
80
|
+
|
|
81
|
+
@cases_params << value
|
|
82
|
+
value.to_s.upcase
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# If a method call is missing, then delegate to concept parent.
|
|
86
|
+
def method_missing(method)
|
|
87
|
+
a = method.to_s
|
|
88
|
+
instance_eval("get(:#{a[0, a.size - 1]})") if a[a.size - 1] == '?'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def gett(value)
|
|
92
|
+
a = get(value)
|
|
93
|
+
return "[#{value}](\#required-params)" if @cases_params.include? value
|
|
94
|
+
return "[#{value}](\#created-params)" if @setted_params[value]
|
|
95
|
+
"[#{a}](\#global-params)" if @global_params.include? value
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def set(key, value)
|
|
99
|
+
@setted_params[key] = value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def unique(_key, _value)
|
|
103
|
+
# don't do nothing
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def log(text = '', type = :info)
|
|
107
|
+
@data[:logs] << "[#{type}]: " + text.to_s
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative '../../application'
|
|
3
|
+
|
|
4
|
+
module Lang
|
|
5
|
+
def self.get(key)
|
|
6
|
+
lang = {}
|
|
7
|
+
lang['en'] = {
|
|
8
|
+
version: 'Teuton version : %s',
|
|
9
|
+
testname: 'Challenge name : %s',
|
|
10
|
+
date: 'Date : %s',
|
|
11
|
+
hosts: "\n\#\#\# Required hosts\n",
|
|
12
|
+
params: "\n\#\#\# Required params\n",
|
|
13
|
+
goto: "\nGo to [%s](\#required-hosts) host, and do next:\n",
|
|
14
|
+
global: "\nGlobal parameters that can be modified:\n",
|
|
15
|
+
created: "\nParams created during challenge execution:\n"
|
|
16
|
+
}
|
|
17
|
+
lang['es'] = {
|
|
18
|
+
version: 'Versión de Teuton : %s',
|
|
19
|
+
testname: 'Nombre del reto : %s',
|
|
20
|
+
date: 'Fecha : %s',
|
|
21
|
+
hosts: "\n\#\#\# Máquinas que se necesitan\n",
|
|
22
|
+
params: "\n\#\#\# Parámetros de necesarios\n",
|
|
23
|
+
goto: "\nIr a la máquina [%s](\#required-hosts), y hacer lo siguiente:\n",
|
|
24
|
+
global: "\nParámetros globales que pueden ser modificados:\n",
|
|
25
|
+
created: "\nParámetros creados durante la ejecución del reto:\n"
|
|
26
|
+
}
|
|
27
|
+
locale = Application.instance.options['lang'].downcase
|
|
28
|
+
lang[locale][key]
|
|
29
|
+
end
|
|
30
|
+
end
|