From 103875334b0a55d3ae9fd052221c6bc76371f3d4 Mon Sep 17 00:00:00 2001 From: Tom Gamull Date: Tue, 3 Jun 2025 09:59:27 -0400 Subject: [PATCH 1/2] docs: add CURSOR_CONTEXT.md for comprehensive documentation and update .gitignore --- .gitignore | 3 +- CURSOR_CONTEXT.md | 113 ++++ .../netbox-enterprise/nbe-jinja2-templates.md | 550 ++++++++++++++++++ 3 files changed, 665 insertions(+), 1 deletion(-) create mode 100644 CURSOR_CONTEXT.md create mode 100644 docs/netbox-enterprise/nbe-jinja2-templates.md diff --git a/.gitignore b/.gitignore index 7a98396a..262a07e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ docs/images/.DS_Store .DS_Store -venv/ \ No newline at end of file +venv/ +scratch/ \ No newline at end of file diff --git a/CURSOR_CONTEXT.md b/CURSOR_CONTEXT.md new file mode 100644 index 00000000..4969d2c6 --- /dev/null +++ b/CURSOR_CONTEXT.md @@ -0,0 +1,113 @@ +# CURSOR_CONTEXT.md + +## Repository Overview + +This repository (`console-docs`) contains the commercial/enterprise documentation for NetBox Labs' products and services. It serves as one component of the unified NetBox documentation ecosystem that powers the official documentation site at https://netboxlabs.com/docs. + +## Documentation Architecture + +The NetBox documentation ecosystem consists of multiple repositories that are combined to create a comprehensive documentation hub: + +### Repository Structure +- **`netboxlabs/netbox`**: Contains the core NetBox open-source documentation (community docs) +- **`netboxlabs/console-docs`** (this repo): Contains commercial/enterprise product documentation +- **`netboxlabs/netboxlabs-website-dochub`**: The deployment/integration repository that combines both documentation sources + +### Content Organization + +This repository contains documentation for NetBox Labs' commercial offerings: + +#### Core Sections +- **Administration Console/**: NetBox Cloud administration interface documentation +- **NetBox Cloud/**: Cloud-hosted NetBox service documentation +- **netbox-enterprise/**: Enterprise edition features and configuration +- **netbox-assurance/**: Network assurance and monitoring capabilities +- **netbox-discovery/**: Automated network discovery features +- **netbox-extensions/**: Advanced features like branching, changes tracking, and diode +- **netbox-integrations/**: Third-party service integrations (ServiceNow, etc.) +- **cloud-connectivity/**: Cloud connectivity and networking documentation +- **sdks/**: Software development kits and API documentation + +#### Supporting Content +- **images/**: Screenshots, diagrams, and visual assets organized by feature +- **stylesheets/**: Custom styling for documentation presentation + +## Integration Process + +The documentation deployment process works as follows: + +1. **Content Sources**: + - Community docs from `netboxlabs/netbox` repository + - Commercial docs from this repository (`netboxlabs/console-docs`) + +2. **Integration Hub**: + - `netboxlabs/netboxlabs-website-dochub` repository combines both sources + - Handles navigation structure, cross-references, and unified presentation + +3. **Deployment**: + - Combined documentation is deployed to https://netboxlabs.com/docs + - Provides seamless experience between community and commercial documentation + +## Build & Deployment Pipeline + +The `netboxlabs-website-dochub` repository handles the technical build and deployment process: + +### Build Technology +- **Framework**: Uses Docusaurus for static site generation +- **Package Manager**: yarn for dependency management and build orchestration +- **Source Integration**: Combines content from both community and commercial documentation repositories + +### Deployment Workflow +1. **Preview Environment**: Changes are previewed in Vercel before production deployment +2. **Production Pipeline**: Built site is pushed to production hosting +3. **Automatic Integration**: **(Unverified)** Merges to this repository should automatically trigger the production pipeline, but this process has not been fully verified yet + +### Integration Status +- **Current State**: Manual verification may be required for production deployments +- **Intended Behavior**: Automatic merge-to-production workflow from this repository +- **Status**: Integration pipeline verification is pending + +## Documentation Technology + +- **Framework**: Built using MkDocs (configured in `mkdocs.yml`) +- **Content Format**: Markdown files with MkDocs extensions +- **Styling**: Custom CSS in `stylesheets/` directory +- **Assets**: Images and media files organized by feature/product + +## Key Considerations for Development + +### Content Strategy +- **Audience Separation**: Clear distinction between community (open-source) and commercial content +- **Feature Parity**: Commercial docs should complement, not duplicate, community documentation +- **Cross-References**: Links between community and commercial docs should work seamlessly + +### File Organization +- Keep related images in corresponding subdirectories under `docs/images/` +- Maintain consistent naming conventions across features +- Organize content hierarchically to match product structure + +### Integration Points +- Navigation structure must align with the combined documentation site +- Cross-references to community docs should use appropriate linking strategies +- Consider how content will appear in the unified search experience + +## Development Workflow + +When working on this repository: + +1. **Local Development**: Use MkDocs for local preview and testing +2. **Content Changes**: Focus on commercial/enterprise features and capabilities +3. **Asset Management**: Ensure images are optimized and properly organized +4. **Integration Testing**: Consider how changes will appear in the combined documentation site +5. **Deployment Verification**: Monitor the automatic deployment process (when fully verified) + +## Related Resources + +- **Main Documentation Site**: https://netboxlabs.com/docs +- **NetBox Community Docs**: Part of the `netboxlabs/netbox` repository +- **Integration Repository**: `netboxlabs/netboxlabs-website-dochub` +- **NetBox GitHub**: https://github.com/netbox-community/netbox (referenced in web content) + +## Purpose Statement + +This repository ensures that NetBox Labs' commercial customers have comprehensive, well-organized documentation for enterprise features while maintaining the unified experience with community documentation that makes NetBox the premier network source of truth solution. \ No newline at end of file diff --git a/docs/netbox-enterprise/nbe-jinja2-templates.md b/docs/netbox-enterprise/nbe-jinja2-templates.md new file mode 100644 index 00000000..39bfe087 --- /dev/null +++ b/docs/netbox-enterprise/nbe-jinja2-templates.md @@ -0,0 +1,550 @@ +# Getting Started with Jinja2 Templates in NetBox Enterprise + +## ๐Ÿ“Œ Introduction + +### What are Jinja2 Templates? + +Jinja2 is a powerful and modern templating engine for Python that allows you to create dynamic content by combining static templates with variable data. In NetBox Enterprise, Jinja2 templates enable you to automate configuration generation, customize data exports, and create dynamic content based on your network infrastructure data. + +### Why Use Jinja2 Templates in NetBox? + +Jinja2 templates in NetBox Enterprise provide several key benefits: + +- **Configuration Automation**: Generate vendor-specific device configurations automatically +- **Data Consistency**: Ensure standardized configurations across your network infrastructure +- **Dynamic Content**: Create customized exports and reports based on real-time NetBox data +- **Integration Ready**: Seamlessly integrate with configuration management tools and CI/CD pipelines +- **Error Reduction**: Minimize manual configuration errors through automated generation + +--- + +## ๐Ÿ” Where Templates Are Used in NetBox + +NetBox Enterprise leverages Jinja2 templates in several key areas: + +### Configuration Rendering +- Generate device-specific configurations based on NetBox data +- Create standardized configuration snippets for different device types +- Automate the creation of network service configurations + +### Export Templates +- Customize data exports for specific formats (CSV, JSON, XML) +- Create vendor-specific configuration files +- Generate reports and documentation + +### Webhooks +- Dynamic payload generation for external system integration +- Custom notification content based on NetBox events +- Automated workflow triggers with contextual data + +### Custom Fields +- Dynamic default values based on other object attributes +- Conditional field validation and formatting +- Automated field population based on templates + +--- + +## ๐Ÿง  Understanding the Rendering Context + +### Configuration Context Overview + +Configuration contexts in NetBox provide structured data that can be consumed by Jinja2 templates. This data is hierarchically organized and can be defined at multiple levels: + +- **Global**: Applied to all devices +- **Region/Site Group**: Applied to devices within specific geographic or organizational boundaries +- **Site**: Applied to devices at specific locations +- **Device Role**: Applied to devices with specific functions +- **Platform**: Applied to devices running specific operating systems +- **Device Type**: Applied to specific hardware models +- **Device**: Applied to individual devices + +### Rendering Context Objects + +When templates are rendered, NetBox provides access to various context objects: + +#### Device Context +```jinja2 +{{ device.name }} +{{ device.device_type.manufacturer.name }} +{{ device.platform.name }} +{{ device.primary_ip4.address }} +{{ device.site.name }} +{{ device.tenant.name }} +``` + +#### Site Context +```jinja2 +{{ site.name }} +{{ site.region.name }} +{{ site.asn }} +{{ site.time_zone }} +{{ site.physical_address }} +``` + +#### Interface Context +```jinja2 +{% for interface in device.interfaces.all %} +{{ interface.name }}: {{ interface.ip_addresses.first.address }} +{% endfor %} + +# Direct interface access by index +{{ device.interfaces.0.name }} +{{ device.interfaces.0.ip_addresses.0.address }} +``` + +#### Custom Fields +```jinja2 +{{ device.custom_fields.management_vlan }} +{{ device.custom_fields.snmp_community }} +{{ device.site.custom_fields.region_code }} +``` + +### Common Filters + +NetBox provides several useful Jinja2 filters for network-specific operations: + +#### IP Address Filters +```jinja2 +{{ ip_address | ipaddr('address') }} # Extract IP address only +{{ ip_address | ipaddr('network') }} # Get network address +{{ ip_address | ipaddr('netmask') }} # Get subnet mask +{{ prefix | ipaddr('first_usable') }} # First usable IP in range +``` + +#### Network Filters +```jinja2 +{{ vlan_id | add:100 }} # Add to VLAN ID +{{ interface_name | upper }} # Convert to uppercase +{{ hostname | lower }} # Convert to lowercase +{{ config.ntp_servers | join("\nntp server ") }} # Join with custom separator +``` + +#### NetBox-Specific Filters +From [jinja2_filters](https://docs.netbox.dev/en/stable/configuration/system/#jinja2_filters): +- `as_slug` - Convert to URL-friendly slug +- `naturalize` - Format numbers naturally +- `humanize_speed` - Format bandwidth values +- `split` - Split strings into lists +- `join` - Join lists into strings + +### Common Pitfalls + +#### Undefined Variables +Always check for variable existence to avoid template errors: + +```jinja2 +# Problematic +{{ device.primary_ip4.address }} + +# Better +{% if device.primary_ip4 %} +{{ device.primary_ip4.address }} +{% else %} +# No primary IP configured +{% endif %} + +# Best +{{ device.primary_ip4.address | default('DHCP') }} +``` + +#### Data Type Issues +```jinja2 +# Ensure proper data types +{{ vlan_id | int }} # Convert to integer +{{ is_enabled | bool }} # Convert to boolean +{{ description | string }} # Convert to string +``` + +--- + +## ๐Ÿ› ๏ธ Step-by-Step Example: Cisco Switch Configuration + +Let's walk through creating a complete Cisco switch configuration using NetBox data. + +### Step 1: Define Configuration Context + +Create a configuration context at the device role level for switches: + +```json +{ + "ntp_servers": ["10.1.1.10", "10.1.1.11"], + "syslog_servers": ["10.1.1.20", "10.1.1.21"], + "snmp": { + "community": "netbox_ro", + "location": "{{ site.physical_address }}" + }, + "vlans": { + "management": 100, + "user": 200, + "voice": 300 + }, + "location_id": "{{ site.name | as_slug }}" +} +``` + +### Step 2: Create the Template + +```jinja2 +! +! Configuration generated by NetBox Enterprise +! Device: {{ device.name }} +! Generated: {{ now() }} +! +version 15.2 +! +hostname {{ device.name }} +! +{% if device.primary_ip4 %} +ip domain-name {{ device.site.name | lower }}.company.com +{% endif %} +! +! NTP Configuration +{% for ntp_server in ntp_servers %} +ntp server {{ ntp_server }} +{% endfor %} +! +! SNMP Configuration +snmp-server community {{ snmp.community }} RO +snmp-server location {{ location_id }} +snmp-server contact {{ device.tenant.name | default('Network Operations') }} +! +! VLAN Configuration +{% for vlan_name, vlan_id in vlans.items() %} +vlan {{ vlan_id }} + name {{ vlan_name | upper }} +! +{% endfor %} +! +! Interface Configuration +{% for interface in device.interfaces.all %} +{% if interface.enabled and interface.type.value != 'virtual' %} +interface {{ interface.name }} + description {{ interface.description | default('Managed by NetBox') }} +{% if interface.mode and interface.mode.value == 'access' %} + switchport mode access +{% if interface.untagged_vlan %} + switchport access vlan {{ interface.untagged_vlan.vid }} +{% endif %} +{% elif interface.mode and interface.mode.value == 'tagged' %} + switchport mode trunk +{% if interface.tagged_vlans.all %} + switchport trunk allowed vlan {{ interface.tagged_vlans.all | join(',', attribute='vid') }} +{% endif %} +{% endif %} +{% if not interface.enabled %} + shutdown +{% endif %} +! +{% endif %} +{% endfor %} +! +! Management Interface +{% if device.primary_ip4 %} +interface vlan{{ vlans.management }} + ip address {{ device.primary_ip4.address | ipaddr('address') }} {{ device.primary_ip4.address | ipaddr('netmask') }} + no shutdown +! +ip default-gateway {{ device.primary_ip4.address | ipaddr('network') | ipaddr('1') | ipaddr('address') }} +{% endif %} +! +! Syslog Configuration +{% for syslog_server in syslog_servers %} +logging host {{ syslog_server }} +{% endfor %} +! +end +``` + +### Step 3: Apply the Template + +Navigate to: +1. **Device โ†’ Configuration tab** โ†’ Select the template โ†’ View rendered output +2. **Export Templates** โ†’ Create an export template in NetBox Enterprise +3. **API Endpoint**: Use the `/api/dcim/devices/{id}/render-config/` endpoint +4. **Custom Scripts**: Integrate with your automation workflows + +### Step 4: Validate the Output + +Always validate generated configurations: + +```bash +# Example validation for Cisco configs +cisco-config-validator validate --file generated_config.txt + +# Or use NetBox's built-in validation +curl -X POST http://netbox.company.com/api/dcim/devices/1/render-config/ \ + -H "Authorization: Token your-api-token" \ + -H "Content-Type: application/json" +``` + +--- + +## ๐Ÿš€ Advanced Use Cases + +### ๐Ÿ” Loops and Conditionals + +```jinja2 +{% for intf in device.interfaces.all %} +interface {{ intf.name }} + {% if intf.enabled %} no shutdown {% else %} shutdown {% endif %} + {% if intf.ip_addresses.first %} + ip address {{ intf.ip_addresses.first.address }} + {% endif %} +{% endfor %} +``` + +### ๐Ÿงฑ Nested Data Access + +Access complex nested data structures: + +```jinja2 +{% for circuit in device.site.circuits.all %} +Circuit {{ circuit.cid }}: + Provider: {{ circuit.provider.name }} + Type: {{ circuit.type.name }} + Bandwidth: {{ circuit.commit_rate }} {{ circuit.commit_rate_unit }} + + {% for termination in circuit.terminations.all %} + {% if termination.site == device.site %} + Termination: {{ termination.port_speed }} on {{ termination.pp_info }} + {% endif %} + {% endfor %} +{% endfor %} +``` + +### ๐Ÿงช Using Custom Fields Effectively + +Leverage custom fields for template logic: + +```jinja2 +{% set device_env = device.custom_fields.environment | default('production') %} +{% set backup_enabled = device.custom_fields.backup_enabled | default(true) %} + +! Environment: {{ device_env | upper }} +! Building: {{ device.custom_fields.building }} +! Region: {{ device.site.custom_fields.region_code }} + +{% if device_env == 'production' %} +! Production device - backup enabled +archive + path bootflash:backup-configs + write-memory +{% elif backup_enabled %} +! Non-production device with backup enabled +ip scp server enable +{% endif %} +``` + +### ๐ŸŒ Environment Segmentation + +Handle different environments with conditional logic: + +```jinja2 +{% if device.tenant.name == 'staging' %} +! Staging Environment Configuration +snmp-server community staging_{{ snmp.community }} RO +logging host {{ syslog_servers | first }} +{% elif device.tenant.name == 'production' %} +! Production Environment Configuration +snmp-server community prod_{{ snmp.community }} RO +{% for server in syslog_servers %} +logging host {{ server }} +{% endfor %} +{% endif %} +``` + +--- + +## ๐Ÿงช Testing & Debugging Templates + +### ๐Ÿ”ง Testing Templates Locally + +Use NetBox's shell_plus for template testing: + +```python +# NetBox shell_plus +from django.template import Template, Context +from dcim.models import Device + +# Get a test device +device = Device.objects.get(name='test-switch-01') + +# Create template +template_content = """ +Device: {{ device.name }} +Site: {{ device.site.name }} +IP: {{ device.primary_ip4.address | default('No IP assigned') }} +""" + +template = Template(template_content) +context = Context({'device': device}) +result = template.render(context) +print(result) +``` + +### ๐Ÿ› ๏ธ Handling Common Errors + +#### Template Syntax Errors +```jinja2 +# Problematic: Missing endif +{% if device.primary_ip4 %} +IP: {{ device.primary_ip4.address }} + +# Fixed: Proper closure +{% if device.primary_ip4 %} +IP: {{ device.primary_ip4.address }} +{% endif %} +``` + +#### Variable Access Errors +```jinja2 +# Problematic: May cause AttributeError +{{ device.interfaces.first.ip_addresses.first.address }} + +# Better: Check existence +{% if device.interfaces.first and device.interfaces.first.ip_addresses.first %} +{{ device.interfaces.first.ip_addresses.first.address }} +{% endif %} + +# Best: Use filters with fallbacks +{{ device.interfaces.first.ip_addresses.first.address | default('No IP') }} +``` + +### ๐Ÿ” API Validation Endpoints + +Use NetBox Enterprise's validation endpoints: + +```bash +# Validate template syntax +curl -X POST "http://netbox.company.com/api/extras/export-templates/validate/" \ + -H "Authorization: Token your-token" \ + -H "Content-Type: application/json" \ + -d '{ + "template_code": "{{ device.name }}\n{{ device.site.name }}", + "object_type": "dcim.device" + }' + +# Test template rendering +curl -X POST "http://netbox.company.com/api/dcim/devices/1/render-config/" \ + -H "Authorization: Token your-token" \ + -H "Content-Type: application/json" \ + -d '{"template_id": 1}' +``` + +### ๐Ÿ’ก Debugging Tips + +- Use the **"Preview"** tab in the NetBox UI for export and config templates +- Use [API endpoints](https://docs.netbox.dev/en/stable/rest-api/extras/export-templates/) to test templates programmatically +- Log template failures in your automation pipeline using NetBox API error responses +- Use try/catch logic for optional fields + +--- + +## โ“ FAQs & Common Issues + +### Q: Why is my template not rendering expected data? + +**A:** Common causes include: +- Missing configuration context at the appropriate level +- Incorrect variable names or paths +- Data not populated in NetBox (e.g., missing IP addresses) +- Template syntax errors +- Invalid JSON in configuration contexts + +**Solution:** Use the debugging methods above and check data availability in NetBox UI. + +### Q: Can I access related objects like interfaces or IPs? + +**A:** Yes! Use dot notation to traverse relationships: +```jinja2 +{{ device.interfaces.all }} # All interfaces +{{ device.primary_ip4.address }} # Primary IPv4 address +{{ device.site.circuits.all }} # All circuits at the device's site +``` + +### Q: Can I access custom fields? + +**A:** Yes. Custom fields are available via the `custom_fields` attribute: +```jinja2 +{{ device.custom_fields.my_field }} +{{ device.site.custom_fields.region_code }} +``` + +### Q: How do I handle optional fields in templates? + +**A:** Always use the `default` filter or conditional statements: + +```jinja2 +# Using default filter +{{ device.serial | default('Unknown') }} + +# Using conditional +{% if device.serial %} +Serial: {{ device.serial }} +{% else %} +Serial: Not Available +{% endif %} +``` + +### Q: Can I use templates with bulk operations? + +**A:** Yes, NetBox Enterprise supports bulk template rendering through: +- Bulk export functionality +- API batch operations +- Custom scripts for mass configuration generation + +### Q: How do I include external data in templates? + +**A:** Use configuration contexts to inject external data: + +```json +{ + "external_data": { + "dns_servers": ["8.8.8.8", "8.8.4.4"], + "routing": { + "ospf_area": 0, + "bgp_asn": 65001 + } + } +} +``` + +### Q: What's the performance impact of complex templates? + +**A:** Consider these optimization strategies: +- Minimize database queries in templates +- Use select_related() and prefetch_related() in custom views +- Cache frequently accessed data in configuration contexts +- Break large templates into smaller, reusable components + +--- + +## ๐ŸŒ Further Reading & Community Resources + +### Official Documentation +- [NetBox Configuration Contexts](https://docs.netbox.dev/en/stable/models/extras/configcontext/) +- [Configuration Rendering](https://docs.netbox.dev/en/stable/features/configuration-rendering/) +- [Export Templates](https://docs.netbox.dev/en/stable/customization/export-templates/) +- [Jinja2 Template Designer Documentation](https://jinja.palletsprojects.com/en/3.1.x/templates/) +- [Jinja2 Filters in NetBox](https://docs.netbox.dev/en/stable/configuration/system/#jinja2_filters) + +### Community Resources +- **Blog**: [How to Generate Device Configurations with NetBox](https://netboxlabs.com/blog/how-to-generate-device-configurations-with-netbox/) +- **HCD**: [Juniper + NetBox Configuration Generation](https://github.com/jeremyschulman/netbox-hcd-juniper) +- **JPMens**: [Configuration Contexts Deep Dive](https://jpmens.net/2019/10/16/netbox-configuration-contexts/) + +### GitHub Discussions & Community +- [Template Best Practices Discussion #17372](https://github.com/netbox-community/netbox/discussions/17372) +- [Configuration Context Examples #12568](https://github.com/netbox-community/netbox/discussions/12568) +- [Reddit Discussion: Jinja2 + Device Roles](https://www.reddit.com/r/Netbox/comments/13iw8zt/device_roles_models_and_the_usage_of_jinja2/) + +### Community Template Examples +Check the NetBox community repository for additional template examples: +- Cisco IOS/IOS-XE templates +- Juniper JunOS templates +- Arista EOS templates +- Custom export templates + +--- + +*This documentation is part of NetBox Enterprise and provides enterprise-specific guidance for Jinja2 template implementation and best practices.* \ No newline at end of file From 0402fab05ff812546d55eee205acd948b9532bb4 Mon Sep 17 00:00:00 2001 From: Tom Gamull Date: Tue, 3 Jun 2025 10:40:44 -0400 Subject: [PATCH 2/2] Add comprehensive Jinja2 templates documentation for NetBox Enterprise - Complete guide covering templates in configuration rendering, exports, webhooks, and custom fields - Step-by-step Cisco switch configuration example with context definition and validation - Advanced use cases including nested data access, custom fields, and environment segmentation - Testing and debugging section with local testing methods and API validation - Comprehensive FAQ addressing common customer questions and troubleshooting - Community resources and external references for further learning - Addresses Linear ticket PRD-389 and customer requests for consolidated Jinja2 guidance --- docs/netbox-enterprise/nbe-jinja2-templates.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/netbox-enterprise/nbe-jinja2-templates.md b/docs/netbox-enterprise/nbe-jinja2-templates.md index 39bfe087..43aa3261 100644 --- a/docs/netbox-enterprise/nbe-jinja2-templates.md +++ b/docs/netbox-enterprise/nbe-jinja2-templates.md @@ -530,8 +530,6 @@ Serial: Not Available ### Community Resources - **Blog**: [How to Generate Device Configurations with NetBox](https://netboxlabs.com/blog/how-to-generate-device-configurations-with-netbox/) -- **HCD**: [Juniper + NetBox Configuration Generation](https://github.com/jeremyschulman/netbox-hcd-juniper) -- **JPMens**: [Configuration Contexts Deep Dive](https://jpmens.net/2019/10/16/netbox-configuration-contexts/) ### GitHub Discussions & Community - [Template Best Practices Discussion #17372](https://github.com/netbox-community/netbox/discussions/17372)