net-knocker 0.0.4 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2b9e2759985d6e60c6ff108157155b7862d703c2e1836284f89f2786e58d199
4
- data.tar.gz: dce4cd990ad60f354628f15e83bb2fe9cadfd7d1bb1ea973e7211447711107a7
3
+ metadata.gz: 8a38824a21ea2beda34df5f73f6be239301b3aa40fe7b83a41c9d2c384af1ca3
4
+ data.tar.gz: 487b9e354c702565c4aeb4e95595a39e9b38b9979d40112175f7aea3add534cf
5
5
  SHA512:
6
- metadata.gz: 43ae20154a32b3a730952bec81a0b0c5a2159c7038b9d1276e4ff11fbf8edbcfb07ae8b6bfc6021c0d892ec47b797a6db14f2a13a7f496fe221c2bcc5540114b
7
- data.tar.gz: 3b3783e2c1d6a7d7b842f6e93f07ad4b0ca2dbe1e759b94e39ea7942c085d3f2b35a7532bbbff77ee8f74bd6fd24b64dfd6bb74ee242089d4ac4337a94f642fa
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
@@ -16,7 +16,7 @@ module Net
16
16
  http.use_ssl = true
17
17
  http.cert = ssl_certificate
18
18
  http.key = ssl_key
19
- http.set_debug_output $stderr if ENV.key? 'NET_KNOCKER_HTTP_DEBUG'
19
+ http.set_debug_output $stderr if ENV.key? 'NET_KNOCKER_DEBUG'
20
20
  end
21
21
  end
22
22
 
@@ -40,21 +40,30 @@ module Net
40
40
  end
41
41
  end
42
42
 
43
- def info(method = :info, msg)
44
- tags = [self.class.name, Process.pid, method.to_s.upcase].join('][')
43
+ def info(msg, method = :info)
44
+ tags = [Net::Knocker, Process.pid, method.to_s.upcase].join('][')
45
45
  log.send(method, "[#{tags}] #{msg}")
46
46
  end
47
47
 
48
48
  def error(msg)
49
- info(__method__, msg)
49
+ info(msg, __method__)
50
50
  end
51
51
 
52
52
  def warn(msg)
53
- info(__method__, msg)
53
+ info(msg, __method__)
54
54
  end
55
55
 
56
56
  def debug(msg)
57
- info(__method__, 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
58
67
  end
59
68
 
60
69
  def ssl_certificate
@@ -62,7 +71,9 @@ module Net
62
71
  end
63
72
 
64
73
  def url
65
- @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'))
66
77
  end
67
78
 
68
79
  def log
@@ -74,6 +85,10 @@ module Net
74
85
  ::Logger.new($stderr)
75
86
  end
76
87
  end
88
+
89
+ def var_names
90
+ @var_names ||= %w[NET_KNOCKER_SECRET NET_KNOCKER_URL].freeze
91
+ end
77
92
  end
78
93
  end
79
94
  end
@@ -1,42 +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.env_var_patterns
7
- @env_var_patterns ||= %W[NET_KNOCKER_URL NET_KNOCKER_SECRET #{ENV['NET_KNOCKER_URL']}].freeze
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")
8
15
  end
9
16
 
10
- # filter out /proc/self/environ, /proc/thread-self/environ, /proc/<PID>/environ" and "/proc/1/environ"
11
- def self.self_patterns
12
- @self_patterns ||= %r{proc/((?:thread-)?self|#{Process.pid}|1)/environ}.freeze
17
+ def environ
18
+ @environ ||= environ_path.binread.split("\0").map do |line|
19
+ line.split('=', 2)
20
+ end.to_h
13
21
  end
14
22
 
15
- def self.environ_paths
16
- Dir['/proc/*/environ'].grep_v(self_patterns)
17
- .map { |p| Pathname.new(p) }
18
- .compact
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
19
41
  end
42
+ # rubocop:enable Metrics/AbcSize
43
+ # rubocop:enable Metrics/PerceivedComplexity
20
44
 
21
- def self.pid_with_content
22
- environ_paths.map do |path|
23
- content = begin
24
- path.binread
25
- .split("\0")
26
- .select { |e| env_var_patterns.any? { |p| e.include? p } }
27
- .compact
28
- rescue StandardError
29
- next
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?
30
49
  end
31
- pid = path.to_s.split('/').third.to_s
32
- [pid, content] unless content.empty? || pid.empty?
33
- end
34
- .compact
35
- .to_h
50
+ end.compact
51
+ end
52
+
53
+ def self.pids
54
+ @pids ||= peers.map(&:pid)
36
55
  end
37
56
 
38
57
  def self.any?(&block)
39
- pid_with_content.any?(&block)
58
+ peers.any?(&block)
40
59
  end
41
60
  end
42
61
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Net
4
4
  class Knocker
5
- VERSION = '0.0.4'
5
+ VERSION = '0.0.6'
6
6
  end
7
7
  end
data/lib/net/knocker.rb CHANGED
@@ -17,16 +17,19 @@ module Net
17
17
  end
18
18
 
19
19
  def in
20
+ return debug(omit_message('PUT')) if should_omit?
21
+
20
22
  send_request 'PUT'
21
23
  end
22
24
 
23
- def msg_end
24
- "to #{url}" unless url.to_s.empty?
25
+ def omit_message(http_method = 'DELETE')
26
+ msg_end = url.to_s.empty? ? '' : "to #{url}"
27
+ "not sending #{http_method} request #{msg_end}"
25
28
  end
26
29
 
27
30
  def out
28
- return debug("not sending DELETE request #{msg_end})") if should_omit?
29
- return info("sending DELETE request is blocked by PID(s) #{Peer.pid_with_content.keys.join(',')}") 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?
30
33
 
31
34
  send_request 'DELETE'
32
35
  end
@@ -34,8 +37,6 @@ module Net
34
37
  private
35
38
 
36
39
  def send_request(http_method)
37
- return debug("not sending #{http_method} request #{msg_end}") if should_omit?
38
-
39
40
  http_client.send_request(http_method, '/') do |response|
40
41
  debug("[#{self.class}][#{__method__}] Public IP: #{response.body} ")
41
42
  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.4
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-13 00:00:00.000000000 Z
11
+ date: 2022-04-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: