Module: IParty

Defined in:
lib/iparty.rb,
lib/iparty/config.rb,
lib/iparty/address.rb,
lib/iparty/railtie.rb,
lib/iparty/version.rb,
lib/iparty/max_mind.rb,
lib/iparty/rake_task.rb,
lib/iparty/cli/colorize.rb,
lib/iparty/cli/formatter.rb,
lib/iparty/cli/application.rb,
lib/iparty/max_mind/result.rb,
lib/iparty/max_mind/database.rb,
lib/iparty/max_mind/lazy_reader.rb,
lib/iparty/max_mind/eager_reader.rb,
lib/iparty/cli/application/actions.rb,
lib/iparty/cli/application/appinfo.rb,
lib/iparty/cli/application/options.rb,
lib/iparty/cli/application/irb_context.rb

Overview

rubocop:enable Naming/MethodName

Defined Under Namespace

Modules: CLI Classes: Address, Config, Error, MaxMind, Railtie, RakeTask

Constant Summary collapse

VERSION =
"0.1.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configObject

Returns the value of attribute config.



59
60
61
# File 'lib/iparty/config.rb', line 59

def config
  @config
end

Class Method Details

.classify(input) ⇒ Object



48
49
50
51
52
# File 'lib/iparty.rb', line 48

def self.classify input
  normalize(input).type
rescue IPAddr::Error
  :invalid
end

.configure {|config| ... } ⇒ Object

Yields:



61
62
63
# File 'lib/iparty/config.rb', line 61

def configure
  yield(config)
end

.default_configObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/iparty/config.rb', line 93

def default_config
  Config.new(
    # If set to false drop last half of v6-addresses as they are insignificant for most applications.
    # The then 64-bit addresses also fit into unsigned bigints allowing for easy range representations.
    # Each IParty::Address can overwrite this with
    #   * #ipv6_significant accessors
    #   * significant: keyword (affected methods only but including new/initialize)
    ipv6_significant: env_value("IPARTY_IPV6_SIGNIFICANT", true),

    # Whether to use the low memory file reader or load mmdb into memory as a whole (see docs/BENCHMARK.md)
    eager_load: env_value("IPARTY_EAGER_LOAD", false),

    # Singleton instances (may be false, true, hash or proc which returns hash-like)
    singletons: env_value("IPARTY_SINGLETONS", false),

    # An IP that is used instead of local IPs
    local_ip_alias: env_value("IPARTY_LOCAL_IP_ALIAS", nil),

    # MaxMind account_id and license_key aka mirror basic-auth
    account_id: env_value("MAXMIND_ACCOUNT_ID", nil),
    license_key: env_value("MAXMIND_LICENSE_KEY", nil),

    # Mirror to download tar.gz compressed mmdb-files from
    mirror: env_value("MAXMIND_MIRROR", "https://download.maxmind.com/geoip/databases/:edition/download?suffix=tar.gz"),

    # The mmdb editions to fetch, you don't really need country if you have city
    editions: env_value("MAXMIND_EDITIONS", "GeoLite2-ASN GeoLite2-Country GeoLite2-City") {|v| v.split(/\s+|,\s*/) },

    # Directory to store mmdb-files in, also creates .updating subdirectory
    directory: env_value("IPARTY_DIRECTORY", nil) do |dir|
      if dir && !dir.empty?
        Pathname.new(dir)
      else
        Pathname.new(Dir.tmpdir).join("iparty")
      end
    end,

    # Proc to turn URL into mmdb-file(s) inside target directory.
    # All .mmdb files will be moved and then dir gets removed.
    url_to_mmdb: proc do |url, dir, config|
      auth = %{-u "#{config.}:#{config.license_key}"} if config. && config.license_key
      curl = %{curl -L -s #{"#{auth} " if auth}"#{url}"}
      tar = %{tar xz --strip-components 1 --exclude "*.txt" --no-same-owner -C #{dir.to_s.shellescape}}
      system("#{curl} | #{tar}")
    end,
  )
end

.env_value(key, default = nil, &vproc) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/iparty/config.rb', line 65

def env_value key, default = nil, &vproc
  env_value = ENV.fetch(key, default)

  env_value = case env_value
  when "1", "true", "on", "yes" then true
  when "0", "false", "off", "no" then false
  when "" then nil
  else env_value
  end

  vproc ? vproc.call(env_value) : env_value
end

.expand_hostnames(*ips_or_hosts) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/iparty.rb', line 54

def self.expand_hostnames *ips_or_hosts
  ips_or_hosts.flatten.flat_map do |name|
    next name unless name.is_a?(String) && !name.include?(":") && name.match?(/[a-z]/i)

    if defined?(Resolv)
      Resolv.getaddresses(name)
    elsif defined?(Addrinfo)
      begin
        Addrinfo.getaddrinfo(name, nil).map(&:ip_address).uniq
      rescue Socket::ResolutionError
        []
      end
    else
      raise "neither resolv nor addrinfo is available (gem install resolv)"
    end
  end
end

.fetch_db_files!(*args, **kw) ⇒ Object



24
25
26
# File 'lib/iparty.rb', line 24

def self.fetch_db_files! *args, **kw
  IParty::MaxMind.fetch_db_files!(*args, **kw)
end

.normalize(input, family = nil, native: false, **kw) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/iparty.rb', line 28

def self.normalize input, family = nil, native: false, **kw
  return unless input
  return if input.is_a?(String) && input.match?(/\A[[:space:]]*\z/)
  return if input.respond_to?(:empty?) && input.empty?

  addr = case input
  when String
    Address.new(input.strip, **kw)
  when IPAddr
    Address.new(input.to_i, input.family)
  when Integer
    family ||= input > (2**32) - 1 ? Socket::AF_INET6 : Socket::AF_INET
    Address.new(input, family, **kw)
  else
    raise IPAddr::InvalidAddressError, "invalid address: #{input}"
  end

  native ? addr.native : addr
end

.with_config(to_merge = {}, &block) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/iparty/config.rb', line 78

def with_config to_merge = {}, &block
  config_was = @config
  new_config = Config.new(config_was.to_h.merge(to_merge))

  if block
    begin
      block.call(self.config = new_config)
    ensure
      self.config = config_was
    end
  else
    new_config
  end
end