FEATURE: add option for binding exporter to ip (#103)

FEATURE: add option for binding exporter to ip (#103)

  • add option for binding exporter to ip

binds to localhost only by default, preventing unintended exposure of this service

closes https://github.com/discourse/prometheus_exporter/issues/101

  • fix style

  • adjust README.md to reflect changed behavior

  • adjust CHANGELOG and prometheus_exporter.gemspec to reflect breaking changes

  • bump version.rb due to breaking change

  • fix indentation and rubocop

  • Update README.md

Co-Authored-By: Sam sam.saffron@gmail.com

diff --git a/CHANGELOG b/CHANGELOG
index 0ab31ed..f850ec9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+0.5.0 - pending
+
+- Breaking change: listen only to localhost by default to prevent unintended insecure configuration
+
 0.4.17 - 13-01-2019
 
 - FEATURE: add support for `to_h` on all metrics which can be used to query existing key/values
diff --git a/README.md b/README.md
index f90877b..95ae490 100644
--- a/README.md
+++ b/README.md
@@ -63,8 +63,9 @@ require 'prometheus_exporter/server'
 require 'prometheus_exporter/client'
 require 'prometheus_exporter/instrumentation'
 
+# bind is the address, on which the webserver will listen
 # port is the port that will provide the /metrics route
-server = PrometheusExporter::Server::WebServer.new port: 12345
+server = PrometheusExporter::Server::WebServer.new bind: 'localhost', port: 12345
 server.start
 
 # wire up a default local client
@@ -116,7 +117,7 @@ In some cases (for example, unicorn or puma clusters) you may want to aggregate
 
 Simplest way to achieve this is to use the built-in collector.
 
-First, run an exporter on your desired port (we use the default port of 9394):
+First, run an exporter on your desired port (we use the default bind to localhost and port of 9394):
 
 `‍``
 $ prometheus_exporter
diff --git a/bin/prometheus_exporter b/bin/prometheus_exporter
index b2441c2..720a234 100755
--- a/bin/prometheus_exporter
+++ b/bin/prometheus_exporter
@@ -19,6 +19,12 @@ def run
            "Port exporter should listen on (default: #{PrometheusExporter::DEFAULT_PORT})") do |o|
       options[:port] = o.to_i
     end
+    opt.on('-b',
+           '--bind STRING',
+           String,
+           "IP address exporter should listen on (default: #{PrometheusExporter::DEFAULT_BIND_ADDRESS})") do |o|
+      options[:bind] = o.to_s
+    end
     opt.on('-t',
            '--timeout INTEGER',
            Integer,
@@ -81,7 +87,7 @@ def run
 
   runner = PrometheusExporter::Server::Runner.new(options)
 
-  puts "#{Time.now} Starting prometheus exporter on port #{runner.port}"
+  puts "#{Time.now} Starting prometheus exporter on #{runner.bind}:#{runner.port}"
   runner.start
   sleep
 end
diff --git a/lib/prometheus_exporter.rb b/lib/prometheus_exporter.rb
index 1403909..ea8b628 100644
--- a/lib/prometheus_exporter.rb
+++ b/lib/prometheus_exporter.rb
@@ -7,6 +7,7 @@ require "thread"
 module PrometheusExporter
   # per: https://github.com/prometheus/prometheus/wiki/Default-port-allocations
   DEFAULT_PORT = 9394
+  DEFAULT_BIND_ADDRESS = 'localhost'
   DEFAULT_PREFIX = 'ruby_'
   DEFAULT_TIMEOUT = 2
 
diff --git a/lib/prometheus_exporter/server/runner.rb b/lib/prometheus_exporter/server/runner.rb
index e6eb524..4511074 100644
--- a/lib/prometheus_exporter/server/runner.rb
+++ b/lib/prometheus_exporter/server/runner.rb
@@ -32,69 +32,46 @@ module PrometheusExporter::Server
         )
       end
 
-      server = server_class.new port: port, collector: collector, timeout: timeout, verbose: verbose
+      server = server_class.new port: port, bind: bind, collector: collector, timeout: timeout, verbose: verbose
       server.start
     end
 
-    def prefix=(prefix)
-      @prefix = prefix
-    end
+    attr_accessor :unicorn_listen_address, :unicorn_pid_file
+    attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class
 
     def prefix
       @prefix || PrometheusExporter::DEFAULT_PREFIX
     end
 
-    def port=(port)
-      @port = port
-    end
-
     def port
       @port || PrometheusExporter::DEFAULT_PORT
     end
 
-    def collector_class=(collector_class)
-      @collector_class = collector_class
+    def bind
+      @bind || PrometheusExporter::DEFAULT_BIND_ADDRESS
     end
 
     def collector_class
       @collector_class || PrometheusExporter::Server::Collector
     end
 
-    def type_collectors=(type_collectors)
-      @type_collectors = type_collectors
-    end
-
     def type_collectors
       @type_collectors || []
     end
 
-    def timeout=(timeout)
-      @timeout = timeout
-    end
-
     def timeout
       @timeout || PrometheusExporter::DEFAULT_TIMEOUT
     end
 
-    def verbose=(verbose)
-      @verbose = verbose
-    end
-
     def verbose
       return @verbose if defined? @verbose
       false
     end
 
-    def server_class=(server_class)
-      @server_class = server_class
-    end
-
     def server_class
       @server_class || PrometheusExporter::Server::WebServer
     end
 
-    attr_accessor :unicorn_listen_address, :unicorn_pid_file
-
     def collector
       @_collector ||= collector_class.new
     end
diff --git a/lib/prometheus_exporter/server/web_server.rb b/lib/prometheus_exporter/server/web_server.rb
index a671ef3..d268941 100644
--- a/lib/prometheus_exporter/server/web_server.rb
+++ b/lib/prometheus_exporter/server/web_server.rb
@@ -9,7 +9,7 @@ module PrometheusExporter::Server
   class WebServer
     attr_reader :collector
 
-    def initialize(port: , collector: nil, timeout: PrometheusExporter::DEFAULT_TIMEOUT, verbose: false)
+    def initialize(port: , bind: nil, collector: nil, timeout: PrometheusExporter::DEFAULT_TIMEOUT, verbose: false)
 
       @verbose = verbose
 
@@ -38,6 +38,7 @@ module PrometheusExporter::Server
 
       @server = WEBrick::HTTPServer.new(
         Port: port,
+        BindAddress: bind,
         Logger: logger,
         AccessLog: access_log,
       )
diff --git a/lib/prometheus_exporter/version.rb b/lib/prometheus_exporter/version.rb
index 00ebac8..337cf90 100644
--- a/lib/prometheus_exporter/version.rb
+++ b/lib/prometheus_exporter/version.rb
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 module PrometheusExporter
-  VERSION = "0.4.17"
+  VERSION = '0.5.0'
 end
diff --git a/prometheus_exporter.gemspec b/prometheus_exporter.gemspec
index 3a31c58..2724e2c 100644
--- a/prometheus_exporter.gemspec
+++ b/prometheus_exporter.gemspec
@@ -5,22 +5,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
 require "prometheus_exporter/version"
 
 Gem::Specification.new do |spec|
-  spec.name          = "prometheus_exporter"
-  spec.version       = PrometheusExporter::VERSION
-  spec.authors       = ["Sam Saffron"]
-  spec.email         = ["sam.saffron@gmail.com"]
+  spec.name                 = "prometheus_exporter"
+  spec.version              = PrometheusExporter::VERSION
+  spec.authors              = ["Sam Saffron"]
+  spec.email                = ["sam.saffron@gmail.com"]
 
-  spec.summary       = %q{Prometheus Exporter}
-  spec.description   = %q{Prometheus metric collector and exporter for Ruby}
-  spec.homepage      = "https://github.com/discourse/prometheus_exporter"
-  spec.license       = "MIT"
+  spec.summary              = %q{Prometheus Exporter}
+  spec.description          = %q{Prometheus metric collector and exporter for Ruby}
+  spec.homepage             = "https://github.com/discourse/prometheus_exporter"
+  spec.license              = "MIT"
 
-  spec.files         = `git ls-files -z`.split("\x0").reject do |f|
+  spec.post_install_message = "prometheus_exporter will only bind to localhost by default as of v0.5"
+
+  spec.files = `git ls-files -z`.split("\x0").reject do |f|
     f.match(%r{^(test|spec|features|bin)/})
   end
-  spec.bindir        = "bin"
-  spec.executables   = ["prometheus_exporter"]
-  spec.require_paths = ["lib"]
+  spec.bindir               = "bin"
+  spec.executables          = ["prometheus_exporter"]
+  spec.require_paths        = ["lib"]
 
   spec.add_development_dependency "rubocop", ">= 0.69"
   spec.add_development_dependency "bundler", "> 1.16"

GitHub sha: f83b4f4f

https://review.discourse.org/t/dev-bump-prometheus-exporter-version/9079