net-knocker 0.0.4 → 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: 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: