mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-18 02:06:22 +00:00
99 lines
2.8 KiB
Python
99 lines
2.8 KiB
Python
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
from django.contrib.postgres.fields import ArrayField
|
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
|
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from ipam.choices import *
|
|
from ipam.constants import *
|
|
from netbox.models import PrimaryModel
|
|
from netbox.models.features import ContactsMixin
|
|
from utilities.data import array_to_string
|
|
|
|
__all__ = (
|
|
'Service',
|
|
'ServiceTemplate',
|
|
)
|
|
|
|
|
|
class ServiceBase(models.Model):
|
|
protocol = models.CharField(
|
|
verbose_name=_('protocol'),
|
|
max_length=50,
|
|
choices=ServiceProtocolChoices
|
|
)
|
|
ports = ArrayField(
|
|
base_field=models.PositiveIntegerField(
|
|
validators=[
|
|
MinValueValidator(SERVICE_PORT_MIN),
|
|
MaxValueValidator(SERVICE_PORT_MAX)
|
|
]
|
|
),
|
|
verbose_name=_('port numbers')
|
|
)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def __str__(self):
|
|
return f'{self.name} ({self.get_protocol_display()}/{self.port_list})'
|
|
|
|
@property
|
|
def port_list(self):
|
|
return array_to_string(self.ports)
|
|
|
|
|
|
class ServiceTemplate(ServiceBase, PrimaryModel):
|
|
"""
|
|
A template for a Service to be applied to a device or virtual machine.
|
|
"""
|
|
name = models.CharField(
|
|
verbose_name=_('name'),
|
|
max_length=100,
|
|
unique=True
|
|
)
|
|
|
|
class Meta:
|
|
ordering = ('name',)
|
|
verbose_name = _('service template')
|
|
verbose_name_plural = _('service templates')
|
|
|
|
|
|
class Service(ContactsMixin, ServiceBase, PrimaryModel):
|
|
"""
|
|
A Service represents a layer-four service (e.g. HTTP or SSH) running on a Device or VirtualMachine. A Service may
|
|
optionally be tied to one or more specific IPAddresses belonging to its parent.
|
|
"""
|
|
parent_object_type = models.ForeignKey(
|
|
to='contenttypes.ContentType',
|
|
on_delete=models.PROTECT,
|
|
related_name='+',
|
|
)
|
|
parent_object_id = models.PositiveBigIntegerField()
|
|
parent = GenericForeignKey(
|
|
ct_field='parent_object_type',
|
|
fk_field='parent_object_id'
|
|
)
|
|
|
|
name = models.CharField(
|
|
max_length=100,
|
|
verbose_name=_('name')
|
|
)
|
|
ipaddresses = models.ManyToManyField(
|
|
to='ipam.IPAddress',
|
|
related_name='services',
|
|
blank=True,
|
|
verbose_name=_('IP addresses'),
|
|
help_text=_("The specific IP addresses (if any) to which this service is bound")
|
|
)
|
|
|
|
clone_fields = ['protocol', 'ports', 'description', 'parent', 'ipaddresses', ]
|
|
|
|
class Meta:
|
|
indexes = (
|
|
models.Index(fields=('parent_object_type', 'parent_object_id')),
|
|
)
|
|
ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique
|
|
verbose_name = _('service')
|
|
verbose_name_plural = _('services')
|