Thank you for your interest in contributing to NetDriver! We welcome contributions from the community and are grateful for your support.
- Contributing to NetDriver
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the Contributor Covenant, version 1.4.
Before you start contributing, please:
- Read this contribution guide thoroughly
- Check the existing issues to see if your concern is already being addressed
- For major changes, open an issue first to discuss what you would like to change
- Fork the repository and create your branch from
master
- Python 3.12 or higher
- uv 0.9.26 or higher (https://docs.astral.sh/uv/)
- Git
-
Fork and Clone the Repository
git clone https://github.com/YOUR_USERNAME/netdriver.git cd netdriver -
Install Python (using pyenv)
# Install pyenv if not already installed curl -fsSL https://pyenv.run | bash # Install Python 3.12.7 pyenv install 3.12.7 pyenv local 3.12.7
-
Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh -
Install Dependencies
uv sync
-
Verify Installation
# Run tests to ensure everything is working uv run pytest
There are many ways to contribute to NetDriver:
- Report bugs - Help us identify and fix issues
- Suggest features - Share ideas for new functionality
- Write documentation - Improve or expand our docs
- Add device plugins - Extend support for more network devices
- Fix bugs - Submit pull requests for known issues
- Improve code quality - Refactoring, optimization, and code cleanup
- Follow PEP 8 - Python code should adhere to PEP 8 style guidelines
- Use Type Hints - Add type annotations to function signatures
- Write Docstrings - Document modules, classes, and functions using Google-style docstrings
- Keep It Simple - Write clear, readable code; avoid unnecessary complexity
from typing import List, Optional
async def execute_command(
device_ip: str,
command: str,
timeout: int = 30
) -> dict:
"""Execute a command on a network device.
Args:
device_ip: IP address of the target device
command: CLI command to execute
timeout: Command execution timeout in seconds
Returns:
Dictionary containing command output and execution status
Raises:
ExecCmdTimeout: If command execution exceeds timeout
LoginFailed: If authentication fails
"""
# Implementation here
pass- Use clear, descriptive commit messages
- Start with a verb in present tense (e.g., "Add", "Fix", "Update", "Refactor")
- Keep the first line under 72 characters
- Add detailed description in the body if needed
Good examples:
Add Cisco ASA plugin support
Fix session timeout handling in SessionPool
- Properly handle expired sessions
- Add reconnection logic
- Update tests
Update documentation for plugin development
Bad examples:
fixed stuff
update
changes
Use descriptive branch names that reflect the work:
feature/add-cisco-asa-pluginfix/session-timeout-handlingdocs/update-plugin-guiderefactor/improve-error-handling
NetDriver uses a plugin architecture to support different network devices. Here's how to add a new plugin:
Create a new file under components/netdriver/plugins/[vendor]/:
components/netdriver/plugins/cisco/cisco_asa.pyfrom netdriver_agent.plugin.plugin_info import PluginInfo
from netdriver_agent.plugins.cisco import CiscoBase
class CiscoASA(CiscoBase):
"""Cisco ASA Firewall Plugin."""
info = PluginInfo(
vendor="cisco",
model="asa",
version="base",
description="Cisco ASA Firewall Plugin"
)
def get_mode_prompt_patterns(self) -> dict:
"""Define prompt patterns for each mode."""
return {
"LOGIN": r"[\r\n][\w\-\.]+>\s*$",
"ENABLE": r"[\r\n][\w\-\.]+#\s*$",
"CONFIG": r"[\r\n][\w\-\.]+\(config[^\)]*\)#\s*$",
}
def get_more_pattern(self) -> str:
"""Pattern for pagination prompts."""
return r"<--- More --->"
def get_error_patterns(self) -> list:
"""Patterns that indicate command errors."""
return [
r"% Invalid",
r"% Incomplete",
r"% Unknown",
]Create corresponding test file:
tests/bases/netdriver/agent/test_cisco_asa.pyAdd the new plugin to the supported devices list in the README.
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=components --cov=bases
# Run specific test file
uv run pytest tests/bases/netdriver/agent/test_cisco_nexus.py
# Run unit tests only
uv run pytest -m unit
# Run integration tests only
uv run pytest -m integration- Write tests for all new features
- Maintain or improve code coverage
- Use pytest fixtures for common setup
- Test both success and failure cases
- Use meaningful test names
Example test:
import pytest
from httpx import AsyncClient
@pytest.mark.integration
async def test_execute_command_success(client: AsyncClient):
"""Test successful command execution."""
response = await client.post(
"/api/v1/exec",
json={
"ip": "192.168.1.1",
"username": "admin",
"password": "password",
"commands": ["show version"]
}
)
assert response.status_code == 200
assert "output" in response.json()-
Update Your Fork
git checkout master git pull upstream master git checkout -b feature/your-feature-name
-
Make Your Changes
- Write your code
- Add tests
- Update documentation
- Ensure all tests pass
-
Commit Your Changes
git add . git commit -m "Add clear description of your changes"
-
Push to Your Fork
git push origin feature/your-feature-name
-
Create Pull Request
- Go to the NetDriver repository
- Click "New Pull Request"
- Select your fork and branch
- Fill in the PR template with:
- Description of changes
- Related issue numbers
- Testing performed
- Screenshots (if applicable)
-
PR Review Requirements
- All tests must pass
- Code coverage should not decrease
- At least one maintainer approval required
- Address all review comments
- Resolve merge conflicts if any
-
After Approval
- A maintainer will merge your PR
- Delete your feature branch
- Pull the latest changes to your fork
When reporting bugs, please include:
- Description - Clear description of the issue
- Steps to Reproduce - Detailed steps to reproduce the bug
- Expected Behavior - What you expected to happen
- Actual Behavior - What actually happened
- Environment:
- NetDriver version
- Python version
- Operating system
- Device type/model (if relevant)
- Logs - Relevant log output or error messages
- Screenshots - If applicable
Use this template:
## Bug Description
Brief description of the bug
## Steps to Reproduce
1. Step one
2. Step two
3. ...
## Expected Behavior
What should happen
## Actual Behavior
What actually happens
## Environment
- NetDriver version: 0.3.10
- Python version: 3.12.7
- OS: Ubuntu 22.04
- Device: Cisco Nexus 9000
## Logs
```text
Paste relevant logs here[Attach screenshots if applicable]
We welcome feature requests! Please:
- Check existing issues - Your idea might already be proposed
- Be specific - Clearly describe the feature and use case
- Explain the value - Why would this benefit users?
- Consider implementation - Any thoughts on how it could work?
Template:
## Feature Description
Clear description of the proposed feature
## Use Case
Why is this feature needed? What problem does it solve?
## Proposed Implementation
Any ideas on how this could be implemented?
## Alternatives Considered
What other approaches have you considered?
## Additional Context
Any other relevant informationUnderstanding the project structure will help you contribute effectively:
netdriver/
├── bases/netdriver/ # Applications
│ ├── agent/ # REST API service
│ └── simunet/ # SSH simulation service
├── components/netdriver/ # Shared libraries
│ ├── client/ # SSH client and session management
│ ├── exception/ # Error handling
│ ├── log/ # Logging utilities
│ ├── plugin/ # Plugin system core
│ ├── plugins/ # Device-specific plugins
│ │ ├── cisco/ # Cisco devices
│ │ ├── huawei/ # Huawei devices
│ │ ├── juniper/ # Juniper devices
│ │ └── ...
│ ├── server/ # SSH server for simulated devices
│ ├── textfsm/ # Output parsing
│ └── utils/ # Utility functions
├── config/ # Configuration files
├── tests/ # Test suites
└── docs/ # Documentation
- Open an issue for questions
- Check existing documentation
- Contact the maintainers:
We value all contributions! Contributors will be:
- Listed in our contributors list
- Mentioned in release notes for significant contributions
- Part of a growing community of network automation enthusiasts
Thank you for contributing to NetDriver!