pechkin 1.0.3 → 1.1.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 +4 -4
- data/lib/pechkin.rb +20 -6
- data/lib/pechkin/app.rb +8 -3
- data/lib/pechkin/auth.rb +57 -0
- data/lib/pechkin/cli.rb +31 -7
- data/lib/pechkin/message_template.rb +3 -20
- data/lib/pechkin/prometheus_utils.rb +12 -0
- data/lib/pechkin/version.rb +1 -1
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59912e94ce5225522475cb9f77b3bbb83c398a5dada6b1f937c02c0a886e2e8f
|
4
|
+
data.tar.gz: dcf67693f3ecaa7de96ef00ee3e4bfc0347d6ee45f546a3c8e7ae9e5d39b34b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d071d69449005cf0dfae928a148391ea1247876bcc06cd52c588ca84d5210e37a66a0838e10511ed0a6554b1ecf6904961467e6d1fef916676a4296f34687367
|
7
|
+
data.tar.gz: d59c5fcbf1c97be064075bf012ca0d760d65edd911bd4cd551efcc64468292ed213423fcfb893823aa57191b38433bb803a09158cd3da2da18558f8a7bd5d795
|
data/lib/pechkin.rb
CHANGED
@@ -3,6 +3,8 @@ require 'rack'
|
|
3
3
|
require 'logger'
|
4
4
|
require 'prometheus/middleware/collector'
|
5
5
|
require 'prometheus/middleware/exporter'
|
6
|
+
require 'htauth'
|
7
|
+
require 'base64'
|
6
8
|
|
7
9
|
require_relative 'pechkin/cli'
|
8
10
|
require_relative 'pechkin/exceptions'
|
@@ -14,6 +16,8 @@ require_relative 'pechkin/connector_telegram'
|
|
14
16
|
require_relative 'pechkin/channel'
|
15
17
|
require_relative 'pechkin/configuration'
|
16
18
|
require_relative 'pechkin/substitute'
|
19
|
+
require_relative 'pechkin/prometheus_utils'
|
20
|
+
require_relative 'pechkin/auth'
|
17
21
|
require_relative 'pechkin/app'
|
18
22
|
|
19
23
|
module Pechkin # :nodoc:
|
@@ -33,20 +37,24 @@ module Pechkin # :nodoc:
|
|
33
37
|
|
34
38
|
def initialize(options)
|
35
39
|
@options = options
|
36
|
-
@configuration = Configuration.load_from_directory(options.config_file)
|
37
|
-
@handler = Handler.new(@configuration.channels)
|
38
40
|
end
|
39
41
|
|
40
42
|
def run
|
43
|
+
if options.add_auth
|
44
|
+
add_auth
|
45
|
+
exit 0
|
46
|
+
end
|
47
|
+
|
48
|
+
@configuration = Configuration.load_from_directory(options.config_file)
|
49
|
+
@handler = Handler.new(@configuration.channels)
|
41
50
|
configuration.list if options.list?
|
42
|
-
|
51
|
+
return if options.check?
|
43
52
|
|
44
53
|
if options.send_data
|
45
54
|
send_data
|
46
|
-
|
55
|
+
else
|
56
|
+
run_server
|
47
57
|
end
|
48
|
-
|
49
|
-
run_server
|
50
58
|
end
|
51
59
|
|
52
60
|
def run_server
|
@@ -79,5 +87,11 @@ module Pechkin # :nodoc:
|
|
79
87
|
[m[1], m[2]]
|
80
88
|
end
|
81
89
|
end
|
90
|
+
|
91
|
+
def add_auth
|
92
|
+
user, password = options.add_auth.split(':')
|
93
|
+
Pechkin::Auth::Manager.new(options.htpasswd).add(user, password)
|
94
|
+
puts IO.read(options.htpasswd)
|
95
|
+
end
|
82
96
|
end
|
83
97
|
end
|
data/lib/pechkin/app.rb
CHANGED
@@ -5,14 +5,19 @@ module Pechkin
|
|
5
5
|
def build(handler, options)
|
6
6
|
app = App.new
|
7
7
|
app.handler = handler
|
8
|
-
|
8
|
+
prometheus = Pechkin::PrometheusUtils.registry
|
9
9
|
logger = create_logger(options.log_dir)
|
10
10
|
|
11
11
|
Rack::Builder.app do
|
12
12
|
use Rack::CommonLogger, logger
|
13
13
|
use Rack::Deflater
|
14
|
-
use Prometheus::Middleware::Collector
|
15
|
-
|
14
|
+
use Prometheus::Middleware::Collector, registry: prometheus
|
15
|
+
# Add Auth check if found htpasswd file or it was excplicitly provided
|
16
|
+
# See CLI class for configuration details
|
17
|
+
if options.htpasswd
|
18
|
+
use Pechkin::Auth::Middleware, auth_file: options.htpasswd
|
19
|
+
end
|
20
|
+
use Prometheus::Middleware::Exporter, registry: prometheus
|
16
21
|
|
17
22
|
run app
|
18
23
|
end
|
data/lib/pechkin/auth.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Pechkin
|
2
|
+
module Auth
|
3
|
+
# Utility class for altering htpasswd files
|
4
|
+
class Manager
|
5
|
+
attr_reader :htpasswd
|
6
|
+
def initialize(htpasswd)
|
7
|
+
@htpasswd = htpasswd
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(user, password)
|
11
|
+
m = File.exist?(htpasswd) ? HTAuth::File::ALTER : HTAuth::File::CREATE
|
12
|
+
HTAuth::PasswdFile.open(htpasswd, m) do |f|
|
13
|
+
f.add_or_update(user, password, 'md5')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Auth middleware to check if provided auth can be found in .htpasswd file
|
19
|
+
class Middleware
|
20
|
+
attr_reader :htpasswd
|
21
|
+
|
22
|
+
def initialize(app, auth_file:)
|
23
|
+
@htpasswd = HTAuth::PasswdFile.open(auth_file) if File.exist?(auth_file)
|
24
|
+
@app = app
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
if authorized?(env)
|
29
|
+
@app.call(env)
|
30
|
+
else
|
31
|
+
body = { status: 'error', reason: 'unathorized' }.to_json
|
32
|
+
['401', { 'Content-Type' => 'application/json' }, [body]]
|
33
|
+
end
|
34
|
+
rescue StandardError => e
|
35
|
+
puts e.backtrace.reverse.join('\n\t')
|
36
|
+
body = { status: 'error', reason: e.message }.to_json
|
37
|
+
['503', { 'Content-Type' => 'application/json' }, [body]]
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def authorized?(env)
|
43
|
+
return true unless htpasswd
|
44
|
+
|
45
|
+
auth = env['HTTP_AUTHORIZATION'] || ''
|
46
|
+
auth.match(/^Basic (.+)$/) do |m|
|
47
|
+
check_auth(*Base64.decode64(m[1]).split(':'))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_auth(user, password)
|
52
|
+
e = htpasswd.fetch(user)
|
53
|
+
e && e.authenticated?(password)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/pechkin/cli.rb
CHANGED
@@ -43,7 +43,7 @@ module Pechkin
|
|
43
43
|
exit 2
|
44
44
|
else
|
45
45
|
parser.parse(args)
|
46
|
-
values
|
46
|
+
new.post_init(values)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -89,6 +89,9 @@ module Pechkin
|
|
89
89
|
|
90
90
|
# Command Line Parser Builder
|
91
91
|
class CLI
|
92
|
+
# Default file name for htpasswd file with auth credentials
|
93
|
+
PECHKIN_HTPASSWD_FILE = 'pechkin.htpasswd'.freeze
|
94
|
+
|
92
95
|
extend CLIHelper
|
93
96
|
|
94
97
|
separator 'Run options'
|
@@ -104,28 +107,49 @@ module Pechkin
|
|
104
107
|
|
105
108
|
opt :log_dir, names: ['--log-dir [DIR]'],
|
106
109
|
desc: 'Path to log directory. Output will be writen to' \
|
107
|
-
'pechkin.log file. If not specified will write to' \
|
110
|
+
'pechkin.log file. If not specified will write to ' \
|
108
111
|
'STDOUT'
|
112
|
+
opt :htpasswd, names: ['--auth-file FILE'],
|
113
|
+
desc: 'Path to .htpasswd file. By default ' \
|
114
|
+
'`pechkin.htpasswd` file will be looked up in ' \
|
115
|
+
'configuration directory and if found then ' \
|
116
|
+
'authorization will be enabled implicitly. ' \
|
117
|
+
'Providing this option enables htpasswd based ' \
|
118
|
+
'authorization explicitly. When making requests use ' \
|
119
|
+
'Basic auth to authorize.'
|
109
120
|
|
110
121
|
separator 'Utils for configuration maintenance'
|
111
|
-
|
112
122
|
opt :list?, names: ['-l', '--[no-]list'],
|
113
123
|
desc: 'List all endpoints'
|
114
124
|
|
115
125
|
opt :check?, names: ['-k', '--[no-]check'],
|
116
126
|
desc: 'Load configuration and exit'
|
117
127
|
opt :send_data, names: ['-s', '--send ENDPOINT'],
|
118
|
-
desc: 'Send data to specified ENDPOINT and exit.
|
119
|
-
'--data to be set.'
|
128
|
+
desc: 'Send data to specified ENDPOINT and exit. ' \
|
129
|
+
'Requires --data to be set.'
|
120
130
|
opt :preview, names: ['--preview'],
|
121
131
|
desc: 'Print rendering result to STDOUT and exit. ' \
|
122
|
-
'Use with send'
|
132
|
+
'Use with --send'
|
123
133
|
opt :data, names: ['--data DATA'],
|
124
134
|
desc: 'Data to send with --send flag. Json string or @filename.'
|
125
135
|
|
126
|
-
separator '
|
136
|
+
separator 'Auth utils'
|
137
|
+
opt :add_auth, names: ['--add-auth USER:PASSWORD'],
|
138
|
+
desc: 'Add auth entry to .htpasswd file. By default ' \
|
139
|
+
'pechkin.htpasswd from configuration directory ' \
|
140
|
+
'will be used. Use --auth-file to specify other ' \
|
141
|
+
'file to update. If file does not exist it will be ' \
|
142
|
+
'created.'
|
127
143
|
|
144
|
+
separator 'Debug options'
|
128
145
|
opt :debug?, names: ['--[no-]debug'],
|
129
146
|
desc: 'Print debug information and stack trace on errors'
|
147
|
+
|
148
|
+
def post_init(values)
|
149
|
+
default_htpasswd = File.join(values.config_file, PECHKIN_HTPASSWD_FILE)
|
150
|
+
values.htpasswd ||= default_htpasswd
|
151
|
+
|
152
|
+
values
|
153
|
+
end
|
130
154
|
end
|
131
155
|
end
|
@@ -8,31 +8,14 @@ module Pechkin
|
|
8
8
|
|
9
9
|
# Message template to render final message.
|
10
10
|
class MessageTemplate
|
11
|
-
|
12
|
-
|
13
|
-
# Need to compare two versions, one is 2.6.0 - which supports keyword
|
14
|
-
# arguments in ERB#initialize. Everything below that should use legacy
|
15
|
-
# arguments
|
16
|
-
rb_v260 = [2, 6, 0]
|
17
|
-
rb_current = ruby_version.split('.').map(&:to_i)
|
18
|
-
|
19
|
-
rb_v260.zip(rb_current).each do |x, y|
|
20
|
-
x ||= 0
|
21
|
-
y ||= 0
|
22
|
-
return false if y < x
|
23
|
-
end
|
24
|
-
|
25
|
-
true
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
RUBY_V260 = MessageTemplate.ruby_v260_or_later?
|
11
|
+
ERB_INITIALIZE_KEYWORD_ARGUMENTS = ERB.instance_method(:initialize)
|
12
|
+
.parameters.assoc(:key)
|
30
13
|
|
31
14
|
def initialize(erb)
|
32
15
|
# ERB#initialize has different signature starting from Ruby 2.6.*
|
33
16
|
# See link:
|
34
17
|
# https://github.com/ruby/ruby/blob/2311087/NEWS#stdlib-updates-outstanding-ones-only
|
35
|
-
if MessageTemplate::
|
18
|
+
if MessageTemplate::ERB_INITIALIZE_KEYWORD_ARGUMENTS # Ruby 2.6+
|
36
19
|
@erb_template = ERB.new(erb, trim_mode: '-')
|
37
20
|
else
|
38
21
|
safe_level = nil
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Pechkin
|
2
|
+
module PrometheusUtils # :nodoc:
|
3
|
+
class << self
|
4
|
+
def registry
|
5
|
+
registry = ::Prometheus::Client.registry
|
6
|
+
registry.gauge(:pechkin_start_time_seconds,
|
7
|
+
docstring: 'Startup timestamp').set(Time.now.to_i)
|
8
|
+
registry
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/pechkin/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pechkin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Arkhanhelsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: htauth
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: prometheus-client
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +58,14 @@ dependencies:
|
|
44
58
|
requirements:
|
45
59
|
- - '='
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.0.
|
61
|
+
version: 2.0.8
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - '='
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.0.
|
68
|
+
version: 2.0.8
|
55
69
|
description:
|
56
70
|
email: ilya.arkhanhelsky at gmail.com
|
57
71
|
executables:
|
@@ -62,6 +76,7 @@ files:
|
|
62
76
|
- bin/pechkin
|
63
77
|
- lib/pechkin.rb
|
64
78
|
- lib/pechkin/app.rb
|
79
|
+
- lib/pechkin/auth.rb
|
65
80
|
- lib/pechkin/channel.rb
|
66
81
|
- lib/pechkin/cli.rb
|
67
82
|
- lib/pechkin/configuration.rb
|
@@ -76,6 +91,7 @@ files:
|
|
76
91
|
- lib/pechkin/exceptions.rb
|
77
92
|
- lib/pechkin/handler.rb
|
78
93
|
- lib/pechkin/message_template.rb
|
94
|
+
- lib/pechkin/prometheus_utils.rb
|
79
95
|
- lib/pechkin/substitute.rb
|
80
96
|
- lib/pechkin/version.rb
|
81
97
|
homepage: https://github.com/iarkhanhelsky/pechkin
|