osp 0.6.1 → 0.7.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 +5 -5
- data/.editorconfig +5 -4
- data/.env.example +2 -0
- data/.gitignore +4 -3
- data/.gitlab-ci.yml +37 -37
- data/.travis.yml +17 -16
- data/README.md +6 -2
- data/Vagrantfile +34 -0
- data/bin/.gitignore +1 -0
- data/bin/dev_setup.sh +19 -0
- data/bin/install.sh +51 -0
- data/bin/osp +342 -329
- data/bin/release.sh +37 -0
- data/bin/test.sh +15 -0
- data/bin/uninstall.sh +24 -0
- data/lib/ext/string.rb +3 -3
- data/lib/osp/database.rb +195 -184
- data/lib/osp/host.rb +112 -116
- data/lib/osp/osp.rb +185 -150
- data/lib/osp/ospdev.rb +12 -10
- data/lib/osp/ospdotcom.rb +14 -14
- data/lib/osp/version.rb +5 -5
- data/osp.gemspec +25 -25
- data/osp.sublime-project +8 -8
- metadata +11 -5
- data/Makefile +0 -21
- data/Makefile.common +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 86f11c7cb6af7a4b1a75643ea75910022c5bd1dee4f369e4f97ef51595dc8841
|
4
|
+
data.tar.gz: c4e7a36a5c4caa26f304068170319cb0a47140bfd732d0a3f2d88a32b793c886
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea147ab56fbc29c8d407039075f6ecb2bb6739f291dc513924848570c245043b18eaa3472b745fe69df319ed9b2b8c67ad8d3650148ff1093c531f4a79d9bc41
|
7
|
+
data.tar.gz: 588e29ef9b6108b9f74cb5f8d4b0b2f1279c125ca69acd75b4f46a8e808e89baf69c5411d2ecfc55daa59f94926972636b5f74a96339902ea5cf91cc5abd8598
|
data/.editorconfig
CHANGED
@@ -3,12 +3,13 @@
|
|
3
3
|
root = true
|
4
4
|
|
5
5
|
[*]
|
6
|
-
indent_style =
|
7
|
-
indent_size =
|
6
|
+
indent_style = space
|
7
|
+
indent_size = 2
|
8
8
|
end_of_line = lf
|
9
9
|
charset = utf-8
|
10
10
|
trim_trailing_whitespace = false
|
11
11
|
insert_final_newline = true
|
12
12
|
|
13
|
-
[*.
|
14
|
-
indent_style =
|
13
|
+
[*.sh]
|
14
|
+
indent_style = tab
|
15
|
+
indent_size = 4
|
data/.env.example
ADDED
data/.gitignore
CHANGED
data/.gitlab-ci.yml
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
before_script:
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
- gem update --system
|
3
|
+
- gem install bundler -v '~>1.13'
|
4
|
+
- bundler --version
|
5
|
+
- bundler install
|
6
6
|
|
7
7
|
stages:
|
8
|
-
|
9
|
-
|
8
|
+
- test
|
9
|
+
- release
|
10
10
|
|
11
11
|
test_21:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
image: ruby:2.1
|
13
|
+
stage: test
|
14
|
+
environment: test
|
15
|
+
only:
|
16
|
+
- tags
|
17
|
+
script:
|
18
|
+
- ./bin/test.sh
|
19
19
|
|
20
20
|
test_22:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
image: ruby:2.2
|
22
|
+
stage: test
|
23
|
+
environment: test
|
24
|
+
only:
|
25
|
+
- tags
|
26
|
+
script:
|
27
|
+
- ./bin/test.sh
|
28
28
|
|
29
29
|
test_23:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
image: ruby:2.3
|
31
|
+
stage: test
|
32
|
+
environment: test
|
33
|
+
only:
|
34
|
+
- tags
|
35
|
+
script:
|
36
|
+
- ./bin/test.sh
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
38
|
+
release:
|
39
|
+
image: ruby:2.4
|
40
|
+
stage: release
|
41
|
+
environment: gem
|
42
|
+
only:
|
43
|
+
- tags
|
44
|
+
script:
|
45
|
+
- mkdir -p ~/.gem
|
46
|
+
- 'printf "%s\n:rubygems_api_key: %s" "---" "${RUBYGEMSORG_API_KEY}" > ~/.gem/credentials; chmod 0600 ~/.gem/credentials'
|
47
|
+
- ./bin/release.sh
|
data/.travis.yml
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
- 2.1
|
4
|
+
- 2.2
|
5
|
+
- 2.3
|
6
|
+
- 2.4.0
|
7
|
+
- 2.5.0
|
8
|
+
- ruby-head
|
8
9
|
sudo: required
|
9
10
|
before_install:
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
- gem update --system
|
12
|
+
- gem install bundler -v '~>1.13'
|
13
|
+
- bundler --version
|
13
14
|
install:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
- bundler install
|
16
|
+
- gem build osp.gemspec
|
17
|
+
- gem install osp-*.gem
|
18
|
+
- gem list -l osp
|
18
19
|
script:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
- ./bin/test.sh
|
21
|
+
- cd
|
22
|
+
- which -a osp
|
23
|
+
- osp --version
|
data/README.md
CHANGED
@@ -5,11 +5,15 @@
|
|
5
5
|
The preferred method of installation is via RubyGems.org:
|
6
6
|
<https://rubygems.org/gems/osp>
|
7
7
|
|
8
|
-
|
8
|
+
```sh
|
9
|
+
$ gem install osp
|
10
|
+
```
|
9
11
|
|
10
12
|
or via `Gemfile`:
|
11
13
|
|
12
|
-
|
14
|
+
```sh
|
15
|
+
$ gem 'osp', '~>0.6'
|
16
|
+
```
|
13
17
|
|
14
18
|
## Project Links
|
15
19
|
|
data/Vagrantfile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
Vagrant.configure("2") do |config|
|
5
|
+
config.vm.box = "generic/debian9"
|
6
|
+
config.vm.box_check_update = false
|
7
|
+
|
8
|
+
config.vm.hostname = 'osp'
|
9
|
+
# config.vm.network "forwarded_port", guest: 3000, host: 3000
|
10
|
+
|
11
|
+
# config.vm.network "private_network", ip: "192.168.33.10"
|
12
|
+
config.vm.synced_folder ".", "/app"
|
13
|
+
|
14
|
+
config.vm.provider "virtualbox" do |vb|
|
15
|
+
vb.gui = false
|
16
|
+
vb.memory = 1024
|
17
|
+
end
|
18
|
+
|
19
|
+
config.vm.provision "shell" do |s|
|
20
|
+
s.env = {
|
21
|
+
'DEBIAN_FRONTEND' => 'noninteractive',
|
22
|
+
}
|
23
|
+
s.inline = <<-SHELL
|
24
|
+
apt-get update -yqq
|
25
|
+
apt-get upgrade -y
|
26
|
+
apt-get install -y htop vim ack-grep lsof net-tools rsync ruby ruby-dev
|
27
|
+
|
28
|
+
gem update --system && \
|
29
|
+
gem install bundler -v '~>1.13.0'
|
30
|
+
|
31
|
+
echo 'done'
|
32
|
+
SHELL
|
33
|
+
end
|
34
|
+
end
|
data/bin/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
test.rb
|
data/bin/dev_setup.sh
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Development setup.
|
4
|
+
|
5
|
+
SCRIPT_BASEDIR=$(dirname "$0")
|
6
|
+
|
7
|
+
|
8
|
+
set -e
|
9
|
+
which cp &> /dev/null || { echo 'ERROR: cp not found in PATH'; exit 1; }
|
10
|
+
which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
|
11
|
+
|
12
|
+
cd "${SCRIPT_BASEDIR}/.."
|
13
|
+
|
14
|
+
# Create .env file.
|
15
|
+
if [[ ! -f .env ]]; then
|
16
|
+
cp .env.example .env
|
17
|
+
fi
|
18
|
+
|
19
|
+
bundler install
|
data/bin/install.sh
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Install Gem local.
|
4
|
+
|
5
|
+
SCRIPT_BASEDIR=$(dirname "$0")
|
6
|
+
|
7
|
+
|
8
|
+
option=$1
|
9
|
+
set -e
|
10
|
+
which mkdir &> /dev/null || { echo 'ERROR: mkdir not found in PATH'; exit 1; }
|
11
|
+
which mv &> /dev/null || { echo 'ERROR: mv not found in PATH'; exit 1; }
|
12
|
+
which chmod &> /dev/null || { echo 'ERROR: chmod not found in PATH'; exit 1; }
|
13
|
+
which gem &> /dev/null || { echo 'ERROR: gem not found in PATH'; exit 1; }
|
14
|
+
which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
|
15
|
+
|
16
|
+
cd "${SCRIPT_BASEDIR}/.."
|
17
|
+
|
18
|
+
# Load Environment Variables
|
19
|
+
[[ -f .env ]] && source .env
|
20
|
+
|
21
|
+
if [[ -z "${GEMSPEC_FILE}" ]] ; then
|
22
|
+
echo 'ERROR: one of the environment variables is missing'
|
23
|
+
|
24
|
+
echo "GEMSPEC_FILE: '${GEMSPEC_FILE}'"
|
25
|
+
|
26
|
+
exit 1
|
27
|
+
fi
|
28
|
+
|
29
|
+
gem_file=$(gem build "${GEMSPEC_FILE}" 2> /dev/null | grep 'File:' | tail -1 | awk '{ print $2 }')
|
30
|
+
|
31
|
+
if [[ -z "$gem_file" ]] ; then
|
32
|
+
echo 'ERROR: gem_file variable not set'
|
33
|
+
exit 1
|
34
|
+
fi
|
35
|
+
|
36
|
+
echo "install gem file '$gem_file'"
|
37
|
+
gem install "$gem_file"
|
38
|
+
|
39
|
+
# Create tmp directory.
|
40
|
+
if [[ ! -d tmp/releases ]]; then
|
41
|
+
mkdir -p tmp/releases
|
42
|
+
|
43
|
+
chmod u=rwx,go-rwx tmp
|
44
|
+
chmod u=rwx,go-rwx tmp/releases
|
45
|
+
fi
|
46
|
+
|
47
|
+
if [[ "$option" = "-f" ]]; then
|
48
|
+
mv -v "$gem_file" tmp/releases
|
49
|
+
else
|
50
|
+
mv -v -i "$gem_file" tmp/releases
|
51
|
+
fi
|
data/bin/osp
CHANGED
@@ -9,35 +9,35 @@ require 'osp'
|
|
9
9
|
|
10
10
|
|
11
11
|
@options = {
|
12
|
-
|
13
|
-
|
12
|
+
:database_path => Pathname.new('.osp').expand_path(Dir.home),
|
13
|
+
:database_lock_path => Pathname.new('.osp~lock').expand_path(Dir.home),
|
14
14
|
}
|
15
15
|
opts = OptionParser.new do |o|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
o.banner = 'Usage: osp [options]'
|
17
|
+
o.separator('')
|
18
|
+
|
19
|
+
o.on('-d', '--database <path>', 'Path to the database file.') do |path|
|
20
|
+
@options[:database_path] = Pathname.new(path).expand_path
|
21
|
+
@options[:database_lock_path] = Pathname.new("#{@options[:database_path]}~lock").expand_path
|
22
|
+
end
|
23
|
+
|
24
|
+
o.on_tail('-V', '--version', 'Show version.') do
|
25
|
+
puts "osp #{TheFox::OSP::VERSION} (#{TheFox::OSP::DATE})"
|
26
|
+
puts TheFox::OSP::HOMEPAGE
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
o.on_tail('-h', '--help', 'Show this message.') do
|
31
|
+
puts o
|
32
|
+
puts
|
33
|
+
exit 3
|
34
|
+
end
|
35
35
|
end
|
36
36
|
opts.parse(ARGV)
|
37
37
|
|
38
38
|
|
39
39
|
if !STDIN.tty?
|
40
|
-
|
40
|
+
raise "STDIN isn't a TTY."
|
41
41
|
end
|
42
42
|
|
43
43
|
@cli = HighLine.new
|
@@ -47,12 +47,12 @@ puts TheFox::OSP::HOMEPAGE
|
|
47
47
|
puts
|
48
48
|
|
49
49
|
if @options[:database_lock_path].exist?
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
puts "WARNING: lock file exist: '#{@options[:database_lock_path]}'"
|
51
|
+
overwrite = @cli.ask('Overwrite? '){ |q| q.default = 'n' }.downcase
|
52
|
+
if overwrite == 'n'
|
53
|
+
puts 'Quit.'
|
54
|
+
exit
|
55
|
+
end
|
56
56
|
end
|
57
57
|
File.write(@options[:database_lock_path], 'tmp')
|
58
58
|
@options[:database_lock_path].chmod(0600)
|
@@ -60,11 +60,19 @@ File.binwrite(@options[:database_lock_path], Process.pid)
|
|
60
60
|
|
61
61
|
puts 'Master Login'
|
62
62
|
if $DEBUG
|
63
|
-
|
64
|
-
|
63
|
+
email = 'example@example.com'
|
64
|
+
password1 = 'password'
|
65
|
+
password2 = 'password'
|
65
66
|
else
|
66
|
-
|
67
|
-
|
67
|
+
email = @cli.ask(' Email: ')
|
68
|
+
password1 = @cli.ask('Password: '){ |q| q.echo = '*' }
|
69
|
+
password2 = @cli.ask(' Confirm: '){ |q| q.echo = '*' }
|
70
|
+
|
71
|
+
if password1 != password2
|
72
|
+
remove_lock
|
73
|
+
puts 'Passwords do not match.'
|
74
|
+
exit 1
|
75
|
+
end
|
68
76
|
end
|
69
77
|
|
70
78
|
Console.cursor_jump_to_column
|
@@ -74,335 +82,340 @@ puts ' Email: *****'
|
|
74
82
|
puts 'Password: *****'
|
75
83
|
puts
|
76
84
|
|
77
|
-
|
78
|
-
@osp_class = TheFox::OSP::OSPDev
|
85
|
+
if $DEBUG
|
86
|
+
@osp_class = TheFox::OSP::OSPDev
|
87
|
+
else
|
88
|
+
@osp_class = TheFox::OSP::OSP
|
89
|
+
end
|
79
90
|
|
80
|
-
|
81
|
-
@
|
91
|
+
print 'Calculating base hash: %d (%d-bit) - please wait ...' % [
|
92
|
+
@osp_class::HASHES_N, @osp_class::HASHES_EXP,
|
93
|
+
]
|
94
|
+
@osp = @osp_class.new(email, password1)
|
82
95
|
@osp.key_derivation
|
83
96
|
puts ' done'
|
84
97
|
|
85
98
|
def database_load_step(step, msg)
|
86
|
-
|
99
|
+
puts "#{step} #{msg}"
|
87
100
|
end
|
88
101
|
|
89
102
|
def database_write_step(step, msg)
|
90
|
-
|
103
|
+
puts "#{step} #{msg}"
|
91
104
|
end
|
92
105
|
|
93
106
|
def remove_lock
|
94
|
-
|
95
|
-
|
96
|
-
|
107
|
+
if @options[:database_lock_path].exist?
|
108
|
+
@options[:database_lock_path].unlink
|
109
|
+
end
|
97
110
|
end
|
98
111
|
|
99
112
|
@database = TheFox::OSP::Database.new(@options[:database_path], @osp)
|
100
113
|
@database.load_callback_method = self.method('database_load_step')
|
101
114
|
@database.write_callback_method = self.method('database_write_step')
|
102
115
|
begin
|
103
|
-
|
116
|
+
@database.load
|
104
117
|
rescue Exception => e
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
118
|
+
puts
|
119
|
+
puts "FATAL ERROR: couldn't open database:"
|
120
|
+
puts "#{e}"
|
121
|
+
remove_lock
|
122
|
+
exit 1
|
110
123
|
end
|
111
124
|
|
112
125
|
def password_callback_method(step, pw)
|
113
|
-
|
126
|
+
printf '.'
|
114
127
|
end
|
115
128
|
@osp.password_callback_method = self.method('password_callback_method')
|
116
129
|
|
117
130
|
def host_show(host, regenerate_password = false)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
131
|
+
if !host.has_generated_password? || regenerate_password
|
132
|
+
print 'Generate password '
|
133
|
+
host.generate_password(regenerate_password)
|
134
|
+
puts ' done'
|
135
|
+
end
|
136
|
+
|
137
|
+
puts " Hostname: #{host.name}"
|
138
|
+
puts "Generation: #{host.generation}"
|
139
|
+
puts " Length: #{host.length}"
|
140
|
+
puts " Symbols: #{host.symbols}"
|
141
|
+
puts " Hashes: #{host.hashes}"
|
142
|
+
puts " Password: #{host.password}"
|
130
143
|
end
|
131
144
|
|
132
145
|
def host_edit(host = nil)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
146
|
+
host = TheFox::OSP::Host.new(@osp) if host.nil?
|
147
|
+
|
148
|
+
puts
|
149
|
+
puts 'New Host'
|
150
|
+
puts
|
151
|
+
|
152
|
+
tmp = @cli.ask(' Hostname: ' + (host.name.nil? ? '[]' : "[#{host.name}]") + ' ').strip.to_s
|
153
|
+
host.name = tmp if tmp != ''
|
154
|
+
host.name = nil if host.name == ''
|
155
|
+
if host.name.nil?
|
156
|
+
return nil
|
157
|
+
end
|
158
|
+
|
159
|
+
host.generation = @cli.ask("Generation: [#{host.generation}] ", Integer){ |q|
|
160
|
+
q.default = host.generation
|
161
|
+
q.in = 1..99 }.to_i
|
162
|
+
|
163
|
+
host.length = @cli.ask(" Length: [#{host.length}] ", Integer){ |q|
|
164
|
+
q.default = host.length
|
165
|
+
q.in = @osp_class::PASSWORD_MIN_SIZE..@osp_class::PASSWORD_MAX_SIZE }.to_i
|
166
|
+
|
167
|
+
host.symbols = @cli.ask(" Symbols: [#{host.symbols}] ", Integer){ |q|
|
168
|
+
q.default = host.symbols
|
169
|
+
q.in = 0..3 }.to_i
|
170
|
+
|
171
|
+
host.updated_at = DateTime.now
|
172
|
+
|
173
|
+
host
|
161
174
|
end
|
162
175
|
|
163
176
|
actions = ['begin']
|
164
177
|
while true
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
178
|
+
case actions.pop
|
179
|
+
when 'begin'
|
180
|
+
puts
|
181
|
+
puts "Type '?' for help."
|
182
|
+
when 'n'
|
183
|
+
puts
|
184
|
+
host = host_edit
|
185
|
+
if !host.nil?
|
186
|
+
host_show(host)
|
187
|
+
puts
|
188
|
+
|
189
|
+
add = @cli.ask('Add to database? [yN] ', String){ |q| q.character = true }.strip.downcase
|
190
|
+
add = 'n' if add == ''
|
191
|
+
puts "Answer: '#{add}'"
|
192
|
+
|
193
|
+
if add == 'y'
|
194
|
+
@database.add_host(host)
|
195
|
+
end
|
196
|
+
else
|
197
|
+
puts "ERROR: hostname can't be nothing."
|
198
|
+
end
|
199
|
+
when 'l'
|
200
|
+
puts
|
201
|
+
puts 'List Hosts'
|
202
|
+
puts
|
203
|
+
|
204
|
+
hosts_n = @database.hosts.count
|
205
|
+
format = '%' + hosts_n.to_s.length.to_s + 'd'
|
206
|
+
|
207
|
+
n = 0
|
208
|
+
@database.hosts.values.each do |h|
|
209
|
+
n += 1
|
210
|
+
printf "#{format}. %s\n", n, h.name
|
211
|
+
end
|
212
|
+
when 's'
|
213
|
+
found_hosts = []
|
214
|
+
|
215
|
+
search_actions = ['begin']
|
216
|
+
while true
|
217
|
+
case search_actions.pop
|
218
|
+
when 'begin'
|
219
|
+
puts
|
220
|
+
puts 'Entering search submenu.'
|
221
|
+
|
222
|
+
search_actions << 's'
|
223
|
+
when 's'
|
224
|
+
puts
|
225
|
+
|
226
|
+
host_name = @cli.ask('Search host names: ', String).strip.downcase
|
227
|
+
re = Regexp.new(host_name, Regexp::IGNORECASE)
|
228
|
+
|
229
|
+
found_hosts = @database.hosts.select{ |name, h| re.match(h.name) }
|
230
|
+
|
231
|
+
search_actions << 'l'
|
232
|
+
when 'l'
|
233
|
+
puts
|
234
|
+
if found_hosts.count > 0
|
235
|
+
puts "#{found_hosts.count} host(s) found:"
|
236
|
+
|
237
|
+
hosts_n = found_hosts.count
|
238
|
+
format = '%' + hosts_n.to_s.length.to_s + 'd'
|
239
|
+
n = 0
|
240
|
+
found_hosts.each do |name, h|
|
241
|
+
n += 1
|
242
|
+
printf "#{format}. %s\n", n, h.name
|
243
|
+
end
|
244
|
+
else
|
245
|
+
puts 'No hosts found.'
|
246
|
+
end
|
247
|
+
when 'i'
|
248
|
+
puts
|
249
|
+
if found_hosts.count > 0
|
250
|
+
index = 1
|
251
|
+
if found_hosts.count > 1
|
252
|
+
index = @cli.ask('Show host, select by number: ', Integer){ |q|
|
253
|
+
q.character = true if found_hosts.count < 10 }.to_i
|
254
|
+
puts
|
255
|
+
end
|
256
|
+
|
257
|
+
if index >= 1 && index <= found_hosts.count
|
258
|
+
puts "Host ##{index} selected:"
|
259
|
+
index -= 1
|
260
|
+
selected_host = nil
|
261
|
+
begin
|
262
|
+
selected_host = found_hosts.values[index]
|
263
|
+
rescue Exception => e
|
264
|
+
puts "ERROR: #{e}"
|
265
|
+
end
|
266
|
+
|
267
|
+
if !selected_host.nil?
|
268
|
+
host_show(selected_host)
|
269
|
+
end
|
270
|
+
else
|
271
|
+
puts 'Abort.'
|
272
|
+
end
|
273
|
+
else
|
274
|
+
puts 'No hosts found.'
|
275
|
+
end
|
276
|
+
when 'e'
|
277
|
+
puts
|
278
|
+
if found_hosts.count > 0
|
279
|
+
index = 1
|
280
|
+
if found_hosts.count > 1
|
281
|
+
index = @cli.ask('Edit, select host by number: ', Integer){ |q|
|
282
|
+
q.character = true if found_hosts.count < 10 }.to_i
|
283
|
+
puts
|
284
|
+
end
|
285
|
+
|
286
|
+
if index >= 1 && index <= found_hosts.count
|
287
|
+
puts "Host ##{index} selected:"
|
288
|
+
index -= 1
|
289
|
+
selected_host = nil
|
290
|
+
begin
|
291
|
+
selected_host = found_hosts.values[index].clone
|
292
|
+
rescue Exception => e
|
293
|
+
puts "ERROR: #{e}"
|
294
|
+
end
|
295
|
+
|
296
|
+
if !selected_host.nil?
|
297
|
+
host_edit(selected_host)
|
298
|
+
host_show(selected_host, true)
|
299
|
+
|
300
|
+
@database.add_host(selected_host)
|
301
|
+
end
|
302
|
+
else
|
303
|
+
puts 'Abort.'
|
304
|
+
end
|
305
|
+
else
|
306
|
+
puts 'No hosts found.'
|
307
|
+
end
|
308
|
+
when 'd'
|
309
|
+
puts
|
310
|
+
if found_hosts.count > 0
|
311
|
+
index = 1
|
312
|
+
if found_hosts.count > 1
|
313
|
+
index = @cli.ask('Delete, select host by number: ', Integer){ |q|
|
314
|
+
q.character = true if found_hosts.count < 10 }.to_i
|
315
|
+
puts
|
316
|
+
end
|
317
|
+
|
318
|
+
if index >= 1 && index <= found_hosts.count
|
319
|
+
puts "Delete host ##{index}."
|
320
|
+
index -= 1
|
321
|
+
selected_host = nil
|
322
|
+
begin
|
323
|
+
selected_host = found_hosts.values[index]
|
324
|
+
rescue Exception => e
|
325
|
+
puts "ERROR: #{e}"
|
326
|
+
end
|
327
|
+
|
328
|
+
if !selected_host.nil?
|
329
|
+
if @database.remove_host(selected_host)
|
330
|
+
found_hosts.delete(selected_host.name)
|
331
|
+
puts "Host '#{selected_host.name}' deleted."
|
332
|
+
else
|
333
|
+
puts "ERROR: Can't delete host '#{selected_host.name}'."
|
334
|
+
end
|
335
|
+
end
|
336
|
+
else
|
337
|
+
puts 'Abort.'
|
338
|
+
end
|
339
|
+
else
|
340
|
+
puts 'No hosts found.'
|
341
|
+
end
|
342
|
+
when 'c'
|
343
|
+
system('clear')
|
344
|
+
when 'q'
|
345
|
+
break
|
346
|
+
when '?'
|
347
|
+
puts
|
348
|
+
puts 'Search-menu help:'
|
349
|
+
puts "\ts - New search."
|
350
|
+
puts "\tl - List found hosts."
|
351
|
+
puts "\ti - Print informations about a host found by a search."
|
352
|
+
puts "\te - Edit a host found by search."
|
353
|
+
puts "\td - Delete a host found by search."
|
354
|
+
puts "\tc - Clear screen."
|
355
|
+
puts "\tq - Quit search."
|
356
|
+
puts "\t? - Print help."
|
357
|
+
else
|
358
|
+
puts "WARNING: invalid input. Type '?' for help."
|
359
|
+
end
|
360
|
+
|
361
|
+
next if search_actions.count > 0
|
362
|
+
|
363
|
+
puts
|
364
|
+
search_actions << @cli.ask('[sliedcq?] >> '){ |q| q.character = true }.downcase
|
365
|
+
end
|
366
|
+
when 'c'
|
367
|
+
system('clear')
|
368
|
+
when 'x'
|
369
|
+
actions << 'q'
|
370
|
+
actions << 'w'
|
371
|
+
when 'w'
|
372
|
+
@database.write
|
373
|
+
when 'q'
|
374
|
+
if @database.has_changed
|
375
|
+
puts
|
376
|
+
puts 'You have unsaved database changes.'
|
377
|
+
|
378
|
+
save = @cli.ask('Would you like to save the database? [Yn] ', String){ |q| q.character = true }.strip.downcase
|
379
|
+
save = 'y' if save == ''
|
380
|
+
puts "Answer: '#{save}'"
|
381
|
+
|
382
|
+
if save == 'y'
|
383
|
+
actions << 'x'
|
384
|
+
else
|
385
|
+
really = @cli.ask('Really? [yN] ', String){ |q| q.character = true }.strip.downcase
|
386
|
+
really = 'n' if really == ''
|
387
|
+
puts "Answer: '#{really}'"
|
388
|
+
|
389
|
+
if really == 'y'
|
390
|
+
@database.has_changed = false
|
391
|
+
actions << 'q'
|
392
|
+
else
|
393
|
+
puts 'Qutting aborted.'
|
394
|
+
end
|
395
|
+
end
|
396
|
+
else
|
397
|
+
puts 'Quit.'
|
398
|
+
break
|
399
|
+
end
|
400
|
+
when '?'
|
401
|
+
puts
|
402
|
+
puts 'Main-menu help:'
|
403
|
+
puts "\tn - New password."
|
404
|
+
puts "\tl - List hosts from database."
|
405
|
+
puts "\ts - Search submenu."
|
406
|
+
puts "\tc - Clear screen."
|
407
|
+
puts "\tx - Same as wq."
|
408
|
+
puts "\tw - Write database to file."
|
409
|
+
puts "\tq - Quit."
|
410
|
+
puts "\t? - Print help."
|
411
|
+
else
|
412
|
+
puts "WARNING: invalid input. Type '?' for help."
|
413
|
+
end
|
414
|
+
|
415
|
+
next if actions.count > 0
|
416
|
+
|
417
|
+
puts
|
418
|
+
actions << @cli.ask('[nlscxwq?] > '){ |q| q.character = true }.downcase
|
406
419
|
end
|
407
420
|
|
408
421
|
remove_lock
|