greenhat 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +64 -0
- data/bin/greenhat +12 -0
- data/lib/greenhat.rb +80 -0
- data/lib/greenhat/accessors/disk.rb +27 -0
- data/lib/greenhat/accessors/logs/production.rb +41 -0
- data/lib/greenhat/accessors/logs/sidekiq.rb +41 -0
- data/lib/greenhat/accessors/memory.rb +46 -0
- data/lib/greenhat/accessors/network.rb +8 -0
- data/lib/greenhat/accessors/process.rb +8 -0
- data/lib/greenhat/archive.rb +108 -0
- data/lib/greenhat/cli.rb +448 -0
- data/lib/greenhat/host.rb +182 -0
- data/lib/greenhat/logbot.rb +86 -0
- data/lib/greenhat/pry_helpers.rb +51 -0
- data/lib/greenhat/settings.rb +51 -0
- data/lib/greenhat/shell.rb +92 -0
- data/lib/greenhat/shell/cat.rb +125 -0
- data/lib/greenhat/shell/disk.rb +68 -0
- data/lib/greenhat/shell/faststats.rb +195 -0
- data/lib/greenhat/shell/gitlab.rb +45 -0
- data/lib/greenhat/shell/help.rb +15 -0
- data/lib/greenhat/shell/helper.rb +514 -0
- data/lib/greenhat/shell/log.rb +344 -0
- data/lib/greenhat/shell/memory.rb +31 -0
- data/lib/greenhat/shell/network.rb +12 -0
- data/lib/greenhat/shell/process.rb +12 -0
- data/lib/greenhat/shell/report.rb +319 -0
- data/lib/greenhat/thing.rb +121 -0
- data/lib/greenhat/thing/file_types.rb +705 -0
- data/lib/greenhat/thing/formatters/api_json.rb +34 -0
- data/lib/greenhat/thing/formatters/bracket_log.rb +44 -0
- data/lib/greenhat/thing/formatters/clean_raw.rb +23 -0
- data/lib/greenhat/thing/formatters/colon_split_strip.rb +12 -0
- data/lib/greenhat/thing/formatters/dotenv.rb +10 -0
- data/lib/greenhat/thing/formatters/format.rb +12 -0
- data/lib/greenhat/thing/formatters/free_m.rb +29 -0
- data/lib/greenhat/thing/formatters/gitlab_ctl_tail.rb +51 -0
- data/lib/greenhat/thing/formatters/gitlab_status.rb +26 -0
- data/lib/greenhat/thing/formatters/json.rb +63 -0
- data/lib/greenhat/thing/formatters/json_shellwords.rb +44 -0
- data/lib/greenhat/thing/formatters/multiline_json.rb +10 -0
- data/lib/greenhat/thing/formatters/raw.rb +18 -0
- data/lib/greenhat/thing/formatters/shellwords.rb +23 -0
- data/lib/greenhat/thing/formatters/table.rb +26 -0
- data/lib/greenhat/thing/formatters/time_json.rb +21 -0
- data/lib/greenhat/thing/formatters/time_shellwords.rb +28 -0
- data/lib/greenhat/thing/formatters/time_space.rb +36 -0
- data/lib/greenhat/thing/helpers.rb +71 -0
- data/lib/greenhat/thing/history.rb +51 -0
- data/lib/greenhat/thing/info_format.rb +193 -0
- data/lib/greenhat/thing/kind.rb +97 -0
- data/lib/greenhat/thing/spinner.rb +52 -0
- data/lib/greenhat/thing/super_log.rb +102 -0
- data/lib/greenhat/tty/custom_line.rb +29 -0
- data/lib/greenhat/tty/line.rb +326 -0
- data/lib/greenhat/tty/reader.rb +110 -0
- data/lib/greenhat/version.rb +3 -0
- data/lib/greenhat/views/css.slim +126 -0
- data/lib/greenhat/views/disk_free.slim +18 -0
- data/lib/greenhat/views/index.slim +51 -0
- data/lib/greenhat/views/info.slim +39 -0
- data/lib/greenhat/views/manifest.slim +22 -0
- data/lib/greenhat/views/memory.slim +18 -0
- data/lib/greenhat/views/netstat.slim +20 -0
- data/lib/greenhat/views/process.slim +21 -0
- data/lib/greenhat/views/systemctl.slim +40 -0
- data/lib/greenhat/views/ulimit.slim +15 -0
- data/lib/greenhat/web.rb +46 -0
- metadata +476 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# https :/ / github.com / piotrmurach / tty - reader / blob / master / lib / tty / reader.rb
|
4
|
+
|
5
|
+
# Disabling Since this is a Shim
|
6
|
+
# rubocop:disable all
|
7
|
+
|
8
|
+
module TTY
|
9
|
+
# A class responsible for reading character input from STDIN
|
10
|
+
#
|
11
|
+
# Used internally to provide key and line reading functionality
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
class Reader
|
15
|
+
attr_accessor :line, :breaker
|
16
|
+
|
17
|
+
def read_line(prompt = '', value: '', echo: true, raw: true, nonblock: false)
|
18
|
+
# Greenhat Shim:: Store Line
|
19
|
+
self.breaker = false
|
20
|
+
self.line = Line.new(value, prompt: prompt)
|
21
|
+
screen_width = TTY::Screen.width
|
22
|
+
buffer = ''
|
23
|
+
|
24
|
+
output.print(line)
|
25
|
+
|
26
|
+
while (codes = get_codes(echo: echo, raw: raw, nonblock: nonblock)) &&
|
27
|
+
(code = codes[0])
|
28
|
+
char = codes.pack('U*')
|
29
|
+
|
30
|
+
# GreenHat Shim / Back Tab Down Submodule
|
31
|
+
if [:back_tab, :ctrl_c].include? console.keys[char]
|
32
|
+
clear_display(line, screen_width)
|
33
|
+
trigger_key_event(char, line: line.to_s)
|
34
|
+
break
|
35
|
+
end
|
36
|
+
|
37
|
+
# Greenhat Shim
|
38
|
+
if EXIT_KEYS.include?(console.keys[char])
|
39
|
+
trigger_key_event(char, line: line.to_s)
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
clear_display(line, screen_width) if raw && echo
|
44
|
+
|
45
|
+
if console.keys[char] == :backspace || code == BACKSPACE
|
46
|
+
unless line.start?
|
47
|
+
line.left
|
48
|
+
line.delete
|
49
|
+
end
|
50
|
+
elsif console.keys[char] == :delete || code == DELETE
|
51
|
+
line.delete
|
52
|
+
elsif console.keys[char].to_s =~ /ctrl_/
|
53
|
+
# skip
|
54
|
+
elsif console.keys[char] == :up
|
55
|
+
line.replace(history_previous) if history_previous?
|
56
|
+
elsif console.keys[char] == :down
|
57
|
+
line.replace(history_next? ? history_next : buffer) if track_history?
|
58
|
+
elsif console.keys[char] == :left
|
59
|
+
line.left
|
60
|
+
elsif console.keys[char] == :right
|
61
|
+
line.right
|
62
|
+
elsif console.keys[char] == :home
|
63
|
+
line.move_to_start
|
64
|
+
elsif console.keys[char] == :end
|
65
|
+
line.move_to_end
|
66
|
+
else
|
67
|
+
if raw && [CARRIAGE_RETURN, NEWLINE].include?(code)
|
68
|
+
char = "\n"
|
69
|
+
line.move_to_end
|
70
|
+
end
|
71
|
+
line.insert(char)
|
72
|
+
buffer = line.text
|
73
|
+
end
|
74
|
+
|
75
|
+
if (console.keys[char] == :backspace || code == BACKSPACE) && echo
|
76
|
+
if raw
|
77
|
+
output.print("\e[1X") unless line.start?
|
78
|
+
else
|
79
|
+
output.print("\s" + (line.start? ? '' : "\b"))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# trigger before line is printed to allow for line changes
|
84
|
+
trigger_key_event(char, line: line.to_s)
|
85
|
+
|
86
|
+
if raw && echo
|
87
|
+
output.print(line.to_s)
|
88
|
+
if char == "\n"
|
89
|
+
line.move_to_start
|
90
|
+
elsif !line.end? # readjust cursor position
|
91
|
+
output.print(cursor.backward(line.text_size - line.cursor))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Greenhat Shim do things
|
96
|
+
next unless [CARRIAGE_RETURN, NEWLINE].include?(code) || breaker
|
97
|
+
|
98
|
+
buffer = ''
|
99
|
+
output.puts unless echo
|
100
|
+
break
|
101
|
+
end
|
102
|
+
|
103
|
+
add_to_history(line.text.rstrip) if track_history? && echo
|
104
|
+
|
105
|
+
line.text
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# rubocop:enable all
|
@@ -0,0 +1,126 @@
|
|
1
|
+
css:
|
2
|
+
.relative {
|
3
|
+
position: relative;
|
4
|
+
z-index: 1;
|
5
|
+
}
|
6
|
+
|
7
|
+
.no-padding {
|
8
|
+
padding: 0 !important;
|
9
|
+
}
|
10
|
+
|
11
|
+
.padding {
|
12
|
+
padding: 10px !important;
|
13
|
+
}
|
14
|
+
|
15
|
+
.line-height {
|
16
|
+
line-height: inherit !important;
|
17
|
+
}
|
18
|
+
|
19
|
+
.mid {
|
20
|
+
display: flex;
|
21
|
+
align-items: center;
|
22
|
+
justify-content: center;
|
23
|
+
flex-wrap: wrap;
|
24
|
+
}
|
25
|
+
|
26
|
+
.aligner {
|
27
|
+
display: flex;
|
28
|
+
align-items: center;
|
29
|
+
justify-content: center;
|
30
|
+
}
|
31
|
+
|
32
|
+
.striped {
|
33
|
+
text-align:center;
|
34
|
+
}
|
35
|
+
|
36
|
+
.striped .entry:nth-child(odd) {
|
37
|
+
background-color: white;
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
.striped .entry:nth-child(even) {
|
42
|
+
background-color: #e8f5e9;
|
43
|
+
}
|
44
|
+
|
45
|
+
.bubble {
|
46
|
+
margin-right: 5px;
|
47
|
+
margin-bottom: 5px;
|
48
|
+
color: rgb(236, 236, 236);
|
49
|
+
font-weight: 300;
|
50
|
+
/* font-size: 0.8rem; */
|
51
|
+
}
|
52
|
+
|
53
|
+
.bubble-left {
|
54
|
+
padding: 2px 15px 2px 15px;
|
55
|
+
border-top-left-radius: 5px;
|
56
|
+
border-bottom-left-radius: 5px;
|
57
|
+
}
|
58
|
+
|
59
|
+
.bubble-right {
|
60
|
+
padding: 2px 15px 2px 15px;
|
61
|
+
border-top-right-radius: 5px;
|
62
|
+
border-bottom-right-radius: 5px;
|
63
|
+
}
|
64
|
+
|
65
|
+
.header {
|
66
|
+
margin: 0 !important;
|
67
|
+
text-align: center;
|
68
|
+
background-color:#42A5F5;
|
69
|
+
color: white;
|
70
|
+
}
|
71
|
+
|
72
|
+
.col7 {
|
73
|
+
width: 14.28%;
|
74
|
+
}
|
75
|
+
|
76
|
+
.col11 {
|
77
|
+
width: 8.9%;
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
.progress-bar {
|
82
|
+
position: absolute;
|
83
|
+
top:0;
|
84
|
+
left: 0px;
|
85
|
+
height: 100%;
|
86
|
+
opacity: 0.7;
|
87
|
+
z-index: -1;
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
div.dataTables_wrapper div.dataTables_filter {
|
92
|
+
text-align: right;
|
93
|
+
}
|
94
|
+
div.dataTables_wrapper div.dataTables_filter label {
|
95
|
+
font-weight: normal;
|
96
|
+
white-space: nowrap;
|
97
|
+
text-align: left;
|
98
|
+
}
|
99
|
+
|
100
|
+
div.dataTables_wrapper div.dataTables_filter input {
|
101
|
+
margin-left: 0.5em;
|
102
|
+
display: inline-block;
|
103
|
+
width: auto;
|
104
|
+
}
|
105
|
+
|
106
|
+
div.dataTables_wrapper div.dataTables_filter input {
|
107
|
+
margin-bottom: 0px
|
108
|
+
}
|
109
|
+
|
110
|
+
.table-header {
|
111
|
+
position: absolute;
|
112
|
+
padding-bottom: 15px;
|
113
|
+
width: 100%;
|
114
|
+
text-align: center;
|
115
|
+
background-color: #f1f8e9;
|
116
|
+
border-bottom: solid 1px grey;
|
117
|
+
/* font-size: 2em; */
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
.aligner-wrap {
|
122
|
+
display: flex;
|
123
|
+
align-items: center;
|
124
|
+
justify-content: left;
|
125
|
+
flex-wrap: wrap;
|
126
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
- if df_h
|
2
|
+
.row.card
|
3
|
+
.col.s12.no-padding
|
4
|
+
.header
|
5
|
+
.flow-text Disk
|
6
|
+
.col.s12.padding
|
7
|
+
- df_h.header.each do |header|
|
8
|
+
.col.s2
|
9
|
+
b = header
|
10
|
+
.col.s12.striped.no-padding
|
11
|
+
- df_h.rows.each do |entry|
|
12
|
+
.col.s12.entry.relative
|
13
|
+
- entry.each do |value|
|
14
|
+
small.col.s2 style='z-index:1' = value
|
15
|
+
.progress-bar.green style='width: #{entry[4]}'
|
16
|
+
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title SOS Display
|
5
|
+
meta content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" name="viewport"
|
6
|
+
|
7
|
+
// Materialize
|
8
|
+
link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet"
|
9
|
+
script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"
|
10
|
+
|
11
|
+
script src="https://code.jquery.com/jquery-2.2.4.min.js"
|
12
|
+
|
13
|
+
link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.min.css" rel="stylesheet"
|
14
|
+
|
15
|
+
// Data tables
|
16
|
+
script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"
|
17
|
+
link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"
|
18
|
+
|
19
|
+
body
|
20
|
+
== slim :css
|
21
|
+
|
22
|
+
nav.green
|
23
|
+
.nav-wrapper
|
24
|
+
a.brand-logo.center href="/" Greenhat
|
25
|
+
ul.left.white-text
|
26
|
+
li
|
27
|
+
a href ='http://localhost:5601/app/kibana' target="_blank"
|
28
|
+
.btn-flat.white-text
|
29
|
+
i.fa.fa-chart-pie.left.line-height
|
30
|
+
| Kibana
|
31
|
+
|
32
|
+
|
33
|
+
.container
|
34
|
+
br
|
35
|
+
- hosts.each do |host|
|
36
|
+
// Host Container
|
37
|
+
.row.blue.white-text.mid.card
|
38
|
+
i.fab.fa-lg.left.line-height class=host.icon
|
39
|
+
.flow-text = host.archive_name
|
40
|
+
|
41
|
+
// Host Info
|
42
|
+
== slim :info, host
|
43
|
+
|
44
|
+
// Other Templates
|
45
|
+
== slim :memory, host
|
46
|
+
== slim :disk_free, host
|
47
|
+
== slim :netstat, host
|
48
|
+
== slim :manifest, host
|
49
|
+
== slim :process, host
|
50
|
+
== slim :ulimit, host
|
51
|
+
== slim :systemctl, host
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.row.striped.card
|
2
|
+
- if manifest
|
3
|
+
.col.s12.entry.flow-text
|
4
|
+
.col.s4 Gitlab Version
|
5
|
+
.col.s8
|
6
|
+
= manifest.build_version
|
7
|
+
|
8
|
+
- if uptime
|
9
|
+
.col.s12.entry
|
10
|
+
.col.s4.aligner style='height:50px;' Uptime
|
11
|
+
.col.s8.aligner
|
12
|
+
- uptime.each do |data|
|
13
|
+
- if data.include? 'load average'
|
14
|
+
- data.split(':').each do |line|
|
15
|
+
.col.s4 = line
|
16
|
+
- else
|
17
|
+
= data
|
18
|
+
|
19
|
+
.col.s12.entry.aligner.padding
|
20
|
+
- if cpuinfo
|
21
|
+
.bubble
|
22
|
+
span.green.bubble-left CPU Count
|
23
|
+
span.blue.bubble-right = cpuinfo.count
|
24
|
+
|
25
|
+
- if total_memory
|
26
|
+
.bubble
|
27
|
+
span.green.bubble-left Total Memory
|
28
|
+
span.blue.bubble-right = total_memory
|
29
|
+
|
30
|
+
- if cpu_speed
|
31
|
+
.bubble
|
32
|
+
span.green.bubble-left = cpu_speed.first
|
33
|
+
span.blue.bubble-right = cpu_speed.last.to_i
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
- if uname
|
38
|
+
.col.s12.entry
|
39
|
+
small = uname
|
@@ -0,0 +1,22 @@
|
|
1
|
+
- if manifest
|
2
|
+
.row
|
3
|
+
.col.s12.no-padding.card
|
4
|
+
.table-header.flow-text Manifest
|
5
|
+
table.display id='manifest#{uuid}'
|
6
|
+
thead
|
7
|
+
tr
|
8
|
+
th Software
|
9
|
+
th Version
|
10
|
+
tbody
|
11
|
+
- manifest.software.each do |key,value|
|
12
|
+
tr
|
13
|
+
td.center = key
|
14
|
+
td.center = value.described_version
|
15
|
+
|
16
|
+
javascript:
|
17
|
+
$('#manifest#{uuid}').DataTable({
|
18
|
+
"columnDefs": [
|
19
|
+
{ "width": "50%", "targets": [0,1] }
|
20
|
+
]
|
21
|
+
});
|
22
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
- if free_m
|
2
|
+
.row.card
|
3
|
+
.col.s12.no-padding
|
4
|
+
.header
|
5
|
+
.flow-text Memory
|
6
|
+
.col.s12.padding.grey.lighten-1.center
|
7
|
+
// Bump Right One col
|
8
|
+
.col.col7
|
9
|
+
- free_m.first.each do |header|
|
10
|
+
.col.col7
|
11
|
+
b = header
|
12
|
+
.col.s12.striped.no-padding.center
|
13
|
+
- free_m[1..-1].each do |entry|
|
14
|
+
.col.s12.entry.relative.padding
|
15
|
+
- entry.each do |value|
|
16
|
+
.col.col7 style='z-index:1' = value
|
17
|
+
.progress-bar.green style='width: #{percent(entry[2],entry[1])}%'
|
18
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
- if netstat
|
2
|
+
.row
|
3
|
+
.card.col.s12.no-padding
|
4
|
+
.table-header.flow-text Netstat
|
5
|
+
table.display id='netstat#{uuid}'
|
6
|
+
thead
|
7
|
+
tr
|
8
|
+
- netstat.headers.each do |header|
|
9
|
+
th = header
|
10
|
+
tbody
|
11
|
+
- netstat.rows.each do |row|
|
12
|
+
tr
|
13
|
+
- row.each do |value|
|
14
|
+
td = value
|
15
|
+
|
16
|
+
javascript:
|
17
|
+
$('#netstat#{uuid}').DataTable({
|
18
|
+
"lengthChange": false,
|
19
|
+
});
|
20
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
- if processes
|
2
|
+
.row
|
3
|
+
.col.s12.no-padding.card
|
4
|
+
.table-header.flow-text Process
|
5
|
+
table.display id='process#{uuid}'
|
6
|
+
thead
|
7
|
+
tr
|
8
|
+
- processes.headers.each do |header|
|
9
|
+
th = header
|
10
|
+
tbody
|
11
|
+
- processes.list.each do |row|
|
12
|
+
tr
|
13
|
+
- row.values.each do |value|
|
14
|
+
td = value
|
15
|
+
|
16
|
+
javascript:
|
17
|
+
$('#process#{uuid}').DataTable({
|
18
|
+
"lengthChange": false,
|
19
|
+
"order": [[ 3, "desc" ]]
|
20
|
+
});
|
21
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
- if systemctl_unit_files
|
2
|
+
.row
|
3
|
+
.col.s12.no-padding.card
|
4
|
+
.table-header.flow-text
|
5
|
+
| Systemctl
|
6
|
+
table.display id='systemctl#{uuid}'
|
7
|
+
thead
|
8
|
+
tr
|
9
|
+
th Unit
|
10
|
+
th State
|
11
|
+
tbody
|
12
|
+
- systemctl_unit_files.each do |entry|
|
13
|
+
tr
|
14
|
+
td = entry.unit
|
15
|
+
td.center.white-text class="#{systemctl_color(entry)}"
|
16
|
+
= entry.status
|
17
|
+
.col.s12.grey.lighten-3
|
18
|
+
small
|
19
|
+
ul
|
20
|
+
li Static: the service is missing the [Install] section in its init script, so you cannot enable or disable it
|
21
|
+
li Generated: unit files are not automatically activated by systemd. There's nothing special about them as far as systemd is concerned
|
22
|
+
li Masked: systemd also has the ability to mark a unit as completely unstartable. Blocks Startup
|
23
|
+
javascript:
|
24
|
+
$('#systemctl#{uuid}').DataTable();
|
25
|
+
|
26
|
+
|
27
|
+
// Full Display
|
28
|
+
.row
|
29
|
+
.card.col.s12.no-padding
|
30
|
+
.header
|
31
|
+
.flow-text Systemctl Status
|
32
|
+
.col.s12.padding
|
33
|
+
- systemctl_unit_files.group_by(&:status).each do |key,group|
|
34
|
+
- next unless key == 'disabled' || key == 'enabled'
|
35
|
+
.row
|
36
|
+
.col.s12.center.blue.white-text style='margin-bottom: 5px' = key
|
37
|
+
.col.s12.aligner-wrap
|
38
|
+
- group.each do |entry|
|
39
|
+
.bubble
|
40
|
+
span.green.bubble-left.bubble-right = entry.unit
|