Commit b3aba120 authored by rpereira2's avatar rpereira2 Committed by Peter Leitzen

Filter params based on the proxy_path

- Permit params in ProxyService class to avoid having to make changes
to both ProxyService and to PrometheusApiController when adding support
for more prometheus apis.
- Also refactor the cache specs.
parent aa27c949
...@@ -13,8 +13,14 @@ module Prometheus ...@@ -13,8 +13,14 @@ module Prometheus
attr_accessor :proxyable, :method, :path, :params attr_accessor :proxyable, :method, :path, :params
PROXY_SUPPORT = { PROXY_SUPPORT = {
'query' => 'GET', 'query' => {
'query_range' => 'GET' method: ['GET'],
params: [:query, :time, :timeout]
},
'query_range' => {
method: ['GET'],
params: [:query, :start, :end, :step, :timeout]
}
}.freeze }.freeze
def self.from_cache(proxyable_class_name, proxyable_id, method, path, params) def self.from_cache(proxyable_class_name, proxyable_id, method, path, params)
...@@ -35,9 +41,11 @@ module Prometheus ...@@ -35,9 +41,11 @@ module Prometheus
def initialize(proxyable, method, path, params) def initialize(proxyable, method, path, params)
@proxyable = proxyable @proxyable = proxyable
@path = path @path = path
# Convert ActionController::Parameters to hash because reactive_cache_worker # Convert ActionController::Parameters to hash because reactive_cache_worker
# does not play nice with ActionController::Parameters. # does not play nice with ActionController::Parameters.
@params = params.to_hash @params = permit_params(params, path).to_hash
@method = method @method = method
end end
...@@ -94,8 +102,16 @@ module Prometheus ...@@ -94,8 +102,16 @@ module Prometheus
prometheus_adapter&.can_query? prometheus_adapter&.can_query?
end end
def permit_params(params, path)
if params.is_a?(ActionController::Parameters)
params.permit(PROXY_SUPPORT.dig(path, :params))
else
params
end
end
def can_proxy? def can_proxy?
PROXY_SUPPORT[@path] == @method PROXY_SUPPORT.dig(@path, :method)&.include?(@method)
end end
end end
end end
...@@ -9,7 +9,7 @@ describe Prometheus::ProxyService do ...@@ -9,7 +9,7 @@ describe Prometheus::ProxyService do
set(:environment) { create(:environment, project: project) } set(:environment) { create(:environment, project: project) }
describe '#initialize' do describe '#initialize' do
let(:params) { ActionController::Parameters.new(query: '1').permit! } let(:params) { ActionController::Parameters.new(query: '1') }
it 'initializes attributes' do it 'initializes attributes' do
result = described_class.new(environment, 'GET', 'query', { query: '1' }) result = described_class.new(environment, 'GET', 'query', { query: '1' })
...@@ -25,12 +25,23 @@ describe Prometheus::ProxyService do ...@@ -25,12 +25,23 @@ describe Prometheus::ProxyService do
expect(result.params).to be_an_instance_of(Hash) expect(result.params).to be_an_instance_of(Hash)
end end
context 'with unknown params' do
let(:params) { ActionController::Parameters.new(query: '1', other_param: 'val') }
it 'filters unknown params' do
result = described_class.new(environment, 'GET', 'query', params)
expect(result.params).to eq('query' => '1')
end
end
end end
describe '#execute' do describe '#execute' do
let(:prometheus_adapter) { instance_double(PrometheusService) } let(:prometheus_adapter) { instance_double(PrometheusService) }
let(:params) { ActionController::Parameters.new(query: '1') }
subject { described_class.new(environment, 'GET', 'query', { query: '1' }) } subject { described_class.new(environment, 'GET', 'query', params) }
context 'when prometheus_adapter is nil' do context 'when prometheus_adapter is nil' do
before do before do
...@@ -62,7 +73,7 @@ describe Prometheus::ProxyService do ...@@ -62,7 +73,7 @@ describe Prometheus::ProxyService do
end end
context 'cannot proxy' do context 'cannot proxy' do
subject { described_class.new(environment, 'POST', 'query', { query: '1' }) } subject { described_class.new(environment, 'POST', 'garbage', params) }
it 'returns error' do it 'returns error' do
expect(subject.execute).to eq( expect(subject.execute).to eq(
...@@ -72,44 +83,42 @@ describe Prometheus::ProxyService do ...@@ -72,44 +83,42 @@ describe Prometheus::ProxyService do
end end
end end
context 'when cached', :use_clean_rails_memory_store_caching do context 'with caching', :use_clean_rails_memory_store_caching do
let(:return_value) { { 'http_status' => 200, 'body' => 'body' } } let(:return_value) { { 'http_status' => 200, 'body' => 'body' } }
let(:opts) { [environment.class.name, environment.id, 'GET', 'query', { query: '1' }] }
before do let(:opts) do
stub_reactive_cache(subject, return_value, opts) [environment.class.name, environment.id, 'GET', 'query', { 'query' => '1' }]
end
before do
allow(environment).to receive(:prometheus_adapter) allow(environment).to receive(:prometheus_adapter)
.and_return(prometheus_adapter) .and_return(prometheus_adapter)
allow(prometheus_adapter).to receive(:can_query?).and_return(true) allow(prometheus_adapter).to receive(:can_query?).and_return(true)
end end
it 'returns cached value' do context 'when value present in cache' do
result = subject.execute before do
stub_reactive_cache(subject, return_value, opts)
expect(result[:http_status]).to eq(return_value[:http_status]) end
expect(result[:body]).to eq(return_value[:body])
end
end
context 'when not cached' do it 'returns cached value' do
let(:return_value) { { 'http_status' => 200, 'body' => 'body' } } result = subject.execute
let(:opts) { [environment.class.name, environment.id, 'GET', 'query', { query: '1' }] }
before do expect(result[:http_status]).to eq(return_value[:http_status])
allow(environment).to receive(:prometheus_adapter) expect(result[:body]).to eq(return_value[:body])
.and_return(prometheus_adapter) end
allow(prometheus_adapter).to receive(:can_query?).and_return(true)
end end
it 'returns nil' do context 'when value not present in cache' do
expect(ReactiveCachingWorker) it 'returns nil' do
.to receive(:perform_async) expect(ReactiveCachingWorker)
.with(subject.class, subject.id, *opts) .to receive(:perform_async)
.with(subject.class, subject.id, *opts)
result = subject.execute result = subject.execute
expect(result).to eq(nil) expect(result).to eq(nil)
end
end end
end end
...@@ -172,7 +181,9 @@ describe Prometheus::ProxyService do ...@@ -172,7 +181,9 @@ describe Prometheus::ProxyService do
describe '.from_cache' do describe '.from_cache' do
it 'initializes an instance of ProxyService class' do it 'initializes an instance of ProxyService class' do
result = described_class.from_cache(environment.class.name, environment.id, 'GET', 'query', { query: '1' }) result = described_class.from_cache(
environment.class.name, environment.id, 'GET', 'query', { query: '1' }
)
expect(result).to be_an_instance_of(described_class) expect(result).to be_an_instance_of(described_class)
expect(result.proxyable).to eq(environment) expect(result.proxyable).to eq(environment)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment