diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index d73bf44..ad36185 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -10,10 +10,10 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: 3.14 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30b7eda..7b83bfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: NETBOX_CONFIGURATION: netbox.configuration_lifecycle strategy: matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ['3.12', '3.13', '3.14'] services: redis: image: redis diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index a975d6a..f93eae1 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: 3.14 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/contrib/configuration_lifecycle.py b/contrib/configuration_lifecycle.py index fb0283f..4aab2f0 100644 --- a/contrib/configuration_lifecycle.py +++ b/contrib/configuration_lifecycle.py @@ -39,6 +39,10 @@ SECRET_KEY = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' +API_TOKEN_PEPPERS = { + 1: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', +} + DEFAULT_PERMISSIONS = {} LOGGING = { diff --git a/netbox_lifecycle/__init__.py b/netbox_lifecycle/__init__.py index 851ecca..643273b 100644 --- a/netbox_lifecycle/__init__.py +++ b/netbox_lifecycle/__init__.py @@ -13,7 +13,7 @@ class NetBoxLifeCycle(PluginConfig): author = metadata.get('Author') author_email = metadata.get('Author-email') base_url = 'lifecycle' - min_version = '4.3.0' + min_version = '4.5.0' required_settings = [] default_settings = { 'lifecycle_card_position': 'right_page', diff --git a/netbox_lifecycle/graphql/filters.py b/netbox_lifecycle/graphql/filters.py index b0759a0..10696c9 100644 --- a/netbox_lifecycle/graphql/filters.py +++ b/netbox_lifecycle/graphql/filters.py @@ -3,7 +3,7 @@ import strawberry import strawberry_django -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin +from netbox.graphql.filters import PrimaryModelFilter from netbox_lifecycle import models @@ -19,12 +19,12 @@ @strawberry_django.filter(models.Vendor, lookups=True) -class VendorFilter(BaseObjectTypeFilterMixin): +class VendorFilter(PrimaryModelFilter): pass @strawberry_django.filter(models.SupportSKU, lookups=True) -class SupportSKUFilter(BaseObjectTypeFilterMixin): +class SupportSKUFilter(PrimaryModelFilter): manufacturer: ( Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None ) = strawberry_django.filter_field() @@ -32,7 +32,7 @@ class SupportSKUFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter(models.SupportContract, lookups=True) -class SupportContractFilter(BaseObjectTypeFilterMixin): +class SupportContractFilter(PrimaryModelFilter): vendor: ( Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None ) = strawberry_django.filter_field() @@ -40,7 +40,7 @@ class SupportContractFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter(models.SupportContractAssignment, lookups=True) -class SupportContractAssignmentFilter(BaseObjectTypeFilterMixin): +class SupportContractAssignmentFilter(PrimaryModelFilter): contract: ( Annotated[ 'SupportContractFilter', strawberry.lazy('netbox_lifecycle.graphql.filters') @@ -74,7 +74,7 @@ class SupportContractAssignmentFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter(models.License, lookups=True) -class LicenseFilter(BaseObjectTypeFilterMixin): +class LicenseFilter(PrimaryModelFilter): manufacturer: ( Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None ) = strawberry_django.filter_field() @@ -82,7 +82,7 @@ class LicenseFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter(models.LicenseAssignment, lookups=True) -class LicenseAssignmentFilter(BaseObjectTypeFilterMixin): +class LicenseAssignmentFilter(PrimaryModelFilter): vendor: ( Annotated['VendorFilter', strawberry.lazy('netbox_lifecycle.graphql.filters')] | None @@ -107,7 +107,7 @@ class LicenseAssignmentFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter(models.HardwareLifecycle, lookups=True) -class HardwareLifecycleFilter(BaseObjectTypeFilterMixin): +class HardwareLifecycleFilter(PrimaryModelFilter): device_type: ( Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None ) = strawberry_django.filter_field() diff --git a/netbox_lifecycle/graphql/types.py b/netbox_lifecycle/graphql/types.py index 93b83ce..e12c6a5 100644 --- a/netbox_lifecycle/graphql/types.py +++ b/netbox_lifecycle/graphql/types.py @@ -11,7 +11,7 @@ ModuleType, ) from virtualization.graphql.types import VirtualMachineType -from netbox.graphql.types import NetBoxObjectType +from netbox.graphql.types import PrimaryObjectType from .filters import * from netbox_lifecycle import models @@ -28,12 +28,12 @@ @strawberry_django.type(models.Vendor, fields='__all__', filters=VendorFilter) -class VendorType(NetBoxObjectType): +class VendorType(PrimaryObjectType): name: str @strawberry_django.type(models.SupportSKU, fields='__all__', filters=SupportSKUFilter) -class SupportSKUType(NetBoxObjectType): +class SupportSKUType(PrimaryObjectType): sku: str manufacturer: ManufacturerType @@ -42,7 +42,7 @@ class SupportSKUType(NetBoxObjectType): @strawberry_django.type( models.SupportContract, fields='__all__', filters=SupportContractFilter ) -class SupportContractType(NetBoxObjectType): +class SupportContractType(PrimaryObjectType): vendor: VendorType contract_id: str @@ -52,7 +52,7 @@ class SupportContractType(NetBoxObjectType): @strawberry_django.type(models.License, fields='__all__', filters=LicenseFilter) -class LicenseType(NetBoxObjectType): +class LicenseType(PrimaryObjectType): manufacturer: ManufacturerType name: str @@ -63,7 +63,7 @@ class LicenseType(NetBoxObjectType): fields='__all__', filters=SupportContractAssignmentFilter, ) -class SupportContractAssignmentType(NetBoxObjectType): +class SupportContractAssignmentType(PrimaryObjectType): contract: SupportContractType sku: SupportSKUType | None device: DeviceType | None @@ -76,7 +76,7 @@ class SupportContractAssignmentType(NetBoxObjectType): @strawberry_django.type( models.LicenseAssignment, fields='__all__', filters=LicenseAssignmentFilter ) -class LicenseAssignmentType(NetBoxObjectType): +class LicenseAssignmentType(PrimaryObjectType): license: LicenseType vendor: VendorType device: DeviceType | None @@ -87,7 +87,7 @@ class LicenseAssignmentType(NetBoxObjectType): @strawberry_django.type( models.HardwareLifecycle, fields='__all__', filters=HardwareLifecycleFilter ) -class HardwareLifecycleType(NetBoxObjectType): +class HardwareLifecycleType(PrimaryObjectType): assigned_object_type: ( Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None ) diff --git a/netbox_lifecycle/migrations/0018_netbox_v040500.py b/netbox_lifecycle/migrations/0018_netbox_v040500.py new file mode 100644 index 0000000..90bc8e1 --- /dev/null +++ b/netbox_lifecycle/migrations/0018_netbox_v040500.py @@ -0,0 +1,85 @@ +# Generated by Django 5.2.5 on 2026-01-07 04:52 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("netbox_lifecycle", "0017_optional_lifecycle_dates"), + ("users", "0015_owner"), + ] + + operations = [ + migrations.AddField( + model_name="hardwarelifecycle", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="license", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="licenseassignment", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="supportcontract", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="supportcontractassignment", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="supportsku", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + migrations.AddField( + model_name="vendor", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.owner", + ), + ), + ] diff --git a/pyproject.toml b/pyproject.toml index d0a622b..97968d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,9 +15,9 @@ maintainers = [ ] description = "NetBox Support Contract and EOL/EOS management" readme = "README.md" -requires-python = ">=3.10" +requires-python = ">=3.12" keywords = ["netbox-plugin", ] -version = "1.1.6" +version = "1.1.7" license = {file = "LICENSE"} classifiers = [ "Programming Language :: Python :: 3", diff --git a/ruff.toml b/ruff.toml index 7bc1215..8dd46a4 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,7 @@ -exclude = [] +exclude = [ + '.github', + 'contrib', +] line-length = 120 target-version = "py310" output-format = "github"