Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Fix check for invalid annotation name #437

Merged
merged 3 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ demo:
test: $(APP_BIN)
## Django: Run tests
$(APP_BIN) collectstatic --noinput
$(APP_BIN) test -v 2
$(APP_BIN) test -v 2 --buffer

.PHONY: bootstrap
## Django: Bootstrap install
Expand Down
4 changes: 2 additions & 2 deletions promgen/prometheus.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def check_rules(rules):
cmd = [util.setting("prometheus:promtool"), "check", "rules", fp.name]

try:
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
subprocess.check_output(cmd, stderr=subprocess.STDOUT, encoding="utf8")
except subprocess.CalledProcessError as e:
raise ValidationError(rendered.decode("utf8") + e.output.decode("utf8"))
raise ValidationError(message=e.output + rendered.decode("utf8"))


def render_rules(rules=None):
Expand Down
11 changes: 10 additions & 1 deletion promgen/tests/test_alert_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,18 @@ def test_macro(self, mock_post):

@override_settings(PROMGEN=TEST_SETTINGS)
@mock.patch("django.dispatch.dispatcher.Signal.send")
def test_invalid_annotation(self, mock_post):
def test_invalid_annotation_value(self, mock_post):
rule = models.Rule.objects.get(pk=1)
# $label.foo is invalid (should be $labels) so make sure we raise an exception
rule.annotations["summary"] = "{{$label.foo}}"
with self.assertRaises(ValidationError):
prometheus.check_rules([rule])

@override_settings(PROMGEN=TEST_SETTINGS)
@mock.patch("django.dispatch.dispatcher.Signal.send")
def test_invalid_annotation_name(self, mock_post):
rule = models.Rule.objects.get(pk=1)
# $label.foo is invalid (should be $labels) so make sure we raise an exception
rule.annotations["has a space"] = "value"
with self.assertRaises(ValidationError):
prometheus.check_rules([rule])
11 changes: 5 additions & 6 deletions promgen/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ def post(self, request, *args, **kwargs):
context["label_form"] = forms.LabelFormSet(data=request.POST)
context["annotation_form"] = forms.AnnotationFormSet(data=request.POST)

# Before we validate the form, we also want to move our labels and annotations
# into our rule instance, so that they can be validated in the call to promtool
context["form"].instance.labels = context["label_form"].to_dict()
context["form"].instance.annotations = context["annotation_form"].to_dict()

# With our labels+annotations manually cached we can test
if not all(
[
Expand All @@ -791,12 +796,6 @@ def post(self, request, *args, **kwargs):
):
return self.form_invalid(**context)

# After we validate that our forms are valid, we can just copy over the
# cleaned data into our instance so that it can be saved in the call to
# form_valid.
context["form"].instance.labels = context["label_form"].to_dict()
context["form"].instance.annotations = context["annotation_form"].to_dict()

return self.form_valid(context["form"])


Expand Down