net-knocker 0.0.3 → 0.0.7

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: 3a06a05f3713cda7540c42ceb9d72543471b226bd9874d6d83fc1c1156e8d923
4
- data.tar.gz: 55310cefb6bfa19cbaac755de7611fc6ceb320b00cfb60c96f16c9cb1f78f63e
3
+ metadata.gz: d65e2fea58b18d3c2ed02a672026a6c26e92e896a3808637a64fd95195b25304
4
+ data.tar.gz: 12584511bf97ded05eeccf3d3887eb57de3bc89ed65b4af8c9694bda92a56bc6
5
5
  SHA512:
6
- metadata.gz: 29d2ae81c2db18ff5e7619ff817d1dfd8cad4fffdf0a0d410afecf74ceddde6ba9f614240f8a672fa689774f89666a9995d248073d3d256d03ab5595c846eb63
7
- data.tar.gz: 636c3fd921b0a223bad6ab2359559043fd767a6f535e0af0fd2dc55faa407d6532891819b46f03d25d0faf9a5fef9b7f2a93588797cbf9f5bfa41ca696fbe805
6
+ metadata.gz: 842a57063b37bb6d3179750ba0b68818f9f36f4ca7dd6728fbc387568e6f614eabc348aeed95979a3baf5335d9737da1be17398896a86699d1d14ea7d5774c90
7
+ data.tar.gz: d43b070daa32a475e0f8bd54632f365d7aa77a3b11cc75f39373905b28694db33e9c84aaeb8afbf65d4a3eedb4d319bbe903464913059adf40e0fb95c48395c3
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.5
1
+ 2.7.6
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) && (logger.respond_to? :debug)
49
- logger
50
- elsif (defined? Rails.logger) && (Rails.logger.respond_to? :debug)
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,27 +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
- content = File.read(path)
14
- 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?
15
49
  end
16
- .any?
50
+ end.compact
17
51
  end
18
52
 
19
- def self.env_var_patterns
20
- @env_var_patterns ||= %W[NET_KNOCKER_URL NET_KNOCKER_SECRET #{ENV['NET_KNOCKER_URL']}].freeze
53
+ def self.pids
54
+ @pids ||= peers.map(&:pid)
21
55
  end
22
56
 
23
- def self.self_patterns
24
- @self_patterns ||= %r{proc/((?:thread-)?self|#{Process.pid})/environ}.freeze
57
+ def self.any?(&block)
58
+ peers.any?(&block)
25
59
  end
26
60
  end
27
61
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Net
4
4
  class Knocker
5
- VERSION = '0.0.3'
5
+ VERSION = '0.0.7'
6
6
  end
7
7
  end
data/lib/net/knocker.rb CHANGED
@@ -3,9 +3,6 @@
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
@@ -20,11 +17,22 @@ module Net
20
17
  end
21
18
 
22
19
  def in
23
- send_request 'PUT'
20
+ return debug(omit_message('PUT')) if should_omit?
21
+
22
+ send_request('PUT').tap do |response|
23
+ # Omit sending the DELETE request after receiving `Not Modified` response
24
+ @should_omit ||= response.code.start_with? '3'
25
+ end
26
+ end
27
+
28
+ def omit_message(http_method = 'DELETE')
29
+ msg_end = url.to_s.empty? ? '' : "to #{url}"
30
+ "not sending #{http_method} request #{msg_end}"
24
31
  end
25
32
 
26
33
  def out
27
- return log.info("[#{self.class}:#{Process.pid}] omitting to send a request") if Peer.any?
34
+ return debug(omit_message) if should_omit?
35
+ return info("#{omit_message}, blocked by PID(s) #{Peer.pids.join(',')}") if Peer.any?
28
36
 
29
37
  send_request 'DELETE'
30
38
  end
@@ -32,10 +40,8 @@ module Net
32
40
  private
33
41
 
34
42
  def send_request(http_method)
35
- return log.info("[#{self.class}:#{Process.pid}] omitting to send a request") if should_omit?
36
-
37
43
  http_client.send_request(http_method, '/') do |response|
38
- log.debug("[#{self.class}][#{__method__}] Public IP: #{response.body} ")
44
+ debug("[#{self.class}][#{__method__}] Public IP: #{response.body} ")
39
45
  end
40
46
  end
41
47
  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.3
4
+ version: 0.0.7
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-08-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: