gloo 0.7.3 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +38 -4
- data/Gemfile +4 -0
- data/Gemfile.lock +43 -17
- data/gloo.gemspec +3 -0
- data/lib/VERSION +1 -0
- data/lib/dependencies.rb +28 -0
- data/lib/gloo/app/engine.rb +4 -4
- data/lib/gloo/app/info.rb +11 -1
- data/lib/gloo/app/settings.rb +3 -3
- data/lib/gloo/core/baseo.rb +2 -0
- data/lib/gloo/core/factory.rb +22 -0
- data/lib/gloo/core/gloo_system.rb +9 -0
- data/lib/gloo/help/core/gloo_system.txt +3 -0
- data/lib/gloo/help/objs/cli/bar.txt +3 -0
- data/lib/gloo/help/objs/data/mysql.txt +40 -0
- data/lib/gloo/help/objs/data/query.txt +37 -0
- data/lib/gloo/help/objs/data/sqlite.txt +26 -0
- data/lib/gloo/help/objs/dev/git_repo.txt +2 -1
- data/lib/gloo/help/objs/dev/stats.txt +36 -0
- data/lib/gloo/help/objs/system/file.txt +7 -0
- data/lib/gloo/help/objs/system/ssh_exec.txt +30 -0
- data/lib/gloo/help/objs/web/http_post.txt +2 -0
- data/lib/gloo/help/objs/web/uri.txt +2 -1
- data/lib/gloo/objs/basic/boolean.rb +3 -0
- data/lib/gloo/objs/cli/bar.rb +22 -1
- data/lib/gloo/objs/data/mysql.rb +192 -0
- data/lib/gloo/objs/data/query.rb +176 -0
- data/lib/gloo/objs/data/sqlite.rb +159 -0
- data/lib/gloo/objs/dev/git.rb +13 -1
- data/lib/gloo/objs/dev/stats.rb +120 -0
- data/lib/gloo/objs/system/file_handle.rb +10 -1
- data/lib/gloo/objs/system/ssh_exec.rb +126 -0
- data/lib/gloo/objs/web/http_post.rb +53 -16
- data/lib/gloo/objs/web/json.rb +1 -1
- data/lib/gloo/objs/web/slack.rb +1 -1
- data/lib/gloo/objs/web/teams.rb +1 -1
- data/lib/gloo/objs/web/uri.rb +18 -1
- data/lib/gloo/persist/file_loader.rb +2 -0
- data/lib/gloo/utils/format.rb +21 -0
- data/lib/gloo/utils/stats.rb +205 -0
- data/lib/gloo/verbs/execute.rb +1 -1
- data/lib/gloo.rb +2 -4
- data/lib/run.rb +3 -2
- metadata +80 -7
@@ -0,0 +1,126 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# An object that can post JSON to a URI.
|
5
|
+
#
|
6
|
+
require 'net/ssh'
|
7
|
+
|
8
|
+
module Gloo
|
9
|
+
module Objs
|
10
|
+
class SshExec < Gloo::Core::Obj
|
11
|
+
|
12
|
+
KEYWORD = 'ssh_exec'.freeze
|
13
|
+
KEYWORD_SHORT = 'ssh'.freeze
|
14
|
+
HOST = 'host'.freeze
|
15
|
+
DEFAULT_HOST = 'localhost'.freeze
|
16
|
+
CMD = 'cmd'.freeze
|
17
|
+
RESULT = 'result'.freeze
|
18
|
+
HOST_REQUIRED_ERR = 'The host is required!'.freeze
|
19
|
+
|
20
|
+
#
|
21
|
+
# The name of the object type.
|
22
|
+
#
|
23
|
+
def self.typename
|
24
|
+
return KEYWORD
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# The short name of the object type.
|
29
|
+
#
|
30
|
+
def self.short_typename
|
31
|
+
return KEYWORD_SHORT
|
32
|
+
end
|
33
|
+
|
34
|
+
# ---------------------------------------------------------------------
|
35
|
+
# Children
|
36
|
+
# ---------------------------------------------------------------------
|
37
|
+
|
38
|
+
#
|
39
|
+
# Does this object have children to add when an object
|
40
|
+
# is created in interactive mode?
|
41
|
+
# This does not apply during obj load, etc.
|
42
|
+
#
|
43
|
+
def add_children_on_create?
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Add children to this object.
|
49
|
+
# This is used by containers to add children needed
|
50
|
+
# for default configurations.
|
51
|
+
#
|
52
|
+
def add_default_children
|
53
|
+
fac = $engine.factory
|
54
|
+
fac.create_string HOST, DEFAULT_HOST, self
|
55
|
+
fac.create_string CMD, nil, self
|
56
|
+
fac.create_string RESULT, nil, self
|
57
|
+
end
|
58
|
+
|
59
|
+
# ---------------------------------------------------------------------
|
60
|
+
# Messages
|
61
|
+
# ---------------------------------------------------------------------
|
62
|
+
|
63
|
+
#
|
64
|
+
# Get a list of message names that this object receives.
|
65
|
+
#
|
66
|
+
def self.messages
|
67
|
+
return super + [ 'run' ]
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# SSH to the host and execute the command, then update result.
|
72
|
+
#
|
73
|
+
def msg_run
|
74
|
+
h = host_value
|
75
|
+
unless h
|
76
|
+
$engine.err HOST_REQUIRED_ERR
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
Net::SSH.start( h ) do |ssh|
|
81
|
+
result = ssh.exec!( cmd_value )
|
82
|
+
update_result result
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# ---------------------------------------------------------------------
|
87
|
+
# Private functions
|
88
|
+
# ---------------------------------------------------------------------
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
#
|
93
|
+
# Get the host from the child object.
|
94
|
+
# Returns nil if there is none.
|
95
|
+
#
|
96
|
+
def host_value
|
97
|
+
o = find_child HOST
|
98
|
+
return nil unless o
|
99
|
+
|
100
|
+
return o.value
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Get the command from the child object.
|
105
|
+
# Returns nil if there is none.
|
106
|
+
#
|
107
|
+
def cmd_value
|
108
|
+
o = find_child CMD
|
109
|
+
return nil unless o
|
110
|
+
|
111
|
+
return o.value
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Set the result of the API call.
|
116
|
+
#
|
117
|
+
def update_result( data )
|
118
|
+
r = find_child RESULT
|
119
|
+
return nil unless r
|
120
|
+
|
121
|
+
r.set_value data
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -16,6 +16,7 @@ module Gloo
|
|
16
16
|
URL = 'uri'.freeze
|
17
17
|
BODY = 'body'.freeze
|
18
18
|
RESULT = 'result'.freeze
|
19
|
+
SKIP_SSL_VERIFY = 'skip_ssl_verify'.freeze
|
19
20
|
|
20
21
|
#
|
21
22
|
# The name of the object type.
|
@@ -113,8 +114,7 @@ module Gloo
|
|
113
114
|
$log.debug "posting to: #{uri}"
|
114
115
|
body = self.body_as_json
|
115
116
|
$log.debug "posting body: #{body}"
|
116
|
-
|
117
|
-
data = Gloo::Objs::HttpPost.post_json uri, body, use_ssl
|
117
|
+
data = Gloo::Objs::HttpPost.post_json( uri, body, skip_ssl_verify? )
|
118
118
|
self.update_result data
|
119
119
|
end
|
120
120
|
|
@@ -125,20 +125,57 @@ module Gloo
|
|
125
125
|
#
|
126
126
|
# Post the content to the endpoint.
|
127
127
|
#
|
128
|
-
def self.post_json( url, body,
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
128
|
+
def self.post_json( url, body, skip_ssl_verify = false )
|
129
|
+
uri = URI( url )
|
130
|
+
params = { use_ssl: uri.scheme == 'https' }
|
131
|
+
params[ :verify_mode ] = ::OpenSSL::SSL::VERIFY_NONE if skip_ssl_verify
|
132
|
+
|
133
|
+
Net::HTTP.start( uri.host, uri.port, params ) do |http|
|
134
|
+
request = Net::HTTP::Post.new uri
|
135
|
+
request.content_type = 'application/json'
|
136
|
+
request.body = body
|
137
|
+
|
138
|
+
result = http.request request # Net::HTTPResponse object
|
139
|
+
$log.debug result.code
|
140
|
+
$log.debug result.message
|
141
|
+
return result.body
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# #
|
146
|
+
# # Post the content to the endpoint.
|
147
|
+
# #
|
148
|
+
# def self.post_json_1( url, body, use_ssl = true )
|
149
|
+
# # Structure the request
|
150
|
+
# uri = URI.parse( url )
|
151
|
+
#
|
152
|
+
# request = Net::HTTP::Post.new( uri.path )
|
153
|
+
# request.content_type = 'application/json'
|
154
|
+
# request.body = body
|
155
|
+
# n = Net::HTTP.new( uri.host, uri.port )
|
156
|
+
# n.use_ssl = use_ssl
|
157
|
+
#
|
158
|
+
# # Send the payload to the endpoint.
|
159
|
+
# result = n.start { |http| http.request( request ) }
|
160
|
+
# $log.debug result.code
|
161
|
+
# $log.debug result.message
|
162
|
+
# return result.body
|
163
|
+
# end
|
164
|
+
|
165
|
+
# ---------------------------------------------------------------------
|
166
|
+
# Private functions
|
167
|
+
# ---------------------------------------------------------------------
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
#
|
172
|
+
# Should we skip SSL verification during the request?
|
173
|
+
#
|
174
|
+
def skip_ssl_verify?
|
175
|
+
skip = find_child SKIP_SSL_VERIFY
|
176
|
+
return false unless skip
|
177
|
+
|
178
|
+
return skip.value
|
142
179
|
end
|
143
180
|
|
144
181
|
end
|
data/lib/gloo/objs/web/json.rb
CHANGED
data/lib/gloo/objs/web/slack.rb
CHANGED
data/lib/gloo/objs/web/teams.rb
CHANGED
data/lib/gloo/objs/web/uri.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
# A URI (URL).
|
5
5
|
#
|
6
6
|
require 'uri'
|
7
|
+
require 'net/http'
|
8
|
+
require 'openssl'
|
7
9
|
|
8
10
|
module Gloo
|
9
11
|
module Objs
|
@@ -51,10 +53,25 @@ module Gloo
|
|
51
53
|
def self.messages
|
52
54
|
basic = %w[open]
|
53
55
|
gets = %w[get_scheme get_host get_path]
|
54
|
-
more = %w[get_query get_fragment]
|
56
|
+
more = %w[get_query get_fragment get_cert_expires]
|
55
57
|
return super + basic + gets + more
|
56
58
|
end
|
57
59
|
|
60
|
+
#
|
61
|
+
# Get the expiration date for the certificate.
|
62
|
+
#
|
63
|
+
def msg_get_cert_expires
|
64
|
+
return unless value
|
65
|
+
o = value
|
66
|
+
uri = URI( value )
|
67
|
+
response = Net::HTTP.start( uri.host, uri.port, :use_ssl => true )
|
68
|
+
cert = response.peer_cert
|
69
|
+
o = cert.not_after
|
70
|
+
|
71
|
+
$engine.heap.it.set_to o
|
72
|
+
return o
|
73
|
+
end
|
74
|
+
|
58
75
|
#
|
59
76
|
# Get the URI fragment that comes after the '#'
|
60
77
|
# in the URL. Might be used to scroll down in the page.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Formatting utilities
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Utils
|
9
|
+
class Format
|
10
|
+
|
11
|
+
#
|
12
|
+
# Format number, adding comma separators.
|
13
|
+
# Ex: 1000 -> 1,000
|
14
|
+
#
|
15
|
+
def self.number( num )
|
16
|
+
return num.to_s.reverse.scan( /.{1,3}/ ).join( ',' ).reverse
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Utilities related to words (strings).
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Utils
|
9
|
+
class Stats
|
10
|
+
|
11
|
+
DIR_NOT_FOUND_ERR = 'The folder was not found!'.freeze
|
12
|
+
|
13
|
+
# ---------------------------------------------------------------------
|
14
|
+
# Setup
|
15
|
+
# ---------------------------------------------------------------------
|
16
|
+
|
17
|
+
#
|
18
|
+
# Create a stats utility class for the given directory.
|
19
|
+
#
|
20
|
+
def initialize( dir, types, skip = [] )
|
21
|
+
@dir = dir
|
22
|
+
setup_loc types
|
23
|
+
@skip = skip
|
24
|
+
end
|
25
|
+
|
26
|
+
# ---------------------------------------------------------------------
|
27
|
+
# Public Functions
|
28
|
+
# ---------------------------------------------------------------------
|
29
|
+
|
30
|
+
#
|
31
|
+
# Is the stats utility valid?
|
32
|
+
# Does it have a valid root directory.
|
33
|
+
#
|
34
|
+
def valid?
|
35
|
+
return true if @dir && File.directory?( @dir )
|
36
|
+
|
37
|
+
$engine.err DIR_NOT_FOUND_ERR
|
38
|
+
$engine.heap.it.set_to false
|
39
|
+
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Show all stat data for the project.
|
45
|
+
#
|
46
|
+
def show_all
|
47
|
+
return unless valid?
|
48
|
+
|
49
|
+
generate
|
50
|
+
puts "Showing All stats for #{@dir}".white
|
51
|
+
puts "\n ** #{@dir_cnt} Total Folders ** "
|
52
|
+
puts " ** #{@file_cnt} Total Files ** "
|
53
|
+
|
54
|
+
busy_folders( 7 )
|
55
|
+
file_types
|
56
|
+
loc
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Get a list of the busiest folders.
|
61
|
+
# Count is how many results we want.
|
62
|
+
#
|
63
|
+
def busy_folders( count = 17 )
|
64
|
+
return unless valid?
|
65
|
+
|
66
|
+
generate
|
67
|
+
puts "\nBusy Folders:".yellow
|
68
|
+
|
69
|
+
@folders.sort! { |a, b| a[ :cnt ] <=> b[ :cnt ] }
|
70
|
+
@folders.reverse!
|
71
|
+
@folders[ 0..count ].each do |f|
|
72
|
+
puts " #{f[ :cnt ]} - #{f[ :name ]}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Show file types and how many of each there are.
|
78
|
+
#
|
79
|
+
def file_types
|
80
|
+
return unless valid?
|
81
|
+
|
82
|
+
generate
|
83
|
+
puts "\nFiles by Type:".yellow
|
84
|
+
|
85
|
+
@types = @types.sort_by( &:last )
|
86
|
+
@types.reverse!
|
87
|
+
@types.each do |o|
|
88
|
+
puts " #{o[ 1 ]} - #{o[ 0 ]}" unless o[ 0 ].empty?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Show Lines of Code
|
94
|
+
#
|
95
|
+
def loc
|
96
|
+
return unless valid?
|
97
|
+
|
98
|
+
generate
|
99
|
+
total = 0
|
100
|
+
|
101
|
+
@loc.each do |k, v|
|
102
|
+
puts "\n #{k} Lines of Code".yellow
|
103
|
+
total += v[ :lines ]
|
104
|
+
formatted = Gloo::Utils::Format.number( v[ :lines ] )
|
105
|
+
puts " ** #{formatted} in #{v[ :files ].count} #{k} files ** "
|
106
|
+
|
107
|
+
puts "\n Busy #{k} files:".yellow
|
108
|
+
files = v[ :files ].sort! { |a, b| a[ :lines ] <=> b[ :lines ] }
|
109
|
+
files.reverse!
|
110
|
+
files[ 0..12 ].each do |f|
|
111
|
+
puts " #{f[ :lines ]} - #{f[ :file ]}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
formatted = Gloo::Utils::Format.number( total )
|
116
|
+
puts "\n #{formatted} Total Lines of Code".white
|
117
|
+
end
|
118
|
+
|
119
|
+
# ---------------------------------------------------------------------
|
120
|
+
# Private Functions
|
121
|
+
# ---------------------------------------------------------------------
|
122
|
+
|
123
|
+
#
|
124
|
+
# Setup counters for lines of code by file type.
|
125
|
+
def setup_loc( types )
|
126
|
+
@loc = {}
|
127
|
+
|
128
|
+
types.split( ' ' ).each do |t|
|
129
|
+
@loc[ t ] = { lines: 0, files: [] }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Generate stat data unless we've already done so.
|
135
|
+
#
|
136
|
+
def generate
|
137
|
+
return if @folders
|
138
|
+
|
139
|
+
$log.debug 'Generating...'
|
140
|
+
@folders = []
|
141
|
+
@types = {}
|
142
|
+
@file_cnt = 0
|
143
|
+
@dir_cnt = 0
|
144
|
+
|
145
|
+
generate_for Pathname.new( @dir )
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Generate data for the given path.
|
150
|
+
# NOTE: this is a recursive function.
|
151
|
+
# It traverses all sub-direcctories.
|
152
|
+
#
|
153
|
+
def generate_for( path )
|
154
|
+
return if @skip.include?( File.basename( path ) )
|
155
|
+
|
156
|
+
cnt = 0
|
157
|
+
path.children.each do |f|
|
158
|
+
if f.directory?
|
159
|
+
@dir_cnt += 1
|
160
|
+
generate_for( f )
|
161
|
+
else
|
162
|
+
@file_cnt += 1
|
163
|
+
cnt += 1
|
164
|
+
handle_file( f )
|
165
|
+
inc_type( File.extname( f ) )
|
166
|
+
end
|
167
|
+
end
|
168
|
+
@folders << { name: path, cnt: cnt }
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Increment the file count.
|
173
|
+
#
|
174
|
+
def inc_type( type )
|
175
|
+
if @types[ type ]
|
176
|
+
@types[ type ] += 1
|
177
|
+
else
|
178
|
+
@types[ type ] = 1
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Consider code file types.
|
184
|
+
#
|
185
|
+
def handle_file( file )
|
186
|
+
ext = File.extname( file )
|
187
|
+
return unless ext
|
188
|
+
|
189
|
+
ext = ext[ 1..-1 ]
|
190
|
+
return unless @loc.key?( ext )
|
191
|
+
|
192
|
+
lines = count_lines( file )
|
193
|
+
@loc[ ext ][ :lines ] += lines
|
194
|
+
@loc[ ext ][ :files ] << { lines: lines, file: file }
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# Count lines of code in file.
|
199
|
+
def count_lines( file )
|
200
|
+
return `wc -l #{file}`.split.first.to_i
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/lib/gloo/verbs/execute.rb
CHANGED
data/lib/gloo.rb
CHANGED
@@ -4,11 +4,9 @@
|
|
4
4
|
# Start the Engine.
|
5
5
|
#
|
6
6
|
|
7
|
+
# Look for all required dependencies.
|
7
8
|
path = File.dirname( File.absolute_path( __FILE__ ) )
|
8
|
-
|
9
|
-
Dir.glob( root ).each do |ruby_file|
|
10
|
-
require ruby_file
|
11
|
-
end
|
9
|
+
require File.join( path, 'dependencies.rb' )
|
12
10
|
|
13
11
|
module Gloo
|
14
12
|
def self.run
|
data/lib/run.rb
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
#
|
5
5
|
# From the /lib/ directory: ruby run.rb
|
6
6
|
#
|
7
|
+
|
8
|
+
# Look for all required dependencies.
|
7
9
|
path = File.dirname( File.absolute_path( __FILE__ ) )
|
8
|
-
|
9
|
-
Dir.glob( root ) { |ruby_file| require ruby_file }
|
10
|
+
require File.join( path, 'dependencies.rb' )
|
10
11
|
|
11
12
|
params = []
|
12
13
|
( params << '--cli' ) if ARGV.count.zero?
|