diff --git a/promgen/fixtures/testcases.yaml b/promgen/fixtures/testcases.yaml index e2923ebc3..31b0d427e 100644 --- a/promgen/fixtures/testcases.yaml +++ b/promgen/fixtures/testcases.yaml @@ -57,3 +57,16 @@ service: 1 shard: 1 farm: 1 +- model: promgen.exporter + pk: 1 + fields: + project: 1 + job: node + port: 9100 +- model: promgen.exporter + pk: 2 + fields: + project: 2 + job: node + port: 9100 + enabled: false diff --git a/promgen/rest.py b/promgen/rest.py index fd0e368d7..335f984b2 100644 --- a/promgen/rest.py +++ b/promgen/rest.py @@ -32,6 +32,13 @@ def rules(self, request): headers={"Content-Disposition": "attachment; filename=alert.rule.yml"}, ) + @action(detail=False, methods=["get"], renderer_classes=[renderers.renderers.JSONRenderer]) + def targets(self, request): + return HttpResponse( + prometheus.render_config(), + content_type="application/json", + ) + class ShardViewSet(viewsets.ModelViewSet): queryset = models.Shard.objects.all() diff --git a/promgen/templates/promgen/navbar.html b/promgen/templates/promgen/navbar.html index 152e143d9..7fd28b468 100644 --- a/promgen/templates/promgen/navbar.html +++ b/promgen/templates/promgen/navbar.html @@ -34,7 +34,7 @@
  • API
  • -
  • Export Targets
  • +
  • Export Targets
  • Export Rules
  • Export URL
  • diff --git a/promgen/tests/examples/export.rule.yml b/promgen/tests/examples/export.rule.yml new file mode 100644 index 000000000..6ada95ca7 --- /dev/null +++ b/promgen/tests/examples/export.rule.yml @@ -0,0 +1,11 @@ +groups: + - name: promgen.example.com + rules: + - alert: example-rule + annotations: + rule: http://promgen.example.com/rule/1 + summary: Example rule summary + expr: up==1 + for: 1s + labels: + severity: high diff --git a/promgen/tests/examples/export.targets.json b/promgen/tests/examples/export.targets.json new file mode 100644 index 000000000..12bd5bf53 --- /dev/null +++ b/promgen/tests/examples/export.targets.json @@ -0,0 +1,16 @@ +[ + { + "labels": { + "__farm_source": "promgen", + "__scheme__": "http", + "__shard": "test-shard", + "farm": "test-farm", + "job": "node", + "project": "test-project", + "service": "test-service" + }, + "targets": [ + "example.com:9100" + ] + } + ] diff --git a/promgen/tests/test_cli.py b/promgen/tests/test_cli.py index 5b49b5e11..b5cfd7b8a 100644 --- a/promgen/tests/test_cli.py +++ b/promgen/tests/test_cli.py @@ -22,15 +22,15 @@ def test_register_job(self, mock_signal): management.call_command("register-job", "test-project", "example", 1234) # Ensure the jobs we expect exist - self.assertCount(models.Exporter, 1) + self.assertCount(models.Exporter, 3, "Import a new exporter") # Registering the same job again shouldn't change our count management.call_command("register-job", "test-project", "example", 1234) - self.assertCount(models.Exporter, 1) + self.assertCount(models.Exporter, 3, "Import additional exporter") # But registering a new one will management.call_command("register-job", "test-project", "example", 4321) - self.assertCount(models.Exporter, 2) + self.assertCount(models.Exporter, 4, 'Import additional exporter') @mock.patch("promgen.signals._trigger_write_config") def test_register_host(self, mock_signal): diff --git a/promgen/tests/test_renderers.py b/promgen/tests/test_renderers.py new file mode 100644 index 000000000..337c6c160 --- /dev/null +++ b/promgen/tests/test_renderers.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 LINE Corporation +# These sources are released under the terms of the MIT license: see LICENSE + +from django.urls import reverse +from yaml import safe_load + +from promgen import tests + + +class RendererTests(tests.PromgenTest): + fixtures = ["testcases.yaml", "extras.yaml"] + + def test_global_rule(self): + expected = tests.Data("examples", "export.rule.yml").yaml() + response = self.client.get(reverse("api:all-rules")) + self.assertEqual(response.status_code, 200) + # The test client does not have a shortcut to decode yaml + data = safe_load(response.content) + self.assertEqual(data, expected) + + def test_global_targets(self): + expected = tests.Data("examples", "export.targets.json").json() + response = self.client.get(reverse("api:all-targets")) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json(), expected) diff --git a/promgen/tests/test_routes.py b/promgen/tests/test_routes.py index 84d19000b..32f05f2df 100644 --- a/promgen/tests/test_routes.py +++ b/promgen/tests/test_routes.py @@ -30,7 +30,7 @@ def test_import(self, mock_write, mock_reload): self.assertRoute(response, views.Import, 302, "Redirect to imported object") self.assertCount(models.Service, 3, "Import one service (Fixture has two services)") self.assertCount(models.Project, 4, "Import two projects") - self.assertCount(models.Exporter, 2, "Import two exporters") + self.assertCount(models.Exporter, 4, "Import two more exporters") self.assertCount(models.Host, 3, "Import three hosts") @override_settings(PROMGEN=TEST_SETTINGS) @@ -50,7 +50,7 @@ def test_replace(self, mock_write, mock_reload): self.assertCount(models.Service, 3, "Import one service (Fixture has two services)") self.assertCount(models.Project, 4, "Import two projects (Fixture has 2 projectsa)") - self.assertCount(models.Exporter, 2, "Import two exporters") + self.assertCount(models.Exporter, 4, "Import two more exporters") self.assertCount( models.Farm, 4, "Original two farms and one new farm (fixture has one farm)" )