netbox-cisco-ise 0.1.5__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/PKG-INFO +1 -1
  2. netbox_cisco_ise-0.1.7/netbox_cisco_ise/__init__.py +137 -0
  3. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/ise_client.py +3 -11
  4. netbox_cisco_ise-0.1.7/netbox_cisco_ise/templates/netbox_cisco_ise/netbox_endpoint_tab.html +24 -0
  5. netbox_cisco_ise-0.1.7/netbox_cisco_ise/urls.py +21 -0
  6. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/views.py +150 -40
  7. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise.egg-info/PKG-INFO +1 -1
  8. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise.egg-info/SOURCES.txt +1 -0
  9. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/pyproject.toml +1 -1
  10. netbox_cisco_ise-0.1.5/netbox_cisco_ise/__init__.py +0 -60
  11. netbox_cisco_ise-0.1.5/netbox_cisco_ise/urls.py +0 -13
  12. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/LICENSE +0 -0
  13. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/README.md +0 -0
  14. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/navigation.py +0 -0
  15. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/device_tab.html +0 -0
  16. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/endpoint_tab.html +0 -0
  17. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/endpoint_tab_content.html +0 -0
  18. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/nad_tab.html +0 -0
  19. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/nad_tab_content.html +0 -0
  20. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise/templates/netbox_cisco_ise/settings.html +0 -0
  21. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise.egg-info/dependency_links.txt +0 -0
  22. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise.egg-info/requires.txt +0 -0
  23. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/netbox_cisco_ise.egg-info/top_level.txt +0 -0
  24. {netbox_cisco_ise-0.1.5 → netbox_cisco_ise-0.1.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-cisco-ise
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: NetBox plugin for Cisco ISE integration - endpoint tracking, NAD management, and session visibility
5
5
  Author-email: sieteunoseis <jeremy.worden@gmail.com>
6
6
  License: Apache-2.0
@@ -0,0 +1,137 @@
1
+ """
2
+ NetBox Cisco ISE Plugin
3
+
4
+ Display Cisco Identity Services Engine (ISE) endpoint and NAD information in Device detail pages.
5
+ Shows endpoint identity, profiling data, active session status, and network access device details.
6
+ """
7
+
8
+ import logging
9
+
10
+ from netbox.plugins import PluginConfig
11
+
12
+ __version__ = "0.1.7"
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class CiscoISEConfig(PluginConfig):
18
+ """Plugin configuration for NetBox Cisco ISE integration."""
19
+
20
+ name = "netbox_cisco_ise"
21
+ verbose_name = "Cisco ISE"
22
+ description = "Display Cisco ISE endpoint and NAD information in device pages"
23
+ version = __version__
24
+ author = "sieteunoseis"
25
+ author_email = "jeremy.worden@gmail.com"
26
+ base_url = "cisco-ise"
27
+ min_version = "4.0.0"
28
+ max_version = "4.99"
29
+
30
+ # Required settings - plugin won't load without these
31
+ required_settings = []
32
+
33
+ # Default configuration values
34
+ default_settings = {
35
+ # ISE Connection Settings
36
+ "ise_url": "", # e.g., "https://ise.example.com"
37
+ "ise_username": "", # ERS Admin username
38
+ "ise_password": "", # ERS Admin password
39
+ "timeout": 30, # API timeout in seconds
40
+ "cache_timeout": 60, # Cache results for 60 seconds
41
+ "verify_ssl": False, # Skip SSL verification for self-signed certs
42
+ # Device mappings - determines which devices show ISE tab and lookup method
43
+ # Format: list of dicts with manufacturer (regex), device_type (regex, optional), lookup method
44
+ #
45
+ # lookup types:
46
+ # "endpoint" - MAC address lookup (for wireless clients, phones, badges)
47
+ # "nad" - Network Access Device lookup (for switches, routers, WLCs)
48
+ #
49
+ # Example:
50
+ # "device_mappings": [
51
+ # {"manufacturer": "cisco", "lookup": "nad"}, # Cisco network devices as NADs
52
+ # {"manufacturer": "vocera", "lookup": "endpoint"}, # Vocera badges by MAC
53
+ # {"manufacturer": "cisco", "device_type": ".*phone.*", "lookup": "endpoint"}, # Cisco phones by MAC
54
+ # ]
55
+ "device_mappings": [
56
+ {
57
+ "manufacturer": r"cisco",
58
+ "lookup": "nad",
59
+ }, # Default: Cisco devices as NADs
60
+ ],
61
+ # Endpoint mappings (requires netbox-endpoints plugin)
62
+ # Format: list of dicts with manufacturer (regex), endpoint_type (regex, optional)
63
+ # All endpoints use MAC lookup since they're endpoint devices
64
+ #
65
+ # Example:
66
+ # "endpoint_mappings": [
67
+ # {"manufacturer": "vocera"}, # All Vocera endpoints
68
+ # {"manufacturer": "cisco", "endpoint_type": ".*phone.*"}, # Cisco phones
69
+ # ]
70
+ # If empty, shows tab for ALL endpoints with a MAC address
71
+ "endpoint_mappings": [],
72
+ }
73
+
74
+ def ready(self):
75
+ """Register endpoint view if netbox_endpoints is available."""
76
+ super().ready()
77
+ self._register_endpoint_views()
78
+
79
+ def _register_endpoint_views(self):
80
+ """Register Cisco ISE tab for Endpoints if plugin is installed."""
81
+ import sys
82
+
83
+ # Quick check if netbox_endpoints is available
84
+ if "netbox_endpoints" not in sys.modules:
85
+ try:
86
+ import importlib.util
87
+
88
+ if importlib.util.find_spec("netbox_endpoints") is None:
89
+ logger.debug("netbox_endpoints not installed, skipping endpoint view registration")
90
+ return
91
+ except Exception:
92
+ logger.debug("netbox_endpoints not available, skipping endpoint view registration")
93
+ return
94
+
95
+ try:
96
+ from django.shortcuts import render
97
+ from netbox.views import generic
98
+ from netbox_endpoints.models import Endpoint
99
+ from utilities.views import ViewTab, register_model_view
100
+
101
+ from .views import should_show_ise_tab_endpoint
102
+
103
+ @register_model_view(Endpoint, name="cisco_ise", path="cisco-ise")
104
+ class EndpointISEView(generic.ObjectView):
105
+ """Display Cisco ISE endpoint details for a netbox Endpoint."""
106
+
107
+ queryset = Endpoint.objects.all()
108
+ template_name = "netbox_cisco_ise/netbox_endpoint_tab.html"
109
+
110
+ tab = ViewTab(
111
+ label="Cisco ISE",
112
+ weight=9001,
113
+ permission="netbox_endpoints.view_endpoint",
114
+ hide_if_empty=False,
115
+ visible=should_show_ise_tab_endpoint,
116
+ )
117
+
118
+ def get(self, request, pk):
119
+ endpoint = Endpoint.objects.get(pk=pk)
120
+ return render(
121
+ request,
122
+ self.template_name,
123
+ {
124
+ "object": endpoint,
125
+ "tab": self.tab,
126
+ "loading": True,
127
+ },
128
+ )
129
+
130
+ logger.info("Registered Cisco ISE tab for Endpoint model")
131
+ except ImportError:
132
+ logger.debug("netbox_endpoints not installed, skipping endpoint view registration")
133
+ except Exception as e:
134
+ logger.warning(f"Could not register endpoint views: {e}")
135
+
136
+
137
+ config = CiscoISEConfig
@@ -275,9 +275,7 @@ class ISEClient:
275
275
  cached["cached"] = True
276
276
  return cached
277
277
 
278
- result = self._make_ers_request(
279
- "/networkdevice", params={"filter": f"ipaddress.EQ.{ip_address}"}
280
- )
278
+ result = self._make_ers_request("/networkdevice", params={"filter": f"ipaddress.EQ.{ip_address}"})
281
279
 
282
280
  return self._process_nad_result(result, cache_key)
283
281
 
@@ -297,9 +295,7 @@ class ISEClient:
297
295
  cached["cached"] = True
298
296
  return cached
299
297
 
300
- result = self._make_ers_request(
301
- "/networkdevice", params={"filter": f"name.CONTAINS.{name}"}
302
- )
298
+ result = self._make_ers_request("/networkdevice", params={"filter": f"name.CONTAINS.{name}"})
303
299
 
304
300
  return self._process_nad_result(result, cache_key)
305
301
 
@@ -365,11 +361,7 @@ class ISEClient:
365
361
  "ro_community": bool(snmp_settings.get("roCommunity")),
366
362
  "polling_interval": snmp_settings.get("pollingInterval"),
367
363
  },
368
- "trustsec_enabled": bool(
369
- trustsec_settings.get("deviceAuthenticationSettings", {}).get(
370
- "sgaDeviceId"
371
- )
372
- ),
364
+ "trustsec_enabled": bool(trustsec_settings.get("deviceAuthenticationSettings", {}).get("sgaDeviceId")),
373
365
  "coA_port": nad.get("coaPort"),
374
366
  "cached": False,
375
367
  }
@@ -0,0 +1,24 @@
1
+ {% extends 'netbox_endpoints/endpoint.html' %}
2
+ {% load helpers %}
3
+
4
+ {% block content %}
5
+ {% if loading %}
6
+ <div id="ise-content"
7
+ hx-get="{% url 'plugins:netbox_cisco_ise:endpoint_content' pk=object.pk %}"
8
+ hx-trigger="load"
9
+ hx-swap="innerHTML">
10
+ <div class="d-flex justify-content-center align-items-center py-5">
11
+ <div class="text-center">
12
+ <div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
13
+ <span class="visually-hidden">Loading...</span>
14
+ </div>
15
+ <p class="text-muted mb-0">Loading Cisco ISE data...</p>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ {% elif error %}
20
+ <div class="alert alert-warning">
21
+ <i class="mdi mdi-alert"></i> {{ error }}
22
+ </div>
23
+ {% endif %}
24
+ {% endblock %}
@@ -0,0 +1,21 @@
1
+ """
2
+ URL routing for NetBox Cisco ISE Plugin
3
+ """
4
+
5
+ from django.urls import path
6
+
7
+ from .views import ENDPOINTS_PLUGIN_INSTALLED, DeviceISEContentView, ISESettingsView, TestConnectionView
8
+
9
+ urlpatterns = [
10
+ path("settings/", ISESettingsView.as_view(), name="settings"),
11
+ path("test-connection/", TestConnectionView.as_view(), name="test_connection"),
12
+ path("device/<int:pk>/content/", DeviceISEContentView.as_view(), name="device_content"),
13
+ ]
14
+
15
+ # Add endpoint URLs if netbox_endpoints is installed
16
+ if ENDPOINTS_PLUGIN_INSTALLED:
17
+ from .views import EndpointISEContentView
18
+
19
+ urlpatterns.append(
20
+ path("endpoint/<int:pk>/content/", EndpointISEContentView.as_view(), name="endpoint_content"),
21
+ )
@@ -19,6 +19,14 @@ from utilities.views import ViewTab, register_model_view
19
19
 
