netbox-maintenance 0.1.0b1
NetBox plugin for managing maintenance windows and scheduled maintenance activities.
License: Apache-2.0
Requires Python: >=3.10

# NetBox Maintenance Plugin

A NetBox plugin for managing maintenance windows and tracking their impact on network infrastructure.

[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)

## Overview

The NetBox Maintenance Plugin extends NetBox's capabilities by providing comprehensive maintenance management with:
- Maintenance window scheduling with start and end times
- Impact tracking for any NetBox object type
- Customizable maintenance and impact status types
- Direct maintenance management from object detail pages
- Bulk impact assignment and updates
- Advanced filtering and search capabilities
- Full REST API support

## Compatibility Matrix

| NetBox Version | Plugin Version |
|----------------|----------------|
|     4.4.x      |      0.1.0     |

## Features

### Core Models

**Maintenance Types** - Define custom maintenance status types:
- Customizable names (e.g., TENTATIVE, CONFIRMED, IN-PROCESS, COMPLETED, CANCELLED)
- Color-coded status indicators
- Description fields for clarity

**Maintenance Impact Types** - Define custom impact levels:
- Customizable impact types (e.g., NO-IMPACT, REDUCED-REDUNDANCY, OUTAGE)
- Color-coded impact indicators
- Description fields for clarity

**Maintenance** - Schedule and track maintenance windows:
- Unique maintenance name/ID and summary
- Start and end date/time tracking
- Status tracking using customizable types
- Internal ticket reference field
- Acknowledgment flag
- Comments and tags support
- Automatic validation (end time must be after start time)

**Maintenance Impact** - Link maintenances to affected objects:
- Associate any configured NetBox object with maintenance windows
- Track impact level per object
- Support for multiple objects per maintenance
- Unique constraint prevents duplicate object assignments

### User Interface Features

**Dynamic Maintenance Tabs** - Automatically added to all configured object types:
- "Maintenances" tab appears on device, interface, circuit, and other object detail pages
- Badge showing count of associated maintenance impacts
- Quick access to add maintenance impacts directly from object pages
- Filtered view showing only maintenances affecting that object

**Advanced Form Workflows**:
- **Tabbed Multi-Object Selection** - Add form uses tabs for each object type with multi-select fields
- **Parent-Child Filtering** - Interfaces filtered by device, VM interfaces by VM, etc.
- **Bulk Update Interface** - Manage all impacts for a maintenance with visual indicators for existing assignments
- **Pre-selection Support** - Objects pre-selected when adding from detail pages
- **Return URL Handling** - Seamless navigation back to originating pages

**Enhanced User Experience**:
- Bold highlighting of pre-existing object assignments
- Parent object display in parentheses for child objects (e.g., "eth0 (device-1)")
- Impact type distribution summary in bulk edit
- Quick access buttons in tables for rapid maintenance management

### REST API

Full REST API support with CRUD operations for:
- `/api/plugins/netbox-maintenance/maintenance-types/` - Maintenance type management
- `/api/plugins/netbox-maintenance/maintenance-impact-types/` - Impact type management
- `/api/plugins/netbox-maintenance/maintenances/` - Maintenance window management
- `/api/plugins/netbox-maintenance/maintenance-impacts/` - Impact tracking

Features:
- Nested serializers for related objects
- Content type filtering support
- Advanced filtering by object type and ID
- Standard NetBox API authentication and permissions

### Search and Filtering

**Global Search** - Maintenance windows searchable by:
- Name/ID
- Summary
- Internal ticket number
- Comments

**Advanced Filters**:
- Filter maintenances by status, date range, acknowledgment
- Filter by affected object (object_type_id and object_id)
- Filter impacts by maintenance, impact type, or object type
- Date range filtering with from/to support

## Installation

### Prerequisites

- NetBox 4.4.x
- Python 3.10, 3.11, or 3.12

### Installation Steps

1. Install the plugin using pip:

```bash
pip install netbox-maintenance
```

2. Enable the plugin in your NetBox `configuration.py`:

