85 lines
2.5 KiB
Ruby
85 lines
2.5 KiB
Ruby
# typed: true
|
|
# frozen_string_literal: true
|
|
class Admin::ProxyController < ApplicationController
|
|
before_action :authenticate_user!
|
|
before_action :require_admin!
|
|
skip_before_action :verify_authenticity_token, only: %i[grafana prometheus]
|
|
|
|
def grafana
|
|
fullpath =
|
|
"http://grafana:3100#{request.fullpath.delete_prefix("/grafana")}"
|
|
proxy_response(fullpath, "/grafana")
|
|
end
|
|
|
|
def prometheus
|
|
fullpath = "http://prometheus:9090#{request.fullpath.delete_prefix("/prometheus")}"
|
|
proxy_response(fullpath, "/prometheus")
|
|
end
|
|
|
|
private
|
|
|
|
def require_admin!
|
|
unless current_user&.admin?
|
|
redirect_to root_path, alert: "You are not authorized to access this area"
|
|
end
|
|
end
|
|
|
|
def grafana_proxy_headers
|
|
{ "X-WEBAUTH-USER" => "admin" }.merge(proxy_headers)
|
|
end
|
|
|
|
def proxy_headers
|
|
{
|
|
"X-Forwarded-Host" => request.host_with_port,
|
|
"X-Forwarded-Proto" => request.ssl? ? "https" : "http",
|
|
"X-Forwarded-For" => request.remote_ip,
|
|
"Host" => request.host,
|
|
"Connection" => request.headers["Connection"],
|
|
"Upgrade" => request.headers["Upgrade"],
|
|
"Accept" => request.headers["Accept"],
|
|
"Cookie" => request.headers["Cookie"],
|
|
"Content-Type" => request.headers["Content-Type"],
|
|
"Content-Length" => request.headers["Content-Length"],
|
|
}.merge
|
|
end
|
|
|
|
def websocket_request?
|
|
request.headers["Connection"]&.include?("upgrade")
|
|
end
|
|
|
|
def proxy_response(fullpath, prefix)
|
|
method = request.method.downcase.to_s
|
|
if method == "post"
|
|
response = HTTP.headers(grafana_proxy_headers).send(method, fullpath, body: request.raw_post)
|
|
else
|
|
response = HTTP.headers(grafana_proxy_headers).send(method, fullpath)
|
|
end
|
|
|
|
headers = response.headers.to_h
|
|
|
|
# Handle redirects by rewriting the Location header
|
|
if response.code.in?([301, 302, 303, 307, 308]) &&
|
|
headers["Location"].present?
|
|
location = headers["Location"]
|
|
# Strip the host from absolute URLs
|
|
location = location.gsub(%r{^https?://[^/]+}, "")
|
|
# Add our prefix to relative URLs
|
|
location = "#{prefix}#{location}" if location.start_with?("/")
|
|
headers["Location"] = location
|
|
end
|
|
|
|
# Pass through the response with all headers
|
|
response_headers = headers.except("Content-Type")
|
|
|
|
render_args = {
|
|
body: response.body.to_s,
|
|
status: response.code,
|
|
content_type: headers["Content-Type"],
|
|
headers: response_headers,
|
|
}
|
|
render_args[:location] = headers["Location"] if headers["Location"]
|
|
|
|
render render_args
|
|
end
|
|
end
|