9856 extras and mixins

This commit is contained in:
Arthur 2023-08-25 13:31:10 -07:00
parent 700f015942
commit 46b0df43f9
4 changed files with 264 additions and 86 deletions

View File

@ -0,0 +1,149 @@
import strawberry
from strawberry import auto
from extras import models, filtersets
__all__ = (
'ConfigContextFilter',
'ConfigTemplateFilter',
'CustomFieldFilter',
'CustomFieldChoiceSetFilter',
'CustomLinkFilter',
'ExportTemplateFilter',
'ImageAttachmentFilter',
'JournalEntryFilter',
'ObjectChangeFilter',
'SavedFilterFilter',
'TagFilter',
'WebhookFilter',
)
@strawberry.django.filter(models.ConfigContext, lookups=True)
class ConfigContextFilter(filtersets.ConfigContextFilterSet):
id: auto
name: auto
is_active: auto
data_synced: auto
@strawberry.django.filter(models.ConfigTemplate, lookups=True)
class ConfigTemplateFilter(filtersets.ConfigTemplateFilterSet):
id: auto
name: auto
description: auto
data_synced: auto
@strawberry.django.filter(models.CustomField, lookups=True)
class CustomFieldFilter(filtersets.CustomFieldFilterSet):
id: auto
content_types: auto
name: auto
group_name: auto
required: auto
search_weight: auto
filter_logic: auto
ui_visibility: auto
weight: auto
is_cloneable: auto
description: auto
@strawberry.django.filter(models.CustomFieldChoiceSet, lookups=True)
class CustomFieldChoiceSetFilter(filtersets.CustomFieldChoiceSetFilterSet):
id: auto
name: auto
description: auto
base_choices: auto
order_alphabetically: auto
@strawberry.django.filter(models.CustomLink, lookups=True)
class CustomLinkFilter(filtersets.CustomLinkFilterSet):
id: auto
content_types: auto
name: auto
enabled: auto
link_text: auto
link_url: auto
weight: auto
group_name: auto
new_window: auto
@strawberry.django.filter(models.ExportTemplate, lookups=True)
class ExportTemplateFilter(filtersets.ExportTemplateFilterSet):
id: auto
content_types: auto
name: auto
description: auto
data_synced: auto
@strawberry.django.filter(models.ImageAttachment, lookups=True)
class ImageAttachmentFilter(filtersets.ImageAttachmentFilterSet):
id: auto
content_type_id: auto
object_id: auto
name: auto
@strawberry.django.filter(models.JournalEntry, lookups=True)
class JournalEntryFilter(filtersets.JournalEntryFilterSet):
id: auto
assigned_object_type_id: auto
assigned_object_id: auto
created: auto
kind: auto
@strawberry.django.filter(models.ObjectChange, lookups=True)
class ObjectChangeFilter(filtersets.ObjectChangeFilterSet):
id: auto
user: auto
user_name: auto
request_id: auto
action: auto
changed_object_type_id: auto
changed_object_id: auto
object_repr: auto
@strawberry.django.filter(models.SavedFilter, lookups=True)
class SavedFilterFilter(filtersets.SavedFilterFilterSet):
id: auto
content_types: auto
name: auto
slug: auto
description: auto
enabled: auto
shared: auto
weight: auto
@strawberry.django.filter(models.Tag, lookups=True)
class TagFilter(filtersets.TagFilterSet):
id: auto
name: auto
slug: auto
# color: auto
description: auto
object_types: auto
@strawberry.django.filter(models.Webhook, lookups=True)
class WebhookFilter(filtersets.WebhookFilterSet):
id: auto
name: auto
type_create: auto
type_update: auto
type_delete: auto
type_job_start: auto
type_job_end: auto
payload_url: auto
enabled: auto
http_method: auto
http_content_type: auto
secret: auto
ssl_verification: auto
ca_file_path: auto

View File