```python
PLUGINS = [
    'netbox_maintenance',
]

PLUGINS_CONFIG = {
    'netbox_maintenance': {
        # Define which object types can be associated with maintenance impacts
        'scope_filter': [
            'dcim.device',
            'dcim.interface',
            'dcim.module',
            'dcim.site',
            'dcim.rack',
            'dcim.location',
            'circuits.circuit',
            'circuits.provider',
            'ipam.ipaddress',
            'ipam.prefix',
            'ipam.vlan',
            'tenancy.tenant',
            'virtualization.virtualmachine',
            'virtualization.vminterface',
            'wireless.wirelesslan',
            'wireless.wirelesslink',
            # Add custom plugin models:
            # 'your_plugin.yourmodel',
        ],
        
        # Optional: Define parent-child relationships for dependent field filtering
        'parent_child_relationships': {
            'dcim.interface': ('dcim.device', 'device_id', 'device'),
            'dcim.module': ('dcim.device', 'device_id', 'device'),
            'virtualization.vminterface': ('virtualization.virtualmachine', 'virtual_machine_id', 'virtual_machine'),
            'dcim.location': ('dcim.site', 'site_id', 'site'),
        },
    }
}
```

3. Run database migrations:

```bash
python manage.py migrate netbox_maintenance
```

4. Restart NetBox services:

```bash
sudo systemctl restart netbox netbox-rq
```

## Configuration

### Configuration Options

#### `scope_filter` (required)
List of model references that can be associated with maintenance impacts.

- **Format**: `'app_label.model_name'` (lowercase)
- **Default**: Includes common DCIM, circuits, IPAM, tenancy, virtualization, and wireless models
- **Examples**: 
  - `'dcim.device'` - Devices
  - `'circuits.circuit'` - Circuits  
  - `'ipam.ipaddress'` - IP Addresses
  - `'your_plugin.segment'` - Custom plugin models
- **Notes**: 
  - Models listed here will have a "Maintenances" tab added to their detail pages
  - Each model type appears as a tab in the maintenance impact add/edit forms
  - If not specified or empty, no object types will be available for selection

#### `parent_child_relationships` (optional)
Defines parent-child relationships for dependent field filtering in forms.

- **Format**: `{'child_model': ('parent_model', 'query_param', 'parent_attr')}`
- **Purpose**: Enables filtering child objects by parent (e.g., interfaces by device)
- **Parameters**:
  - `child_model` - The child model path (e.g., `'dcim.interface'`)
  - `parent_model` - The parent model path (e.g., `'dcim.device'`)
  - `query_param` - The API query parameter name for filtering (e.g., `'device_id'`)
  - `parent_attr` - The attribute on child model referencing parent (e.g., `'device'`)
- **Default relationships**:
  ```python
  {
      'dcim.interface': ('dcim.device', 'device_id', 'device'),
      'dcim.module': ('dcim.device', 'device_id', 'device'),
      'virtualization.vminterface': ('virtualization.virtualmachine', 'virtual_machine_id', 'virtual_machine'),
      'dcim.location': ('dcim.site', 'site_id', 'site'),
  }
  ```
- **Benefits**:
  - Improves form usability with cascading dropdowns
  - Displays parent information alongside child objects
  - Helps users locate objects more easily in large lists

### Initial Setup

After installation, you should create some default maintenance types and impact types:

1. Navigate to **Plugins → Maintenance → Configuration → Maintenance Types**
2. Add common maintenance types like:
   - TENTATIVE (e.g., color: FFA500)
   - CONFIRMED (e.g., color: 2196F3)
   - IN-PROCESS (e.g., color: FF9800)
   - COMPLETED (e.g., color: 4CAF50)
   - CANCELLED (e.g., color: 9E9E9E)

3. Navigate to **Plugins → Maintenance → Configuration → Impact Types**
4. Add common impact types like:
   - NO-IMPACT (e.g., color: 4CAF50)
   - REDUCED-REDUNDANCY (e.g., color: FF9800)
   - DEGRADED-SERVICE (e.g., color: FFC107)
   - OUTAGE (e.g., color: F44336)

## Usage

### Creating a Maintenance Window