20
20
  from .ise_client import get_client
21
21
 
22
+ # Check if netbox_endpoints plugin is installed
23
+ try:
24
+ from netbox_endpoints.models import Endpoint
25
+
26
+ ENDPOINTS_PLUGIN_INSTALLED = True
27
+ except ImportError:
28
+ ENDPOINTS_PLUGIN_INSTALLED = False
29
+
22
30
 
23
31
  def is_valid_mac(value):
24
32
  """Check if a value looks like a MAC address."""
@@ -53,18 +61,10 @@ def get_device_lookup_method(device):
53
61
 
54
62
  # Get device info for matching
55
63
  manufacturer = device.device_type.manufacturer
56
- manufacturer_slug = (
57
- manufacturer.slug.lower() if manufacturer and manufacturer.slug else ""
58
- )
59
- manufacturer_name = (
60
- manufacturer.name.lower() if manufacturer and manufacturer.name else ""
61
- )
62
- device_type_slug = (
63
- device.device_type.slug.lower() if device.device_type.slug else ""
64
- )
65
- device_type_model = (
66
- device.device_type.model.lower() if device.device_type.model else ""
67
- )
64
+ manufacturer_slug = manufacturer.slug.lower() if manufacturer and manufacturer.slug else ""
65
+ manufacturer_name = manufacturer.name.lower() if manufacturer and manufacturer.name else ""
66
+ device_type_slug = device.device_type.slug.lower() if device.device_type.slug else ""
67
+ device_type_model = device.device_type.model.lower() if device.device_type.model else ""
68
68
 
69
69
  # Check each mapping
70
70
  for mapping in mappings:
@@ -76,15 +76,12 @@ def get_device_lookup_method(device):
76
76
  manufacturer_match = False
77
77
  if manufacturer_pattern:
78
78
  try:
