bbk-utils 1.0.1.68971 → 1.0.1.72916
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/Gemfile +3 -0
- data/Gemfile.lock +29 -6
- data/README.md +9 -0
- data/bin/console +2 -0
- data/lib/bbk/utils/config.rb +197 -180
- data/lib/bbk/utils/crypt.rb +31 -23
- data/lib/bbk/utils/env_helper.rb +74 -69
- data/lib/bbk/utils/log_formatter.rb +15 -8
- data/lib/bbk/utils/logger.rb +33 -30
- data/lib/bbk/utils/proxy_logger.rb +29 -24
- data/lib/bbk/utils/version.rb +6 -1
- data/lib/bbk/utils/xml.rb +31 -20
- data/lib/bbk/utils.rb +7 -1
- data/sig/bbk/config.rbs +55 -0
- data/sig/bbk/crypt.rbs +9 -0
- data/sig/bbk/env_helper.rbs +13 -0
- data/sig/bbk/log_formatter.rbs +10 -0
- data/sig/bbk/logger.rbs +15 -0
- data/sig/bbk/proxy_logger.rbs +16 -0
- data/sig/bbk/proxy_object.rbs +7 -0
- data/sig/bbk/utils.rbs +5 -0
- data/sig/bbk/xml.rbs +10 -0
- data/sig/env.rbs +4 -0
- data/sig/logger.rbs +37 -0
- metadata +59 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5957c10e7a4b4b4138cf0af29b2ed4ac640c922ca1408678fbecf2d4f49d999
|
4
|
+
data.tar.gz: dd4c42d1fede6d5a6e6f18d4d61179020c280a4ecaa70c609019440b593ca6a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 143f480f6fbba94f66fa11d8a920a14fe6cafe6c056632cc770b6e5924b55c61bc3a31a4f706708147a971d79949a5a4804b5b1fed79aad23a31bc589c251ffe
|
7
|
+
data.tar.gz: 653f4dc3033c5aea12c7ecbb840b6f356b509983aafec50d6b79494698203654e4caca175a2b6a03e0b87ee54b740f7bb51d6a20523cb7b8ecb293c85c51c56e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bbk-utils (1.0.1.
|
5
|
-
activesupport
|
4
|
+
bbk-utils (1.0.1.72916)
|
5
|
+
activesupport (~> 6.0)
|
6
6
|
russian
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (6.1.4.
|
11
|
+
activesupport (6.1.4.4)
|
12
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
13
|
i18n (>= 1.6, < 2)
|
14
14
|
minitest (>= 5.1)
|
@@ -49,7 +49,8 @@ GEM
|
|
49
49
|
kwalify (0.7.2)
|
50
50
|
launchy (2.5.0)
|
51
51
|
addressable (~> 2.7)
|
52
|
-
minitest (5.
|
52
|
+
minitest (5.15.0)
|
53
|
+
parallel (1.21.0)
|
53
54
|
parser (3.0.3.1)
|
54
55
|
ast (~> 2.4.1)
|
55
56
|
path_expander (1.1.0)
|
@@ -60,6 +61,8 @@ GEM
|
|
60
61
|
kwalify (~> 0.7.0)
|
61
62
|
parser (~> 3.0.0)
|
62
63
|
rainbow (>= 2.0, < 4.0)
|
64
|
+
regexp_parser (2.2.0)
|
65
|
+
rexml (3.2.5)
|
63
66
|
rspec (3.10.0)
|
64
67
|
rspec-core (~> 3.10.0)
|
65
68
|
rspec-expectations (~> 3.10.0)
|
@@ -75,6 +78,20 @@ GEM
|
|
75
78
|
rspec-support (3.10.3)
|
76
79
|
rspec_junit_formatter (0.4.1)
|
77
80
|
rspec-core (>= 2, < 4, != 2.12.0)
|
81
|
+
rubocop (1.22.3)
|
82
|
+
parallel (~> 1.10)
|
83
|
+
parser (>= 3.0.0.0)
|
84
|
+
rainbow (>= 2.2.2, < 4.0)
|
85
|
+
regexp_parser (>= 1.8, < 3.0)
|
86
|
+
rexml
|
87
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
88
|
+
ruby-progressbar (~> 1.7)
|
89
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
90
|
+
rubocop-ast (1.13.0)
|
91
|
+
parser (>= 3.0.1.1)
|
92
|
+
rubocop-rspec (2.6.0)
|
93
|
+
rubocop (~> 1.19)
|
94
|
+
ruby-progressbar (1.11.0)
|
78
95
|
ruby_parser (3.18.1)
|
79
96
|
sexp_processor (~> 4.16)
|
80
97
|
rubycritic (4.6.1)
|
@@ -95,6 +112,9 @@ GEM
|
|
95
112
|
docile (~> 1.1)
|
96
113
|
simplecov-html (~> 0.11)
|
97
114
|
simplecov_json_formatter (~> 0.1)
|
115
|
+
simplecov-cobertura (2.1.0)
|
116
|
+
rexml
|
117
|
+
simplecov (~> 0.19)
|
98
118
|
simplecov-console (0.9.1)
|
99
119
|
ansi
|
100
120
|
simplecov
|
@@ -113,7 +133,7 @@ GEM
|
|
113
133
|
coercible (~> 1.0)
|
114
134
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
115
135
|
equalizer (~> 0.0, >= 0.0.9)
|
116
|
-
zeitwerk (2.5.
|
136
|
+
zeitwerk (2.5.3)
|
117
137
|
|
118
138
|
PLATFORMS
|
119
139
|
ruby
|
@@ -127,9 +147,12 @@ DEPENDENCIES
|
|
127
147
|
rake (~> 12.0)
|
128
148
|
rspec (~> 3.0)
|
129
149
|
rspec_junit_formatter
|
150
|
+
rubocop
|
151
|
+
rubocop-rspec
|
130
152
|
rubycritic
|
131
153
|
simplecov
|
154
|
+
simplecov-cobertura
|
132
155
|
simplecov-console
|
133
156
|
|
134
157
|
BUNDLED WITH
|
135
|
-
2.2.
|
158
|
+
2.2.33
|
data/README.md
CHANGED
data/bin/console
CHANGED
data/lib/bbk/utils/config.rb
CHANGED
@@ -1,223 +1,240 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BBK
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
4
|
+
module Utils
|
5
|
+
class Config
|
6
|
+
|
7
|
+
attr_accessor :store, :name
|
8
|
+
|
9
|
+
class BooleanCaster
|
10
|
+
|
11
|
+
FALSE_VALUES = [
|
12
|
+
false, 0,
|
13
|
+
'0', :"0",
|
14
|
+
'f', :f,
|
15
|
+
'F', :F,
|
16
|
+
'false', false,
|
17
|
+
'FALSE', :FALSE,
|
18
|
+
'off', :off,
|
19
|
+
'OFF', :OFF
|
20
|
+
].to_set.freeze
|
21
|
+
|
22
|
+
def self.cast(value)
|
23
|
+
if value.nil? || value == ''
|
24
|
+
nil
|
25
|
+
else
|
26
|
+
!FALSE_VALUES.include?(value)
|
27
|
+
end
|
23
28
|
end
|
29
|
+
|
24
30
|
end
|
25
|
-
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
32
|
+
def self.instance
|
33
|
+
@instance ||= new
|
34
|
+
end
|
30
35
|
|
31
|
-
|
32
|
-
delegate :map, :require, :optional, :run!, :[], :[]=, :content, :to_s, :to_json, :as_json, :to_yaml, :fetch, to: :instance
|
33
|
-
end
|
36
|
+
class << self
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
@store = {}
|
38
|
-
end
|
38
|
+
delegate :map, :require, :optional, :run!, :[], :[]=, :content, :to_s, :to_json, :as_json, :to_yaml, :fetch,
|
39
|
+
to: :instance
|
39
40
|
|
40
|
-
|
41
|
-
@store[env.to_s.upcase] = {
|
42
|
-
env: (key || env).to_s.upcase,
|
43
|
-
file: file,
|
44
|
-
required: required,
|
45
|
-
desc: desc,
|
46
|
-
bool: bool
|
47
|
-
}
|
48
|
-
end
|
41
|
+
end
|
49
42
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@store[env.to_s.upcase] = {
|
55
|
-
env: (key || env).to_s.upcase,
|
56
|
-
required: true,
|
57
|
-
desc: desc,
|
58
|
-
bool: bool,
|
59
|
-
type: type
|
60
|
-
}
|
61
|
-
end
|
43
|
+
def initialize(name = nil)
|
44
|
+
@name = name
|
45
|
+
@store = {}
|
46
|
+
end
|
62
47
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
74
|
-
end
|
48
|
+
def map(env, file, required: true, desc: nil, bool: false, key: nil)
|
49
|
+
@store[env.to_s.upcase] = {
|
50
|
+
env: (key || env).to_s.upcase,
|
51
|
+
file: file,
|
52
|
+
required: required,
|
53
|
+
desc: desc,
|
54
|
+
bool: bool,
|
55
|
+
type: nil
|
56
|
+
}
|
57
|
+
end
|
75
58
|
|
76
|
-
|
77
|
-
|
78
|
-
|
59
|
+
def require(env, desc: nil, bool: false, type: nil, key: nil)
|
60
|
+
raise ArgumentError.new('Specified type and bool') if bool && type.present?
|
61
|
+
|
62
|
+
type = BBK::Config::BooleanCaster.singleton_method(:cast) if bool
|
63
|
+
@store[env.to_s.upcase] = {
|
64
|
+
env: (key || env).to_s.upcase,
|
65
|
+
file: nil,
|
66
|
+
required: true,
|
67
|
+
desc: desc,
|
68
|
+
bool: bool,
|
69
|
+
type: type
|
70
|
+
}
|
79
71
|
end
|
80
|
-
end
|
81
72
|
|
82
|
-
|
83
|
-
|
84
|
-
|
73
|
+
def optional(env, default: nil, desc: nil, bool: false, type: nil, key: nil)
|
74
|
+
raise ArgumentError.new('Specified type and bool') if bool && type.present?
|
75
|
+
|
76
|
+
type = BBK::Utils::Config::BooleanCaster.singleton_method(:cast) if bool
|
77
|
+
@store[env.to_s.upcase] = {
|
78
|
+
env: (key || env).to_s.upcase,
|
79
|
+
file: nil,
|
80
|
+
required: false,
|
81
|
+
default: default,
|
82
|
+
desc: desc,
|
83
|
+
bool: true,
|
84
|
+
type: type
|
85
|
+
}
|
86
|
+
end
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
def run!(source = ENV)
|
89
|
+
@store.each_value do |item|
|
90
|
+
process(source, item)
|
91
|
+
end
|
92
|
+
end
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
if (file = item[:file])
|
93
|
-
File.read(file)
|
94
|
-
else
|
95
|
-
item[:value]
|
94
|
+
def [](key)
|
95
|
+
@store[normalize_key(key)][:value]
|
96
96
|
end
|
97
|
-
end
|
98
97
|
|
99
|
-
|
100
|
-
|
101
|
-
if (field = store[key.to_s.upcase]).present? && field.key?(:value)
|
102
|
-
field[:value]
|
103
|
-
else
|
104
|
-
default
|
98
|
+
def []=(key, value)
|
99
|
+
@store[normalize_key(key)][:value] = value
|
105
100
|
end
|
106
|
-
end
|
107
101
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
102
|
+
def content(key)
|
103
|
+
item = @store[normalize_key(key)]
|
104
|
+
if (file = item[:file])
|
105
|
+
File.read(file)
|
106
|
+
else
|
107
|
+
item[:value]
|
108
|
+
end
|
109
|
+
end
|
113
110
|
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
def fetch(key, default = nil)
|
112
|
+
# store.fetch(key.to_s.upcase, default)
|
113
|
+
if (field = store[key.to_s.upcase]).present? && field.key?(:value)
|
114
|
+
field[:value]
|
117
115
|
else
|
118
|
-
|
116
|
+
default
|
119
117
|
end
|
120
118
|
end
|
121
|
-
result.string
|
122
|
-
end
|
123
119
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
120
|
+
def to_s
|
121
|
+
result = StringIO.new
|
122
|
+
result.puts "Environment variables#{@name ? " for #{@name}" : ''}:"
|
123
|
+
padding = ' ' * 3
|
124
|
+
sorted = @store.values.sort_by do |item|
|
125
|
+
[item[:file].present? ? 0 : 1, item[:required] ? 0 : 1]
|
126
|
+
end
|
127
|
+
|
128
|
+
sorted.each do |item|
|
129
|
+
if item[:file]
|
130
|
+
result.puts print_file_item(item, padding)
|
131
|
+
else
|
132
|
+
result.puts print_item(item, padding)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
result.string
|
129
136
|
end
|
130
137
|
|
131
|
-
|
132
|
-
|
138
|
+
def as_json(*_args)
|
139
|
+
values = @store.values.sort_by do |item|
|
140
|
+
[item[:file].present? ? 0 : 1, item[:required] ? 0 : 1]
|
141
|
+
end.reduce({}) do |ret, item|
|
142
|
+
ret.merge(item[:env] => item)
|
143
|
+
end
|
133
144
|
|
134
|
-
|
135
|
-
|
136
|
-
end
|
145
|
+
@name ? { @name => values } : values
|
146
|
+
end
|
137
147
|
|
138
|
-
|
139
|
-
|
140
|
-
|
148
|
+
def to_json(*_args)
|
149
|
+
JSON.pretty_generate(as_json)
|
150
|
+
end
|
141
151
|
|
142
|
-
|
152
|
+
def to_yaml(*_args)
|
153
|
+
JSON.parse(to_json).to_yaml
|
154
|
+
end
|
143
155
|
|
144
|
-
|
145
|
-
k = key.to_s.upcase
|
146
|
-
raise "There is no such key: #{k} in config!" unless @store.key?(k)
|
156
|
+
private
|
147
157
|
|
148
|
-
|
149
|
-
|
158
|
+
def normalize_key(key)
|
159
|
+
k = key.to_s.upcase
|
160
|
+
raise "There is no such key: #{k} in config!" unless @store.key?(k)
|
150
161
|
|
151
|
-
|
152
|
-
|
162
|
+
k
|
163
|
+
end
|
153
164
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
165
|
+
def process(source, item)
|
166
|
+
content = source.fetch(item[:env], item[:default])
|
167
|
+
|
168
|
+
# Если данные есть, либо указан тип (нужно для того чтобы переменная была нужного типа)
|
169
|
+
if content.present? || item[:type].present?
|
170
|
+
if file = item[:file]
|
171
|
+
dirname = File.dirname(file)
|
172
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
173
|
+
File.write(file, content)
|
174
|
+
item[:value] = file
|
175
|
+
else
|
176
|
+
item[:value] = if (type = item[:type])
|
177
|
+
if type.respond_to? :call
|
178
|
+
type.call(content)
|
179
|
+
else
|
180
|
+
type.new(content)
|
181
|
+
end
|
182
|
+
else
|
183
|
+
content
|
184
|
+
end
|
185
|
+
end
|
186
|
+
elsif item[:required]
|
187
|
+
required!(item)
|
188
|
+
else
|
189
|
+
item[:value] = content
|
190
|
+
end
|
191
|
+
rescue StandardError => e
|
192
|
+
msg = "Failed processing #{item[:env]} parameter. #{e.inspect}"
|
193
|
+
if $logger
|
194
|
+
$logger.error msg
|
195
|
+
else
|
196
|
+
puts msg
|
197
|
+
end
|
198
|
+
raise
|
171
199
|
end
|
172
|
-
elsif item[:required]
|
173
|
-
required!(item)
|
174
|
-
else
|
175
|
-
item[:value] = content
|
176
|
-
end
|
177
|
-
rescue => e
|
178
|
-
msg = "Failed processing #{item[:env]} parameter. #{e.inspect}"
|
179
|
-
if $logger
|
180
|
-
$logger.error msg
|
181
|
-
else
|
182
|
-
puts msg
|
183
|
-
end
|
184
|
-
raise
|
185
|
-
end
|
186
200
|
|
187
|
-
|
188
|
-
|
189
|
-
|
201
|
+
def required!(item)
|
202
|
+
raise "ENV [#{item[:env]}] is required!"
|
203
|
+
end
|
190
204
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
205
|
+
def print_file_item(item, padding)
|
206
|
+
line = "#{padding}File #{wrap_required(item)}"
|
207
|
+
line = if item[:desc].present?
|
208
|
+
"#{line.ljust(50)} #{item[:desc]}"
|
209
|
+
else
|
210
|
+
line
|
211
|
+
end
|
198
212
|
|
199
|
-
|
200
|
-
|
213
|
+
"#{line}\n#{padding * 2}-> #{item[:file].inspect}"
|
214
|
+
end
|
201
215
|
|
202
|
-
|
203
|
-
|
204
|
-
|
216
|
+
def print_item(item, padding)
|
217
|
+
line = padding + wrap_required(item)
|
218
|
+
line += " (=#{item[:default]})" if item[:default].present?
|
205
219
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
220
|
+
line = if item[:desc].present?
|
221
|
+
"#{line.ljust(50)} #{item[:desc]}"
|
222
|
+
else
|
223
|
+
line
|
224
|
+
end
|
211
225
|
|
212
|
-
|
213
|
-
|
226
|
+
"#{line}\n#{padding * 2}-> #{item[:value].inspect}"
|
227
|
+
end
|
228
|
+
|
229
|
+
def wrap_required(item)
|
230
|
+
if item[:required]
|
231
|
+
"<#{item[:env]}>"
|
232
|
+
else
|
233
|
+
"[#{item[:env]}]"
|
234
|
+
end
|
235
|
+
end
|
214
236
|
|
215
|
-
def wrap_required(item)
|
216
|
-
if item[:required]
|
217
|
-
"<#{item[:env]}>"
|
218
|
-
else
|
219
|
-
"[#{item[:env]}]"
|
220
|
-
end
|
221
237
|
end
|
222
238
|
end
|
223
239
|
end
|
240
|
+
|
data/lib/bbk/utils/crypt.rb
CHANGED
@@ -1,34 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
2
4
|
|
3
5
|
module BBK
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
errors
|
6
|
+
module Utils
|
7
|
+
class Crypt
|
8
|
+
|
9
|
+
def self.full_check(key_path, cert_path, *cacert_chain)
|
10
|
+
errors = []
|
11
|
+
errors << 'Invalid key and cert pair' unless valid_key_cert?(key_path, cert_path)
|
12
|
+
errors << 'Invalid cert and cacert pair' unless valid_cert_sign?(cert_path,
|
13
|
+
*cacert_chain.compact)
|
14
|
+
if errors.empty?
|
15
|
+
nil
|
16
|
+
else
|
17
|
+
errors
|
18
|
+
end
|
13
19
|
end
|
14
|
-
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
def self.valid_key_cert?(key_path, cert_path)
|
22
|
+
raise "Key file #{key_path} not exists" unless File.exist? key_path
|
23
|
+
raise "Cert file #{cert_path} not exists" unless File.exist? cert_path
|
19
24
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
key = OpenSSL::PKey::RSA.new(File.read(key_path))
|
26
|
+
cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
|
27
|
+
cert.check_private_key(key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.valid_cert_sign?(cert_path, *ca_certs_paths)
|
31
|
+
raise "Cert file #{cert_path} not exists" unless File.exist? cert_path
|
32
|
+
raise "Not all files in ca chain #{ca_certs_paths} exists" unless ca_certs_paths.all? {|pth| File.exist? pth }
|
24
33
|
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
store = ca_certs_paths.reduce(OpenSSL::X509::Store.new) {|st, c| st.add_file(c) }
|
35
|
+
cert = OpenSSL::X509::Certificate.new File.read(cert_path)
|
36
|
+
store.verify(cert)
|
37
|
+
end
|
28
38
|
|
29
|
-
store = ca_certs_paths.reduce(OpenSSL::X509::Store.new) { |st, c| st.add_file(c) }
|
30
|
-
cert = OpenSSL::X509::Certificate.new File.read(cert_path)
|
31
|
-
store.verify(cert)
|
32
39
|
end
|
33
40
|
end
|
34
41
|
end
|
42
|
+
|