Skip to content

Commit

Permalink
Move promql-query request to the backend
Browse files Browse the repository at this point in the history
The API end point of some shards are protected with HTTP Basic Auth. This is
making the promql-query component to fail receiving a '401 Unauthorized' error
response.

Now that the Shard model supports an "authorization" field to specify the value
of the "Authorization" HTTP header, we can address this issue.

However, if we perform the request in the front end, that information would be
visible by a simple inspection of the HTTP headers. Because of that we have
moved it to the back end.
  • Loading branch information
vincent-olivert-riera committed Jul 1, 2024
1 parent 36f8503 commit f43fde0
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 8 deletions.
10 changes: 6 additions & 4 deletions promgen/static/js/promgen.vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ app.component('silence-form', {

app.component("promql-query", {
delimiters: ['[[', ']]'],
props: ["href", "query", "max"],
props: ["shard", "query", "max"],
data: function () {
return {
count: 0,
Expand All @@ -207,9 +207,11 @@ app.component("promql-query", {
},
template: '#promql-query-template',
mounted() {
var url = new URL(this.href);
url.search = new URLSearchParams({ query: this.query });
fetch(url)
const params = new URLSearchParams({
shard: this.shard,
query: this.query,
});
fetch(`/promql-query?${params}`)
.then(response => response.json())
.then(result => this.count = Number.parseInt(result.data.result[0].value[1]))
.finally(() => this.ready = true);
Expand Down
4 changes: 2 additions & 2 deletions promgen/templates/promgen/project_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ <h1>Register new Project</h1>
</td>
{% if shard.proxy %}
<td>
<promql-query class="label" href='{{shard.url}}/api/v1/query' query='sum(scrape_samples_scraped)' max="{{shard.samples}}">Samples: </promql-query>
<promql-query class="label" shard="{{shard.id}}" query="sum(scrape_samples_scraped)" max="{{shard.samples}}">Samples: </promql-query>
</td>
<td>
<promql-query class="label" href='{{shard.url}}/api/v1/query' query='count(up)' max="{{shard.targets}}">Exporters: </promql-query>
<promql-query class="label" shard="{{shard.id}}" query="count(up)" max="{{shard.targets}}">Exporters: </promql-query>
</td>
{% else %}
<td>&nbsp;</td>
Expand Down
4 changes: 2 additions & 2 deletions promgen/templates/promgen/shard_header.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{% load i18n %}
<div class="well">
{% if shard.proxy %}
<promql-query class="label" href='{{shard.url}}/api/v1/query' query='sum(scrape_samples_scraped)' max="{{shard.samples}}">Samples: </promql-query>
<promql-query class="label" href='{{shard.url}}/api/v1/query' query='count(up)' max="{{shard.targets}}">Exporters: </promql-query>
<promql-query class="label" shard="{{shard.id}}" query="sum(scrape_samples_scraped)" max="{{shard.samples}}">Samples: </promql-query>
<promql-query class="label" shard="{{shard.id}}" query="count(up)" max="{{shard.targets}}">Exporters: </promql-query>
{% endif %}

{% if user.is_superuser %}
Expand Down
2 changes: 2 additions & 0 deletions promgen/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
path("proxy/v1/silences/<silence_id>", csrf_exempt(proxy.ProxyDeleteSilence.as_view()), name="proxy-silence-delete"),
# Promgen rest API
path("rest/", include((router.urls, "api"), namespace="api")),
# PromQL Query
path("promql-query", views.PromqlQuery.as_view(), name="promql-query"),
]

try:
Expand Down
26 changes: 26 additions & 0 deletions promgen/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import CreateView, DeleteView, FormView
from prometheus_client.core import CounterMetricFamily, GaugeMetricFamily
from requests.exceptions import HTTPError

import promgen.templatetags.promgen as macro
from promgen import (
Expand Down Expand Up @@ -1374,3 +1375,28 @@ def post(self, request, pk):
return JsonResponse(
{request.POST["target"]: render_to_string("promgen/ajax_clause_check.html", result)}
)


class PromqlQuery(View):
def get(self, request):
if not all(x in request.GET for x in ["shard", "query"]):
return HttpResponse("BAD REQUEST", status=400)

shard = models.Shard.objects.get(pk=request.GET["shard"])
params = {"query": request.GET["query"]}
headers = {}

if shard.authorization:
headers["Authorization"] = shard.authorization

try:
response = util.get(f"{shard.url}/api/v1/query", params=params, headers=headers)
response.raise_for_status()
except HTTPError:
return HttpResponse(
response.content,
content_type=response.headers["content-type"],
status=response.status_code,
)

return HttpResponse(response.content, content_type="application/json")

0 comments on commit f43fde0

Please sign in to comment.