79
- if re.search(
80
- manufacturer_pattern, manufacturer_slug, re.IGNORECASE
81
- ) or re.search(manufacturer_pattern, manufacturer_name, re.IGNORECASE):
79
+ if re.search(manufacturer_pattern, manufacturer_slug, re.IGNORECASE) or re.search(
80
+ manufacturer_pattern, manufacturer_name, re.IGNORECASE
81
+ ):
82
82
  manufacturer_match = True
83
83
  except re.error:
84
- if (
85
- manufacturer_pattern in manufacturer_slug
86
- or manufacturer_pattern in manufacturer_name
87
- ):
84
+ if manufacturer_pattern in manufacturer_slug or manufacturer_pattern in manufacturer_name:
88
85
  manufacturer_match = True
89
86
 
90
87
  if not manufacturer_match:
@@ -94,15 +91,12 @@ def get_device_lookup_method(device):
94
91
  if device_type_pattern:
95
92
  device_type_match = False
96
93
  try:
97
- if re.search(
98
- device_type_pattern, device_type_slug, re.IGNORECASE
99
- ) or re.search(device_type_pattern, device_type_model, re.IGNORECASE):
94
+ if re.search(device_type_pattern, device_type_slug, re.IGNORECASE) or re.search(
95
+ device_type_pattern, device_type_model, re.IGNORECASE
96
+ ):
100
97
  device_type_match = True
101
98
  except re.error:
102
- if (
103
- device_type_pattern in device_type_slug
104
- or device_type_pattern in device_type_model
105
- ):
99
+ if device_type_pattern in device_type_slug or device_type_pattern in device_type_model:
106
100
  device_type_match = True
107
101
 
108
102
  if not device_type_match:
@@ -169,11 +163,7 @@ class DeviceISEContentView(LoginRequiredMixin, PermissionRequiredMixin, View):
169
163
 
170
164
  def get(self, request, pk):
171
165
  """Fetch ISE data and return HTML content."""
172
- device = (
173
- Device.objects.select_related("device_type__manufacturer")
174
- .prefetch_related("interfaces")
175
- .get(pk=pk)
176
- )
166
+ device = Device.objects.select_related("device_type__manufacturer").prefetch_related("interfaces").get(pk=pk)
177
167
 
178
168
  client = get_client()
179
169
  config = settings.PLUGINS_CONFIG.get("netbox_cisco_ise", {})
@@ -195,10 +185,7 @@ class DeviceISEContentView(LoginRequiredMixin, PermissionRequiredMixin, View):
195
185
  if "error" not in ise_data:
196
186
  # Also get session data for connected endpoints
197
187
  session_data = client.get_active_session_by_mac(mac_address)
198
- if (
199
- "error" in session_data
200
- and session_data.get("connected") is False
201
- ):
188
+ if "error" in session_data and session_data.get("connected") is False:
202
189
  # Not connected is fine, just no active session
203
190
  pass
204
191
  else:
@@ -220,11 +207,7 @@ class DeviceISEContentView(LoginRequiredMixin, PermissionRequiredMixin, View):
220
207
 
221
208
  # If IP lookup failed or no IP, try hostname
222
209
  # Use VC name for virtual chassis members (original hostname)
223
- lookup_hostname = (
224
- device.virtual_chassis.name
225
- if device.virtual_chassis
226
- else device.name
227
- )
210
+ lookup_hostname = device.virtual_chassis.name if device.virtual_chassis else device.name
228
211
  if ("error" in ise_data or not ise_data) and lookup_hostname:
229
212
  ise_data = client.get_network_device_by_name(lookup_hostname)
230
213
 
@@ -298,3 +281,130 @@ class TestConnectionView(View):
298
281
  return JsonResponse(result, status=400)
299
282
 
300
283
  return JsonResponse(result)
