Troubleshooting ISE SDK Issues
Overview
When ISE doesn’t behave as expected (like parent groups not nesting properly), the issue is often a mismatch between what netapi sends and what the ciscoisesdk expects.
This guide shows you how to debug these issues yourself.
Common Issue: Parameter Name Mismatch
Symptom
# You create a child group with --parent
netapi ise create-endpoint-group "Linux-Research-Workstations" \
--description "Child group" \
--parent "Linux-Workstations"
# ✓ Command succeeds (no error)
# ✗ But in ISE GUI, groups are independent (no hierarchy)
The command doesn’t fail, but the parent relationship is silently ignored.
How to Debug This Yourself
Step 1: Inspect the SDK Method Signature
Check what parameters the ciscoisesdk method actually expects:
python3 << 'EOF'
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
# Create dummy client (doesn't need to connect)
client = IdentityServicesEngineAPI(
username="dummy",
password="dummy",
base_url="https://dummy"
)
# Get the method you're debugging
method = client.endpoint_identity_group.create_endpoint_group
# Print the signature
sig = inspect.signature(method)
print("create_endpoint_group parameters:")
for param_name, param in sig.parameters.items():
print(f" {param_name}: {param.annotation if param.annotation != inspect.Parameter.empty else 'Any'}")
EOF
Output:
create_endpoint_group parameters:
description: Any
name: Any
system_defined: Any
parent_id: Any <-- SNAKE_CASE, not parentId!
headers: Any
payload: Any
active_validation: Any
query_parameters: Any
Step 2: Check What netapi is Sending
Look at the code in ers_client.py:
# Find the create method
grep -n "def create_endpoint_group" \
~/atelier/_projects/personal/netapi/netapi/vendors/cisco/ise/ers_client.py
Read the method (e.g., line 572):
# Read the method implementation
cat -n ~/atelier/_projects/personal/netapi/netapi/vendors/cisco/ise/ers_client.py \
| sed -n '572,620p'
Look for the line that builds the payload:
# WRONG (camelCase)
payload["parentId"] = parent.get("id")
# CORRECT (snake_case)
payload["parent_id"] = parent.get("id")
Step 3: Fix the Parameter Name
Edit ers_client.py:
cd ~/atelier/_projects/personal/netapi
# Open in your editor
nvim netapi/vendors/cisco/ise/ers_client.py +609
Change:
# Before
payload["parentId"] = parent.get("id")
# After
payload["parent_id"] = parent.get("id")
Step 4: Test the Fix
# Delete old groups
netapi ise delete-endpoint-group "Linux-Research-Workstations"
netapi ise delete-endpoint-group "Linux-Workstations"
# Recreate with parent
netapi ise create-endpoint-group "Linux-Workstations" \
--description "Parent group"
netapi ise create-endpoint-group "Linux-Research-Workstations" \
--description "Child group" \
--parent "Linux-Workstations"
# Verify in ISE GUI - should now show proper hierarchy
Step 5: Commit the Fix
cd ~/atelier/_projects/personal/netapi
git add netapi/vendors/cisco/ise/ers_client.py
git commit -m "[fix] Endpoint group parent - use parent_id not parentId
Bug: parentId (camelCase) was silently ignored by ISE SDK
Fix: Changed to parent_id (snake_case) per ciscoisesdk signature
Location: ers_client.py:609"
Common Parameter Naming Issues
| Wrong (ignored by SDK) | Correct (SDK expects) | Resource |
|---|---|---|
|
|
Endpoint Groups |
|
|
Endpoints |
|
|
Authorization Profiles (depends on API) |
|
|
Authorization Profiles |
Rule of thumb: ISE SDK uses snake_case for parameters, not camelCase.
Debugging Workflow Summary
# 1. Inspect SDK method signature
python3 -c "
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username='x', password='x', base_url='https://x')
method = client.<resource>.<method_name>
print(inspect.signature(method))
"
# 2. Find netapi implementation
grep -n "def <method_name>" \
~/atelier/_projects/personal/netapi/netapi/vendors/cisco/ise/ers_client.py
# 3. Read the code
cat -n ~/atelier/_projects/personal/netapi/netapi/vendors/cisco/ise/ers_client.py \
| sed -n '<line_start>,<line_end>p'
# 4. Fix parameter name mismatch
# Edit ers_client.py and change camelCase to snake_case
# 5. Test
netapi ise <command> <args>
# 6. Commit
git add netapi/vendors/cisco/ise/ers_client.py
git commit -m "[fix] <description>"
Other Debugging Techniques
Enable SDK Debug Logging
Set debug logging to see raw API calls:
import logging
logging.basicConfig(level=logging.DEBUG)
# Then run your netapi command
# You'll see HTTP requests/responses in the logs
Check ISE ERS API Documentation
Official Cisco ISE ERS API reference shows exact field names:
# ISE GUI: Administration > System > Settings > ERS Settings > SDK Download
# Or: https://<ISE_PAN>:9060/ers/sdk
Compare the JSON schema in the docs to what netapi is sending.
Use ISE API Inspector
ISE has built-in API logging:
-
Enable ERS API logging: Administration > System > Logging > Debug Log Configuration
-
Set level:
erscomponent toDEBUG -
Watch logs: Operations > Troubleshoot > Debug Logs > Download Logs
-
Search for: Your API calls and see what payload ISE received
Test with curl
Bypass netapi and test the API directly:
# Get credentials
eval "$(dsec source d000 dev/ise)"
# Test endpoint group creation with parent_id
curl -k -u "${ISE_API_USER}:${ISE_API_PASS}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST "https://${ISE_PAN_IP}:9060/ers/config/endpointgroup" \
-d '{
"EndpointGroup": {
"name": "Test-Child-Group",
"description": "Testing parent_id",
"parent_id": "<parent-group-uuid>"
}
}'
If curl works but netapi doesn’t, the issue is in netapi’s code.
Real-World Example: Endpoint Group Parent
Problem: Groups created with --parent were independent, not nested.
Investigation:
# 1. Check SDK signature
python3 -c "
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username='x', password='x', base_url='https://x')
print(inspect.signature(client.endpoint_identity_group.create_endpoint_group))
"
# Output showed: parent_id (not parentId)
Code Review:
# ers_client.py:609 (WRONG)
payload["parentId"] = parent.get("id")
# Should be (CORRECT)
payload["parent_id"] = parent.get("id")
Fix:
# Changed parentId → parent_id
# Committed with git commit
# Tested - groups now nest properly
Quick Reference: Inspecting Other Methods
Check Authorization Profile Parameters
python3 << 'EOF'
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username="x", password="x", base_url="https://x")
method = client.authorization_profile.create_authorization_profile
sig = inspect.signature(method)
print("create_authorization_profile parameters:")
for param_name in sig.parameters.keys():
print(f" {param_name}")
EOF
Check Network Device Parameters
python3 << 'EOF'
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username="x", password="x", base_url="https://x")
method = client.network_device.create_network_device
sig = inspect.signature(method)
print("create_network_device parameters:")
for param_name in sig.parameters.keys():
print(f" {param_name}")
EOF
Check SGT Parameters
python3 << 'EOF'
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username="x", password="x", base_url="https://x")
method = client.security_groups.create_security_group
sig = inspect.signature(method)
print("create_security_group parameters:")
for param_name in sig.parameters.keys():
print(f" {param_name}")
EOF
Prevention: Check Before Implementing
When adding a new netapi command:
# 1. Always check SDK signature first
python3 -c "
import inspect
from ciscoisesdk import IdentityServicesEngineAPI
client = IdentityServicesEngineAPI(username='x', password='x', base_url='https://x')
print(inspect.signature(client.<resource>.<method>))
"
# 2. Match parameter names exactly (use snake_case)
# 3. Test with a simple case
# 4. Verify in ISE GUI that the result is correct