Skip to content

Commit ff3786d

Browse files
authored
feat: display-only diode_target_display plugin config setting (#164)
Allow overriding the displayed Diode Target URL via the diode_target_display plugin config without affecting internal auth communication, so users see the correct external ingress address for gRPC client configuration.
1 parent 0db1758 commit ff3786d

4 files changed

Lines changed: 110 additions & 2 deletions

File tree

netbox_diode_plugin/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class NetBoxDiodePluginConfig(PluginConfig):
4343
# TTL in seconds for caching find_existing_object results in Redis.
4444
# Set to 0 to disable caching.
4545
"find_obj_cache_ttl": 5,
46+
47+
# Override the displayed Diode target URL without affecting internal
48+
# communication (e.g. to show the external ingress address).
49+
"diode_target_display": None,
4650
}
4751

4852

netbox_diode_plugin/tests/v4.4.x/tests/test_views.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,53 @@ def test_settings_created_if_not_found(self):
7676
self.assertIn("grpc://localhost:8080/diode", str(response.content))
7777

7878

79+
def test_settings_display_with_diode_target_display(self):
80+
"""Test that diode_target_display overrides the displayed target."""
81+
self.request.user = User.objects.create_user("foo", password="pass")
82+
self.add_permissions(self.request.user, "netbox_diode_plugin.view_setting")
83+
84+
def mock_get_plugin_config(plugin, key):
85+
if key == "diode_target_display":
86+
return "grpcs://external.example.com/diode"
87+
if key == "diode_target_override":
88+
return None
89+
if key == "diode_target":
90+
return "grpc://localhost:8080/diode"
91+
return None
92+
93+
with mock.patch(
94+
"netbox_diode_plugin.views.get_plugin_config",
95+
side_effect=mock_get_plugin_config,
96+
):
97+
response = self.view.get(self.request)
98+
self.assertEqual(response.status_code, status.HTTP_200_OK)
99+
self.assertIn("grpcs://external.example.com/diode", str(response.content))
100+
self.assertNotIn("grpc://localhost:8080/diode", str(response.content))
101+
102+
def test_diode_target_display_takes_precedence_over_override(self):
103+
"""Test that diode_target_display takes precedence over diode_target_override for display."""
104+
self.request.user = User.objects.create_user("foo", password="pass")
105+
self.add_permissions(self.request.user, "netbox_diode_plugin.view_setting")
106+
107+
def mock_get_plugin_config(plugin, key):
108+
if key == "diode_target_display":
109+
return "grpcs://external.example.com/diode"
110+
if key == "diode_target_override":
111+
return "grpc://internal-override:8080/diode"
112+
if key == "diode_target":
113+
return "grpc://localhost:8080/diode"
114+
return None
115+
116+
with mock.patch(
117+
"netbox_diode_plugin.views.get_plugin_config",
118+
side_effect=mock_get_plugin_config,
119+
):
120+
response = self.view.get(self.request)
121+
self.assertEqual(response.status_code, status.HTTP_200_OK)
122+
self.assertIn("grpcs://external.example.com/diode", str(response.content))
123+
self.assertNotIn("grpc://internal-override:8080/diode", str(response.content))
124+
125+
79126
class SettingsEditViewTestCase(TestCase):
80127
"""Test case for the SettingsEditView."""
81128

netbox_diode_plugin/tests/v4.5.x/tests/test_views.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,53 @@ def test_settings_created_if_not_found(self):
7676
self.assertIn("grpc://localhost:8080/diode", str(response.content))
7777

7878

79+
def test_settings_display_with_diode_target_display(self):
80+
"""Test that diode_target_display overrides the displayed target."""
81+
self.request.user = User.objects.create_user("foo", password="pass")
82+
self.add_permissions(self.request.user, "netbox_diode_plugin.view_setting")
83+
84+
def mock_get_plugin_config(plugin, key):
85+
if key == "diode_target_display":
86+
return "grpcs://external.example.com/diode"
87+
if key == "diode_target_override":
88+
return None
89+
if key == "diode_target":
90+
return "grpc://localhost:8080/diode"
91+
return None
92+
93+
with mock.patch(
94+
"netbox_diode_plugin.views.get_plugin_config",
95+
side_effect=mock_get_plugin_config,
96+
):
97+
response = self.view.get(self.request)
98+
self.assertEqual(response.status_code, status.HTTP_200_OK)
99+
self.assertIn("grpcs://external.example.com/diode", str(response.content))
100+
self.assertNotIn("grpc://localhost:8080/diode", str(response.content))
101+
102+
def test_diode_target_display_takes_precedence_over_override(self):
103+
"""Test that diode_target_display takes precedence over diode_target_override for display."""
104+
self.request.user = User.objects.create_user("foo", password="pass")
105+
self.add_permissions(self.request.user, "netbox_diode_plugin.view_setting")
106+
107+
def mock_get_plugin_config(plugin, key):
108+
if key == "diode_target_display":
109+
return "grpcs://external.example.com/diode"
110+
if key == "diode_target_override":
111+
return "grpc://internal-override:8080/diode"
112+
if key == "diode_target":
113+
return "grpc://localhost:8080/diode"
114+
return None
115+
116+
with mock.patch(
117+
"netbox_diode_plugin.views.get_plugin_config",
118+
side_effect=mock_get_plugin_config,
119+
):
120+
response = self.view.get(self.request)
121+
self.assertEqual(response.status_code, status.HTTP_200_OK)
122+
self.assertIn("grpcs://external.example.com/diode", str(response.content))
123+
self.assertNotIn("grpc://internal-override:8080/diode", str(response.content))
124+
125+
79126
class SettingsEditViewTestCase(TestCase):
80127
"""Test case for the SettingsEditView."""
81128

netbox_diode_plugin/views.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ def get(self, request):
147147
diode_target_override = get_plugin_config(
148148
"netbox_diode_plugin", "diode_target_override"
149149
)
150+
diode_target_display = get_plugin_config(
151+
"netbox_diode_plugin", "diode_target_display"
152+
)
150153

151154
try:
152155
settings = Setting.objects.get()
@@ -158,15 +161,22 @@ def get(self, request):
158161
diode_target=diode_target_override or default_diode_target
159162
)
160163

161-
diode_target = diode_target_override or settings.diode_target
164+
diode_target = (
165+
diode_target_display
166+
or diode_target_override
167+
or settings.diode_target
168+
)
162169

163170
# Check if branching plugin is available
164171
from django.conf import settings as django_settings
165172
has_branching_plugin = "netbox_branching" in django_settings.PLUGINS
166173

167174
context = {
168175
"diode_target": diode_target,
169-
"is_diode_target_overridden": diode_target_override is not None,
176+
"is_diode_target_overridden": (
177+
diode_target_override is not None
178+
or diode_target_display is not None
179+
),
170180
"branch": settings.branch if has_branching_plugin else None,
171181
"has_branching_plugin": has_branching_plugin,
172182
}

0 commit comments

Comments
 (0)