284
+
285
+
286
+ # Endpoint-specific functions for netbox_endpoints plugin
287
+ def should_show_ise_tab_endpoint(endpoint):
288
+ """
289
+ Determine if the ISE tab should be visible for this endpoint.
290
+
291
+ Shows tab if endpoint has a MAC address and matches configured endpoint_mappings
292
+ (or if endpoint_mappings is empty, show for all endpoints with MAC).
293
+ """
294
+ if not ENDPOINTS_PLUGIN_INSTALLED:
295
+ return False
296
+
297
+ # Must have MAC address for ISE lookup
298
+ if not endpoint.mac_address:
299
+ return False
300
+
301
+ config = settings.PLUGINS_CONFIG.get("netbox_cisco_ise", {})
302
+ mappings = config.get("endpoint_mappings", [])
303
+
304
+ # If no mappings configured, show for all endpoints with MAC
305
+ if not mappings:
306
+ return True
307
+
308
+ # Check if endpoint matches any mapping
309
+ if not endpoint.endpoint_type:
310
+ return False
311
+
312
+ manufacturer = endpoint.endpoint_type.manufacturer
313
+ manufacturer_slug = manufacturer.slug.lower() if manufacturer and manufacturer.slug else ""
314
+ manufacturer_name = manufacturer.name.lower() if manufacturer and manufacturer.name else ""
315
+ endpoint_type_slug = endpoint.endpoint_type.slug.lower() if endpoint.endpoint_type.slug else ""
316
+ endpoint_type_model = endpoint.endpoint_type.model.lower() if endpoint.endpoint_type.model else ""
317
+
318
+ for mapping in mappings:
319
+ manufacturer_pattern = mapping.get("manufacturer", "").lower()
320
+ endpoint_type_pattern = mapping.get("endpoint_type", "").lower()
321
+
322
+ # Check manufacturer match
323
+ manufacturer_match = False
324
+ if manufacturer_pattern:
325
+ try:
326
+ if re.search(manufacturer_pattern, manufacturer_slug, re.IGNORECASE) or re.search(
327
+ manufacturer_pattern, manufacturer_name, re.IGNORECASE
328
+ ):
329
+ manufacturer_match = True
330
+ except re.error:
331
+ if manufacturer_pattern in manufacturer_slug or manufacturer_pattern in manufacturer_name:
332
+ manufacturer_match = True
333
+
334
+ if not manufacturer_match:
335
+ continue
336
+
337
+ # Check endpoint_type match if specified
338
+ if endpoint_type_pattern:
339
+ endpoint_type_match = False
340
+ try:
341
+ if re.search(endpoint_type_pattern, endpoint_type_slug, re.IGNORECASE) or re.search(
342
+ endpoint_type_pattern, endpoint_type_model, re.IGNORECASE
343
+ ):
344
+ endpoint_type_match = True
345
+ except re.error:
346
+ if endpoint_type_pattern in endpoint_type_slug or endpoint_type_pattern in endpoint_type_model:
347
+ endpoint_type_match = True
348
+
349
+ if not endpoint_type_match:
350
+ continue
351
+
352
+ # Mapping matches
353
+ return True
354
+
355
+ return False
356
+
357
+
358
+ # Endpoint views - only available if netbox_endpoints is installed
359
+ if ENDPOINTS_PLUGIN_INSTALLED:
360
+
361
+ class EndpointISEContentView(LoginRequiredMixin, PermissionRequiredMixin, View):
362
+ """HTMX endpoint that returns ISE content for netbox Endpoint async loading."""
363
+
364
+ permission_required = "netbox_endpoints.view_endpoint"
365
+
366
+ def get(self, request, pk):
367
+ """Fetch ISE data and return HTML content."""
368
+ endpoint = Endpoint.objects.select_related("endpoint_type__manufacturer").get(pk=pk)
369
+
370
+ client = get_client()
371
+ config = settings.PLUGINS_CONFIG.get("netbox_cisco_ise", {})
372
+
373
+ ise_data = {}
374
+ session_data = {}
375
+ error = None
376
+
377
+ if not client:
378
+ error = "Cisco ISE not configured. Configure the plugin in NetBox settings."
379
+ elif not endpoint.mac_address:
380
+ error = "No MAC address configured for this endpoint."
381
+ else:
382
+ # Endpoint lookup by MAC address
383
+ mac_address = str(endpoint.mac_address)
384
+ ise_data = client.get_endpoint_by_mac(mac_address)
385
+ if "error" not in ise_data:
386
+ # Also get session data for connected endpoints
387
+ session_data = client.get_active_session_by_mac(mac_address)
388
+ if "error" in session_data and session_data.get("connected") is False:
389
+ # Not connected is fine, just no active session
390
+ pass
391
+ else:
392
+ error = ise_data.get("error")
393
+ ise_data = {}
394
+
395
+ # Get ISE URL for external links
396
+ ise_url = config.get("ise_url", "").rstrip("/")
397
+
398
+ return HttpResponse(
399
+ render_to_string(
400
+ "netbox_cisco_ise/endpoint_tab_content.html",
401
+ {
402
+ "object": endpoint,
403
+ "ise_data": ise_data,
404
+ "session_data": session_data,
405
+ "error": error,
406
+ "ise_url": ise_url,
407
+ },
408
+ request=request,
409
+ )
410
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-cisco-ise
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: NetBox plugin for Cisco ISE integration - endpoint tracking, NAD management, and session visibility
5
5
  Author-email: sieteunoseis <jeremy.worden@gmail.com>
6
6
  License: Apache-2.0
@@ -16,4 +16,5 @@ netbox_cisco_ise/templates/netbox_cisco_ise/endpoint_tab.html
16
16
  netbox_cisco_ise/templates/netbox_cisco_ise/endpoint_tab_content.html
17
17
  netbox_cisco_ise/templates/netbox_cisco_ise/nad_tab.html
18
18
  netbox_cisco_ise/templates/netbox_cisco_ise/nad_tab_content.html
19
+ netbox_cisco_ise/templates/netbox_cisco_ise/netbox_endpoint_tab.html
19
20
  netbox_cisco_ise/templates/netbox_cisco_ise/settings.html
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "netbox-cisco-ise"
7
- version = "0.1.5"
7
+ version = "0.1.7"
8
8
  description = "NetBox plugin for Cisco ISE integration - endpoint tracking, NAD management, and session visibility"
9
9
  readme = "README.md"
10
10
  license = {text = "Apache-2.0"}
@@ -1,60 +0,0 @@
1
- """
2
- NetBox Cisco ISE Plugin
3
-
4
- Display Cisco Identity Services Engine (ISE) endpoint and NAD information in Device detail pages.
5
- Shows endpoint identity, profiling data, active session status, and network access device details.
6
- """
7
-
8
- from netbox.plugins import PluginConfig
9
-
10
- __version__ = "0.1.5"
11
-
12
-
13
- class CiscoISEConfig(PluginConfig):
14
- """Plugin configuration for NetBox Cisco ISE integration."""
15
-
16
- name = "netbox_cisco_ise"
17
- verbose_name = "Cisco ISE"
18
- description = "Display Cisco ISE endpoint and NAD information in device pages"
19
- version = __version__
20
- author = "sieteunoseis"
21
- author_email = "jeremy.worden@gmail.com"
22
- base_url = "cisco-ise"
23
- min_version = "4.0.0"
24
- max_version = "4.99"
25
-
26
- # Required settings - plugin won't load without these
27
- required_settings = []
28
-
29
- # Default configuration values
30
- default_settings = {
31
- # ISE Connection Settings
32
- "ise_url": "", # e.g., "https://ise.example.com"
33
- "ise_username": "", # ERS Admin username
34
- "ise_password": "", # ERS Admin password
35
- "timeout": 30, # API timeout in seconds
36
- "cache_timeout": 60, # Cache results for 60 seconds
37
- "verify_ssl": False, # Skip SSL verification for self-signed certs
38
- # Device mappings - determines which devices show ISE tab and lookup method
39
- # Format: list of dicts with manufacturer (regex), device_type (regex, optional), lookup method
40
- #
41
- # lookup types:
42
- # "endpoint" - MAC address lookup (for wireless clients, phones, badges)
43
- # "nad" - Network Access Device lookup (for switches, routers, WLCs)
44
- #
45
- # Example:
46
- # "device_mappings": [
47
- # {"manufacturer": "cisco", "lookup": "nad"}, # Cisco network devices as NADs
48
- # {"manufacturer": "vocera", "lookup": "endpoint"}, # Vocera badges by MAC
49
- # {"manufacturer": "cisco", "device_type": ".*phone.*", "lookup": "endpoint"}, # Cisco phones by MAC
50
- # ]
51
- "device_mappings": [
52
- {
53
- "manufacturer": r"cisco",
54
- "lookup": "nad",
55
- }, # Default: Cisco devices as NADs
56
- ],
57
- }
58
-
59
-
60
- config = CiscoISEConfig
@@ -1,13 +0,0 @@
1
- """
2
- URL routing for NetBox Cisco ISE Plugin
3
- """
4
-
5
- from django.urls import path
6
-
7
- from .views import DeviceISEContentView, ISESettingsView, TestConnectionView
8
-
9
- urlpatterns = [
10
- path("settings/", ISESettingsView.as_view(), name="settings"),
11
- path("test-connection/", TestConnectionView.as_view(), name="test_connection"),
12
- path("device/<int:pk>/content/", DeviceISEContentView.as_view(), name="device_content"),
13
- ]