net-knocker 0.0.2 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9789879bc518f157cbecee0b2275e9740cb424bc0e4337b57183c299b8a6c82
4
- data.tar.gz: 2817492fa9cadde9138836aa266dfae4120d26c6b45aa4a4a14fd99a84cd8ed3
3
+ metadata.gz: 8a38824a21ea2beda34df5f73f6be239301b3aa40fe7b83a41c9d2c384af1ca3
4
+ data.tar.gz: 487b9e354c702565c4aeb4e95595a39e9b38b9979d40112175f7aea3add534cf
5
5
  SHA512:
6
- metadata.gz: f254f92c4758ac0b595244d4bb7aa9556a18fa0ffdedfa80273fe055b466cca7f862f2916601f9d8ac6d36d9576623abccb558147c590f339437b459b4189990
7
- data.tar.gz: eff3af079d67b23c36b7d534d78c82c70863124804bb27582b2c913072a77d879b0cfc4ffa84ad766cb05b38d65965526d5ec62d9e379a852356229b148a50c1
6
+ metadata.gz: ae90907f7a0d12d3b189f2df89fca91013b127fd5e7126391e2c2de35d850750c4c27f911b9b31cb448332c336cf9fef1cc5337d25fdfbbab40dcec2c5fb582e
7
+ data.tar.gz: 28880d5f8e3937140eb1648fdc11aa995880b5afc3ad4e1f9873ef1a14410f93fd1697e5b495c9570cdd7c0286edc439d54ef4d4bc47ba19bb7eb805aedf7b67
data/README.md CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
25
25
  |---------------------------|--------------------|
26
26
  | NET_KNOCKER_URL | |
27
27
  | NET_KNOCKER_SECRET | |
28
- | NET_KNOCKER_HTTP_DEBUG | |
28
+ | NET_KNOCKER_DEBUG | |
29
29
 
30
30
 
31
31
  ## Usage
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'logger'
4
+ require 'net/https'
5
+ require 'uri'
6
+
3
7
  module Net
4
8
  class Knocker
5
9
  module Env
@@ -12,7 +16,7 @@ module Net
12
16
  http.use_ssl = true
13
17
  http.cert = ssl_certificate
14
18
  http.key = ssl_key
15
- http.set_debug_output $stderr if ENV.key? 'NET_KNOCKER_HTTP_DEBUG'
19
+ http.set_debug_output $stderr if ENV.key? 'NET_KNOCKER_DEBUG'
16
20
  end
17
21
  end
18
22
 
@@ -36,22 +40,54 @@ module Net
36
40
  end
37
41
  end
38
42
 
43
+ def info(msg, method = :info)
44
+ tags = [Net::Knocker, Process.pid, method.to_s.upcase].join('][')
45
+ log.send(method, "[#{tags}] #{msg}")
46
+ end
47
+
48
+ def error(msg)
49
+ info(msg, __method__)
50
+ end
51
+
52
+ def warn(msg)
53
+ info(msg, __method__)
54
+ end
55
+
56
+ def debug(msg)
57
+ return unless debugging?
58
+
59
+ info(msg, __method__)
60
+ end
61
+
62
+ def debugging?
63
+ @debugging ||= begin
64
+ env_debug = ENV.fetch('NET_KNOCKER_DEBUG', false).to_s.downcase
65
+ %w[true yes yep 1].include? env_debug
66
+ end
67
+ end
68
+
39
69
  def ssl_certificate
40
70
  @ssl_certificate ||= OpenSSL::X509::Certificate.new(env_secret)
41
71
  end
42
72
 
43
73
  def url
44
- @url ||= URI.parse(ENV.fetch('NET_KNOCKER_URL')) unless should_omit?
74
+ return if should_omit?
75
+
76
+ @url ||= URI.parse(ENV.fetch('NET_KNOCKER_URL'))
45
77
  end
46
78
 
47
79
  def log
48
- @log ||= if defined? logger
49
- logger
50
- elsif defined? Rails.logger
51
- Rails.logger
52
- else
53
- ::Logger.new($stderr)
54
- end
80
+ @log ||= if (defined? logger) && (logger.respond_to? :debug)
81
+ logger
82
+ elsif (defined? Rails.logger) && (Rails.logger.respond_to? :debug)
83
+ Rails.logger
84
+ else
85
+ ::Logger.new($stderr)
86
+ end
87
+ end
88
+
89
+ def var_names
90
+ @var_names ||= %w[NET_KNOCKER_SECRET NET_KNOCKER_URL].freeze
55
91
  end
56
92
  end
57
93
  end
@@ -1,29 +1,61 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'env'
3
4
  module Net
4
5
  class Knocker
5
6
  class Peer
6
- def self.any?
7
- return unless ENV
8
-
9
- Dir['/proc/*/environ']
10
- .select { |path| File.readable_real? path }
11
- .grep_v(self_patterns)
12
- .select do |path|
13
- File.read(path)
14
- .then do |content|
15
- (env_var_patterns.any? { |pattern| content.include? pattern })
7
+ extend Env
8
+
9
+ attr_reader :pid, :exe, :environ_path
10
+
11
+ def initialize(pid)
12
+ @pid = pid
13
+ @exe ||= Pathname("/proc/#{pid}/exe").realpath
14
+ @environ_path ||= Pathname("/proc/#{pid}/environ")
15
+ end
16
+
17
+ def environ
18
+ @environ ||= environ_path.binread.split("\0").map do |line|
19
+ line.split('=', 2)
20
+ end.to_h
21
+ end
22
+
23
+ # rubocop:todo Metrics/PerceivedComplexity
24
+ # rubocop:todo Metrics/AbcSize
25
+ def self.try_peer(path) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
26
+ pid = File.basename(path).to_i
27
+ return if pid.zero? || (pid.eql? Process.pid)
28
+
29
+ peer_candidate = new(pid)
30
+ return unless peer_candidate.exe.basename.eql? Pathname('/proc/self/exe').realpath.basename
31
+ return unless var_names.all? { |e| peer_candidate.environ.key? e }
32
+ return unless URI.parse(peer_candidate.environ.fetch('NET_KNOCKER_URL')).eql? url
33
+ return unless peer_candidate.environ.fetch('NET_KNOCKER_SECRET').eql? env_secret
34
+
35
+ peer_candidate
36
+ rescue Errno::EACCES
37
+ nil
38
+ rescue StandardError => e
39
+ debug "non-crical exception raised: #{e.class}: #{e.message}"
40
+ nil
41
+ end
42
+ # rubocop:enable Metrics/AbcSize
43
+ # rubocop:enable Metrics/PerceivedComplexity
44
+
45
+ def self.peers
46
+ @peers ||= Dir['/proc/*/'].map do |path|
47
+ try_peer(path).tap do |p|
48
+ debug("peer found #{p.pid}") unless p.nil?
16
49
  end
17
- end
18
- .any?
50
+ end.compact
19
51
  end
20
52
 
21
- def self.env_var_patterns
22
- @env_var_patterns ||= %W[NET_KNOCKER_URL NET_KNOCKER_SECRET #{ENV['NET_KNOCKER_URL']}].freeze
53
+ def self.pids
54
+ @pids ||= peers.map(&:pid)
23
55
  end
24
56
 
25
- def self.self_patterns
26
- @self_patterns ||= %r{proc/((?:thread-)?self|#{Process.pid})/environ}.freeze
57
+ def self.any?(&block)
58
+ peers.any?(&block)
27
59
  end
28
60
  end
29
61
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Net
4
4
  class Knocker
5
- VERSION = '0.0.2'
5
+ VERSION = '0.0.6'
6
6
  end
7
7
  end
data/lib/net/knocker.rb CHANGED
@@ -3,13 +3,10 @@
3
3
  require_relative './knocker/version'
4
4
  require_relative './knocker/env'
5
5
  require_relative './knocker/peer'
6
- require 'logger'
7
- require 'net/https'
8
- require 'uri'
9
6
 
10
7
  module Net
11
8
  class Knocker
12
- include Knocker::Env
9
+ include Net::Knocker::Env
13
10
 
14
11
  def self.check
15
12
  new
@@ -20,11 +17,19 @@ module Net
20
17
  end
21
18
 
22
19
  def in
20
+ return debug(omit_message('PUT')) if should_omit?
21
+
23
22
  send_request 'PUT'
24
23
  end
25
24
 
25
+ def omit_message(http_method = 'DELETE')
26
+ msg_end = url.to_s.empty? ? '' : "to #{url}"
27
+ "not sending #{http_method} request #{msg_end}"
28
+ end
29
+
26
30
  def out
27
- return log.info("[#{self.class}:#{Process.pid}] omitting send request") if Peer.any?
31
+ return debug(omit_message) if should_omit?
32
+ return info("#{omit_message}, blocked by PID(s) #{Peer.pids.join(',')}") if Peer.any?
28
33
 
29
34
  send_request 'DELETE'
30
35
  end
@@ -32,10 +37,8 @@ module Net
32
37
  private
33
38
 
34
39
  def send_request(http_method)
35
- return log.info("[#{self.class}:#{Process.pid}] omitting send request") if should_omit?
36
-
37
40
  http_client.send_request(http_method, '/') do |response|
38
- log.debug("[#{self.class}][#{__method__}] Public IP: #{response.body} ")
41
+ debug("[#{self.class}][#{__method__}] Public IP: #{response.body} ")
39
42
  end
40
43
  end
41
44
  end
data/net-knocker.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = 'Use Mutual TLS to knock to remote endpoint.'
12
12
  # spec.description = ''
13
13
  spec.homepage = 'https://github.com/todosmodos/net-knocker'
14
- spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0') # rubocop:todo Gemspec/RequiredRubyVersion
15
15
 
16
16
  # spec.metadata['homepage_uri'] = spec.homepage
17
17
  # spec.metadata['source_code_uri'] = 'TODO: Put your gem's public repo URL here.'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-knocker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tio Teath
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-12 00:00:00.000000000 Z
11
+ date: 2022-04-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: