diff --git a/docs/modules/ROOT/pages/database-diagram.adoc b/docs/modules/ROOT/pages/database-diagram.adoc index a5254e3..7a37839 100644 --- a/docs/modules/ROOT/pages/database-diagram.adoc +++ b/docs/modules/ROOT/pages/database-diagram.adoc @@ -50,6 +50,7 @@ erDiagram ControlPlane { string name string description + string k8s_api_endpoint json api_credentials } diff --git a/src/servala/core/admin.py b/src/servala/core/admin.py index d718fe0..9f2a009 100644 --- a/src/servala/core/admin.py +++ b/src/servala/core/admin.py @@ -112,16 +112,16 @@ class CloudProviderAdmin(admin.ModelAdmin): @admin.register(ControlPlane) class ControlPlaneAdmin(admin.ModelAdmin): form = ControlPlaneAdminForm - list_display = ("name", "cloud_provider") + list_display = ("name", "cloud_provider", "k8s_api_endpoint") list_filter = ("cloud_provider",) - search_fields = ("name", "description") + search_fields = ("name", "description", "k8s_api_endpoint") autocomplete_fields = ("cloud_provider",) actions = ["test_kubernetes_connection"] fieldsets = ( ( None, - {"fields": ("name", "description", "cloud_provider")}, + {"fields": ("name", "description", "k8s_api_endpoint", "cloud_provider")}, ), ( _("API Credentials"), diff --git a/src/servala/core/migrations/0005_remove_controlplane_k8s_api_endpoint.py b/src/servala/core/migrations/0005_remove_controlplane_k8s_api_endpoint.py deleted file mode 100644 index b704b0d..0000000 --- a/src/servala/core/migrations/0005_remove_controlplane_k8s_api_endpoint.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 5.2b1 on 2025-03-24 10:27 - -import encrypted_fields.fields -from django.db import migrations - -import servala.core.models.service - - -class Migration(migrations.Migration): - - dependencies = [ - ("core", "0004_encrypt_api_credentials"), - ] - - operations = [ - migrations.RemoveField( - model_name="controlplane", - name="k8s_api_endpoint", - ), - migrations.AlterField( - model_name="controlplane", - name="api_credentials", - field=encrypted_fields.fields.EncryptedJSONField( - help_text="Required fields: certificate-authority-data, server (URL), token", - validators=[servala.core.models.service.validate_api_credentials], - verbose_name="API credentials", - ), - ), - ] diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 78815da..a3b04d8 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -89,6 +89,7 @@ def validate_api_credentials(value): class ControlPlane(models.Model): name = models.CharField(max_length=100, verbose_name=_("Name")) description = models.TextField(blank=True, verbose_name=_("Description")) + k8s_api_endpoint = models.URLField(verbose_name=_("Kubernetes API endpoint")) # Either contains the fields "certificate_authority_data", "server" and "token", or is empty api_credentials = EncryptedJSONField( verbose_name=_("API credentials"), diff --git a/src/tests/conftest.py b/src/tests/conftest.py index d88870e..d956d39 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -1,18 +1,12 @@ import pytest +from servala.core.models import Organization, OrganizationMembership, User, OrganizationOrigin -from servala.core.models import ( - Organization, - OrganizationMembership, - OrganizationOrigin, - User, -) @pytest.fixture def origin(): return OrganizationOrigin.objects.create(name="TESTORIGIN") - @pytest.fixture def organization(origin): return Organization.objects.create(name="Test Org", origin=origin) @@ -22,11 +16,9 @@ def organization(origin): def other_organization(origin): return Organization.objects.create(name="Test Org Alternate", origin=origin) - @pytest.fixture def org_owner(organization): user = User.objects.create(email="user@example.org", password="example") - OrganizationMembership.objects.create( - organization=organization, user=user, role="owner" - ) + OrganizationMembership.objects.create(organization=organization, user=user, role="owner") return user + diff --git a/src/tests/test_views.py b/src/tests/test_views.py index 23475fc..adf7d29 100644 --- a/src/tests/test_views.py +++ b/src/tests/test_views.py @@ -1,13 +1,10 @@ import pytest -@pytest.mark.parametrize( - "url,redirect", - ( - ("/", "/accounts/login/?next=/"), - ("/accounts/profile/", "/accounts/login/?next=/accounts/profile/"), - ), -) +@pytest.mark.parametrize("url,redirect", ( + ("/", "/accounts/login/?next=/"), + ("/accounts/profile/", "/accounts/login/?next=/accounts/profile/") +)) def test_root_view_redirects_valid_urls(client, url, redirect): response = client.get(url) assert response.status_code == 302 @@ -36,9 +33,7 @@ def test_user_cannot_see_other_organization(client, org_owner, other_organizatio @pytest.mark.django_db -def test_organization_linked_in_sidebar( - client, org_owner, organization, other_organization -): +def test_organization_linked_in_sidebar(client, org_owner, organization, other_organization): client.force_login(org_owner) response = client.get("/", follow=True) assert response.status_code == 200