Skip to content

Commit

Permalink
Merge pull request #101 from DanSheps/develop
Browse files Browse the repository at this point in the history
Upgrade model to PrimaryModel, add GraphQL support, add new config_status variable to check if IOS devices are saved, refine build process
  • Loading branch information
DanSheps authored Sep 13, 2024
2 parents 89e8027 + 2b6b77c commit 0d6e200
Show file tree
Hide file tree
Showing 32 changed files with 671 additions and 120 deletions.
16 changes: 15 additions & 1 deletion .github/configuration.testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,23 @@
}

PLUGINS = [
'netbox_secretstore',
'netbox_napalm_plugin',
'netbox_config_backup',
]

PLUGINS_CONFIG = {
'netbox_config_backup': {
'repository': '/tmp/repository/',
'committer': 'Test Committer <[email protected]>',
'author': 'Test Committer <[email protected]>',
'frequency': 3600,
},
'netbox_napalm_plugin': {
'NAPALM_USERNAME': 'xxx',
'NAPALM_PASSWORD': 'yyy',
}
}

REDIS = {
'tasks': {
'HOST': 'localhost',
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Build Test
on: [push, pull_request]
jobs:
pypi-publish:
name: Test Build Process
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
strategy:
matrix:
python-version: [3.12]
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade setuptools wheel
- name: Install pypa/build
run: python3 -m pip install build --user
- name: Build
run: python -m build
12 changes: 9 additions & 3 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
NETBOX_CONFIGURATION: netbox.configuration_testing
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.10', '3.11', '3.12']
services:
redis:
image: redis
Expand Down Expand Up @@ -51,9 +51,15 @@ jobs:
- name: Install dependencies & set up configuration
run: |
python -m pip install --upgrade pip
pip install -r netbox\requirements.txt
pip install -r netbox/requirements.txt
pip install pycodestyle coverage tblib
pip install -e netbox-config-backup
cp -f netbox-config-backup/.github/configuration.testing.py netbox/netbox/netbox/configuration_testing.py
mkdir /tmp/repository
git init /tmp/repository
- name: Run tests
run: coverage run --source="netbox-config-backup/" netbox/manage.py test netbox-config-backup/ --parallel
run: coverage run --source="netbox-config-backup/netbox_config_backup" netbox/netbox/manage.py test netbox-config-backup/netbox_config_backup --parallel

- name: Show coverage report
run: coverage report --skip-covered --omit '*/migrations/*,*/tests/*'
4 changes: 2 additions & 2 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
id-token: write
strategy:
matrix:
python-version: [3.9]
python-version: [3.12]
steps:
- name: Checkout repo
uses: actions/checkout@v2
Expand All @@ -24,7 +24,7 @@ jobs:
python -m pip install --upgrade pip
pip install --upgrade setuptools wheel
- name: Build
run: python setup.py sdist bdist_wheel
run: python -m build
#- name: Publish package to TestPyPI
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
Expand Down
1 change: 1 addition & 0 deletions netbox_config_backup/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class NetboxConfigBackup(PluginConfig):
queues = [
'jobs'
]
graphql_schema = 'graphql.schema.schema'


config = NetboxConfigBackup
12 changes: 8 additions & 4 deletions netbox_config_backup/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@


class BackupSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_config_backup-api:backup-detail')
device = DeviceSerializer(nested=True)
ip = IPAddressSerializer(nested=True)
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_config_backup-api:backup-detail'
)
device = DeviceSerializer(nested=True, required=False, allow_null=True),
ip = IPAddressSerializer(nested=True, required=False, allow_null=True)

class Meta:
model = Backup
fields = [
'id', 'url', 'display', 'device', 'ip', 'name', 'uuid', 'status'
'id', 'url', 'display', 'name', 'device', 'ip',
'uuid', 'status', 'config_status',
]
brief_fields = ('display', 'id', 'name', 'url')
4 changes: 2 additions & 2 deletions netbox_config_backup/api/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from rest_framework.viewsets import ModelViewSet

from netbox.api.viewsets import NetBoxModelViewSet
from netbox_config_backup.api import BackupSerializer
from netbox_config_backup.models import Backup


class BackupViewSet(ModelViewSet):
class BackupViewSet(NetBoxModelViewSet):
queryset = Backup.objects.all()
serializer_class = BackupSerializer
12 changes: 8 additions & 4 deletions netbox_config_backup/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,14 @@ def search(self, queryset, name, value):

def filter_address(self, queryset, name, value):
try:
return queryset.filter(ip__address__net_host_contained=value)
except ValidationError:
if type(value) is list:
query = Q()
for val in value:
query |= Q(ip__address__net_host_contained=val)
return queryset.filter(query)
else:
return queryset.filter(ip__address__net_host_contained=value)
except ValidationError as e:
return queryset.none()


Expand All @@ -83,10 +89,8 @@ class Meta:
fields = ['id', 'file']

def search(self, queryset, name, value):
print('Search')
if not value.strip():
return queryset
print(value)
qs_filter = (
Q(file__type=value) |
Q(file__type__startswith=value)
Expand Down
26 changes: 22 additions & 4 deletions netbox_config_backup/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@
from dcim.choices import DeviceStatusChoices
from dcim.models import Device
from ipam.models import IPAddress
from netbox.forms import NetBoxModelForm, NetBoxModelBulkEditForm
from netbox_config_backup.models import Backup
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, CommentField

__all__ = (
'BackupForm',
'BackupFilterSetForm',
'BackupBulkEditForm',
)

from utilities.forms.rendering import FieldSet

class BackupForm(forms.ModelForm):

class BackupForm(NetBoxModelForm):
device = DynamicModelChoiceField(
label='Device',
required=False,
Expand All @@ -36,9 +40,11 @@ class BackupForm(forms.ModelForm):
'assigned_to_interface': True
},
)
comments = CommentField()

class Meta:
model = Backup
fields = ('name', 'device', 'ip', 'status')
fields = ('name', 'device', 'ip', 'status', 'description', 'comments', 'config_status')

def clean(self):
super().clean()
Expand Down Expand Up @@ -71,7 +77,7 @@ class BackupFilterSetForm(forms.Form):
'status': [DeviceStatusChoices.STATUS_ACTIVE],
'platform__napalm__ne': None,
'has_primary_ip': True,
}
},
)
ip = forms.CharField(
required=False,
Expand All @@ -84,3 +90,15 @@ class BackupFilterSetForm(forms.Form):
)