1. Navigate to **Plugins → Maintenance → Maintenances**
2. Click **+ Add** to create a new maintenance
3. Fill in the required fields:
   - **Name**: Unique maintenance ID or ticket number
   - **Summary**: Brief description of the maintenance
   - **Status**: Select from configured maintenance types
   - **Start/End**: Date and time range for the maintenance
   - **Internal Ticket**: (Optional) Reference to internal ticketing system
   - **Acknowledged**: Flag to track acknowledgment
4. Click **Create** to save

### Assigning Impacts to Objects

**Method 1: From Maintenance Detail Page**
1. Open a maintenance window detail page
2. Click the **Impacts** tab
3. Click **BulkUpdate Assigned Objects**
4. Select objects from the tabbed interface (one tab per object type)
5. Choose an impact type
6. Click **Save**

**Method 2: From Object Detail Page**
1. Navigate to any device, interface, circuit, etc.
2. Click the **Maintenances** tab
3. Click **+ Add Maintenance Impact**
4. The current object will be pre-selected
5. Choose a maintenance and impact type
6. Click **Create**

**Method 3: From Maintenance Table**
1. In the maintenances list, click the **pencil-box-multiple** icon in the Actions column
2. This opens the bulk update interface for that maintenance
3. Add or remove objects and update impact types
4. Existing assignments are shown in **bold**

### Viewing Maintenances for an Object

1. Navigate to any configured object (device, circuit, etc.)
2. Click the **Maintenances** tab
3. View all maintenance windows affecting this object
4. The tab badge shows the count of associated impacts
5. Filter or search within the list as needed

### Filtering Maintenances

Use the filter panel to find maintenances by:
- **Name, Summary, or Ticket**: Text search
- **Status**: One or more maintenance types
- **Acknowledged**: Yes/No/Any
- **Start/End Date**: Date range filters
- **Affected Object**: Filter by object type and ID (useful from object tabs)

### Using the REST API

**List all maintenances:**
```bash
curl -X GET http://netbox/api/plugins/netbox-maintenance/maintenances/ \
  -H "Authorization: Token YOUR_TOKEN"
```

**Filter maintenances by affected object:**
```bash
curl -X GET "http://netbox/api/plugins/netbox-maintenance/maintenances/?object_type_id=23&object_id=456" \
  -H "Authorization: Token YOUR_TOKEN"
```

**Create a maintenance:**
```bash
curl -X POST http://netbox/api/plugins/netbox-maintenance/maintenances/ \
  -H "Authorization: Token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MAINT-2025-001",
    "summary": "Network upgrade",
    "status": 1,
    "start": "2025-12-01T10:00:00Z",
    "end": "2025-12-01T14:00:00Z"
  }'
```

**Create a maintenance impact:**
```bash
curl -X POST http://netbox/api/plugins/netbox-maintenance/maintenance-impacts/ \
  -H "Authorization: Token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "maintenance": 1,
    "object_type": 23,
    "object_id": 456,
    "impact": 2
  }'
```

## Development

### Setting Up Development Environment

```bash
# Clone the repository
git clone https://github.com/yourusername/netbox-maintenance.git
cd netbox-maintenance

# Install in development mode
pip install -e .

# Install development dependencies
pip install -e ".[dev]"
```

### Running Tests

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=netbox_maintenance

# Run specific test file
pytest tests/test_models.py
```

### Code Quality

```bash
# Format code
make format

# Run linters
make lint

# Run pre-commit hooks
make pre-commit
```

## Troubleshooting

### Maintenance tab not appearing on objects

1. Verify the model is listed in `scope_filter` configuration
2. Ensure you've restarted NetBox services after configuration changes
3. Check NetBox logs for any plugin loading errors

### Parent-child filtering not working

1. Verify the relationship is defined in `parent_child_relationships`
2. Ensure the query parameter name matches the API filter parameter
3. Check that the parent attribute name exists on the child model

### Objects not showing in forms

1. Confirm the model is in `scope_filter`
2. Verify you have appropriate permissions for the object type
3. Check that objects exist and are not filtered out by other constraints

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Run tests and ensure they pass
5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- Inspired by the BCOP maintenance notification standard
- Built for the NetBox community