@ -1,7 +1,7 @@
import strawberry
import graphene
from typing import TYPE_CHECKING, Annotated, List
from django.contrib.contenttypes.models import ContentType
from graphene.types.generic import GenericScalar
from extras.models import ObjectChange
@ -14,11 +14,16 @@ __all__ = (
'TagsMixin',
)
if TYPE_CHECKING:
from .types import ImageAttachmentType, JournalEntryType, ObjectChangeType, TagType
from tenancy.graphql.types import ContactAssignmentType
@strawberry.type
class ChangelogMixin:
changelog = graphene.List('extras.graphql.types.ObjectChangeType')
def resolve_changelog(self, info):
@strawberry.django.field
def changelog(self) -> List[Annotated["ObjectChangeType", strawberry.lazy('.types')]]:
content_type = ContentType.objects.get_for_model(self)
object_changes = ObjectChange.objects.filter(
changed_object_type=content_type,
@ -27,43 +32,49 @@ class ChangelogMixin:
return object_changes.restrict(info.context.user, 'view')
@strawberry.type
class ConfigContextMixin:
config_context = GenericScalar()
def resolve_config_context(self, info):
@strawberry.django.field
def config_context(self) -> strawberry.scalars.JSON:
return self.get_config_context()
@strawberry.type
class CustomFieldsMixin:
custom_fields = GenericScalar()
def resolve_custom_fields(self, info):
@strawberry.django.field
def custom_fields(self) -> strawberry.scalars.JSON:
return self.custom_field_data
@strawberry.type
class ImageAttachmentsMixin:
image_attachments = graphene.List('extras.graphql.types.ImageAttachmentType')
def resolve_image_attachments(self, info):
@strawberry.django.field
def image_attachments(self) -> List[Annotated["ImageAttachmentType", strawberry.lazy('.types')]]:
return self.images.restrict(info.context.user, 'view')
@strawberry.type
class JournalEntriesMixin:
journal_entries = graphene.List('extras.graphql.types.JournalEntryType')
def resolve_journal_entries(self, info):
@strawberry.django.field
def journal_entries(self) -> List[Annotated["JournalEntryType", strawberry.lazy('.types')]]:
return self.journal_entries.restrict(info.context.user, 'view')
@strawberry.type
class TagsMixin:
tags = graphene.List('extras.graphql.types.TagType')
def resolve_tags(self, info):
@strawberry.django.field
def tags(self) -> List[Annotated["TagType", strawberry.lazy('.types')]]:
return self.tags.all()
@strawberry.type
class ContactsMixin:
contacts = graphene.List('tenancy.graphql.types.ContactAssignmentType')
def resolve_contacts(self, info):
@strawberry.django.field
def contacts(self) -> List[Annotated["ContactAssignmentType", strawberry.lazy('tenancy.graphql.types')]]:
return list(self.contacts.all())

View File

@ -1,6 +1,10 @@
import strawberry
from strawberry import auto
from extras import filtersets, models
from extras.graphql.mixins import CustomFieldsMixin, TagsMixin
from netbox.graphql.types import BaseObjectType, ObjectType, OrganizationalObjectType
from .filters import *
__all__ = (
'ConfigContextType',
@ -18,97 +22,109 @@ __all__ = (
)
@strawberry.django.type(
models.ConfigContext,
fields='__all__',
filters=ConfigContextFilter
)
class ConfigContextType(ObjectType):
class Meta:
model = models.ConfigContext
fields = '__all__'
filterset_class = filtersets.ConfigContextFilterSet
pass
@strawberry.django.type(
models.ConfigTemplate,
fields='__all__',
filters=ConfigTemplateFilter
)
class ConfigTemplateType(TagsMixin, ObjectType):
class Meta:
model = models.ConfigTemplate
fields = '__all__'
filterset_class = filtersets.ConfigTemplateFilterSet
pass
@strawberry.django.type(
models.CustomField,
fields='__all__',
filters=CustomFieldFilter
)
class CustomFieldType(ObjectType):
class Meta:
model = models.CustomField
exclude = ('content_types', )
filterset_class = filtersets.CustomFieldFilterSet
pass
@strawberry.django.type(
models.CustomFieldChoiceSet,
fields='__all__',
filters=CustomFieldChoiceSetFilter
)
class CustomFieldChoiceSetType(ObjectType):
class Meta:
model = models.CustomFieldChoiceSet
fields = '__all__'
filterset_class = filtersets.CustomFieldChoiceSetFilterSet
pass
@strawberry.django.type(
models.CustomLink,
fields='__all__',
filters=CustomLinkFilter
)
class CustomLinkType(ObjectType):
class Meta:
model = models.CustomLink
exclude = ('content_types', )
filterset_class = filtersets.CustomLinkFilterSet
pass
@strawberry.django.type(
models.ExportTemplate,
fields='__all__',
filters=ExportTemplateFilter
)
class ExportTemplateType(ObjectType):
class Meta:
model = models.ExportTemplate
exclude = ('content_types', )
filterset_class = filtersets.ExportTemplateFilterSet
pass
@strawberry.django.type(
models.ImageAttachment,
fields='__all__',
filters=ImageAttachmentFilter
)
class ImageAttachmentType(BaseObjectType):
class Meta:
model = models.ImageAttachment
fields = '__all__'
filterset_class = filtersets.ImageAttachmentFilterSet
pass
@strawberry.django.type(
models.JournalEntry,
fields='__all__',
filters=JournalEntryFilter
)
class JournalEntryType(CustomFieldsMixin, TagsMixin, ObjectType):
class Meta:
model = models.JournalEntry
fields = '__all__'
filterset_class = filtersets.JournalEntryFilterSet
pass
@strawberry.django.type(
models.ObjectChange,
fields='__all__',
filters=ObjectChangeFilter
)
class ObjectChangeType(BaseObjectType):
class Meta:
model = models.ObjectChange
fields = '__all__'
filterset_class = filtersets.ObjectChangeFilterSet
pass
@strawberry.django.type(
models.SavedFilter,
exclude=['content_types',],
filters=SavedFilterFilter
)
class SavedFilterType(ObjectType):
class Meta:
model = models.SavedFilter
exclude = ('content_types', )
filterset_class = filtersets.SavedFilterFilterSet
pass
@strawberry.django.type(
models.Tag,
exclude=['extras_taggeditem_items', 'color'], # bug - remove color from exclude
filters=TagFilter
)
class TagType(ObjectType):
class Meta:
model = models.Tag
exclude = ('extras_taggeditem_items',)
filterset_class = filtersets.TagFilterSet
pass
@strawberry.django.type(
models.Webhook,
exclude=['content_types',],
filters=WebhookFilter
)
class WebhookType(OrganizationalObjectType):
class Meta:
model = models.Webhook
exclude = ('content_types', )
filterset_class = filtersets.WebhookFilterSet
pass

View File

@ -21,23 +21,24 @@ __all__ = (
# Base types
#
@strawberry.type
class BaseObjectType:
"""
Base GraphQL object type for all NetBox objects. Restricts the model queryset to enforce object permissions.
"""
display: auto
class_type: auto
@classmethod
def get_queryset(cls, queryset, info):
# Enforce object permissions on the queryset
return queryset.restrict(info.context.request.user, 'view')
def resolve_display(parent, info, **kwargs):
return str(parent)
@strawberry.django.field
def display(self) -> str:
return str(self)
def resolve_class_type(parent, info, **kwargs):
return parent.__class__.__name__
@strawberry.django.field
def class_type(self) -> str:
return self.__class__.__name__
class ObjectType(
@ -79,8 +80,9 @@ class NetBoxObjectType(
# Miscellaneous types
#
@strawberry.django.type(
ContentType,
fields=['id', 'app_label', 'model'],
)
class ContentTypeType:
class Meta:
model = ContentType
fields = ('id', 'app_label', 'model')
pass