class BackupBulkEditForm(NetBoxModelBulkEditForm):

description = forms.CharField(
label=_('Description'),
max_length=200,
required=False
)
comments = CommentField()

model = Backup
fieldsets = ()
nullable_fields = ()
Empty file.
14 changes: 14 additions & 0 deletions netbox_config_backup/graphql/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import strawberry_django
from netbox_config_backup import filtersets, models

from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin

__all__ = (
'BackupFilter',
)


@strawberry_django.filter(models.Backup, lookups=True)
@autotype_decorator(filtersets.BackupFilterSet)
class BackupFilter(BaseFilterMixin):
pass
17 changes: 17 additions & 0 deletions netbox_config_backup/graphql/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import List

import strawberry
import strawberry_django

from .types import *


@strawberry.type(name="Query")
class BackupQuery:
backup: BackupType = strawberry_django.field()
backup_list: List[BackupType] = strawberry_django.field()


schema = [
BackupQuery,
]
25 changes: 25 additions & 0 deletions netbox_config_backup/graphql/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Annotated

import strawberry
import strawberry_django

from netbox.graphql.types import NetBoxObjectType
from .filters import *

from netbox_config_backup import models

__all__ = (
'BackupType',
)


@strawberry_django.type(
models.Backup,
fields='__all__',
filters=BackupFilter
)
class BackupType(NetBoxObjectType):

name: str
device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
ip: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
18 changes: 15 additions & 3 deletions netbox_config_backup/management/commands/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@ def test(i):
time.sleep(10)
self.stdout.write(f"Child {i} sleep complete")

processes = []
for i in range(1, 2):
processes = {}
for i in range(1, 3):
p = Process(target=test, args=(i,))
p.start()
p.join(1)
self.stdout.write(f"Child {i} running")
processes.append(p)
processes.update({p.pid: p})

while True:
if len(processes) == 0:
break
for pid in list(processes.keys()):
process = processes.get(pid, None)
if not process.is_alive():
del processes[pid]
time.sleep(1)




18 changes: 18 additions & 0 deletions netbox_config_backup/migrations/0014_backup_config_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.8 on 2024-09-06 02:24

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('netbox_config_backup', '0013_backup__to_netboxmodel'),
]

operations = [
migrations.AddField(
model_name='backup',
name='config_status',
field=models.BooleanField(blank=True, null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.0.8 on 2024-09-12 13:35

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('netbox_config_backup', '0014_backup_config_status'),
]

operations = [
migrations.AddField(
model_name='backup',
name='comments',
field=models.TextField(blank=True),
),
migrations.AddField(
model_name='backup',
name='description',
field=models.CharField(blank=True, max_length=200),
),
]
1 change: 1 addition & 0 deletions netbox_config_backup/models/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@

class BigIDModel(models.Model):
id = models.BigAutoField(primary_key=True)

class Meta:
abstract = True
Loading

0 comments on commit 0d6e200

Please sign in to comment.