From a12889cbe0f6e82b25271410af9413c45de6a190 Mon Sep 17 00:00:00 2001 From: Pericles Theodorou Date: Thu, 7 Mar 2024 11:38:20 +0200 Subject: [PATCH 1/2] Validate naming --- lib/prometheus_exporter/client.rb | 28 +++++++++++++++++++++++++++- test/client_test.rb | 21 +++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/prometheus_exporter/client.rb b/lib/prometheus_exporter/client.rb index 2302bd4c..58b3dbc9 100644 --- a/lib/prometheus_exporter/client.rb +++ b/lib/prometheus_exporter/client.rb @@ -5,7 +5,9 @@ module PrometheusExporter class Client - class RemoteMetric + NAMING_VALIDATION_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/ + + class RemoteMetric attr_reader :name, :type, :help def initialize(name:, help:, type:, client:, opts: nil) @@ -128,6 +130,8 @@ def find_registered_metric(name, type: nil, help: nil) end def send_json(obj) + return false unless valid_naming?(obj) + payload = if @custom_labels if obj[:custom_labels] @@ -269,6 +273,28 @@ def wait_for_empty_queue_with_timeout(timeout_seconds) sleep(0.05) end end + + def valid_naming?(obj) + if obj[:name] + return false unless obj[:name].match?(NAMING_VALIDATION_REGEX) + end + + custom_label_names = [] + if obj[:custom_labels] + custom_label_names.concat(obj[:custom_labels].keys) + end + + if @custom_labels + custom_label_names.concat(@custom_labels.keys) + end + + return true if custom_label_names.empty? + + custom_label_names.all? { |name| + str = name.to_s + str.match?(NAMING_VALIDATION_REGEX) && !str.start_with?("__") + } + end end class LocalClient < Client diff --git a/test/client_test.rb b/test/client_test.rb index 55051140..763da55e 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -65,4 +65,25 @@ def test_overriding_logger assert_includes(logs.string, "dropping message cause queue is full") end + + def test_invalid_naming + client = PrometheusExporter::Client.new(custom_labels: {"label" => 1}) + + refute_same(false, client.send_json({})) + refute_same(false, client.send_json({name: "valid_name"})) + refute_same(false, client.send_json({name: "__valid_name"})) + refute_same(false, client.send_json({name: "__valid_name_1"})) + refute_same(false, client.send_json({name: "__valid_name_1", custom_labels: {"valid_name" => "value"}})) + refute_same(false, client.send_json({name: "valid_name", custom_labels: {"_valid_name" => "value"}})) + + assert_equal(false, client.send_json({name: "invalid-name"})) + assert_equal(false, client.send_json({name: "valid_name", custom_labels: {"__invalid_name" => "value"}})) + assert_equal(false, client.send_json({name: "valid_name", custom_labels: {"invalid-name" => "value"}})) + + client.custom_labels = {"__invalid_name" => "value"} + assert_equal(false, client.send_json({})) + + client.custom_labels = {"invalid-name" => "value"} + assert_equal(false, client.send_json({})) + end end From fe16e355933776a90bc481bbd86624fd40d5729b Mon Sep 17 00:00:00 2001 From: Pericles Theodorou Date: Thu, 7 Mar 2024 12:00:38 +0200 Subject: [PATCH 2/2] Indentation --- lib/prometheus_exporter/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/prometheus_exporter/client.rb b/lib/prometheus_exporter/client.rb index 58b3dbc9..fac774c9 100644 --- a/lib/prometheus_exporter/client.rb +++ b/lib/prometheus_exporter/client.rb @@ -7,7 +7,7 @@ module PrometheusExporter class Client NAMING_VALIDATION_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/ - class RemoteMetric + class RemoteMetric attr_reader :name, :type, :help def initialize(name:, help:, type:, client:, opts: nil)