mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #1687: Enabled custom fields for services
This commit is contained in:
@ -3,11 +3,11 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
# Models which support custom fields
|
# Models which support custom fields
|
||||||
CUSTOMFIELD_MODELS = (
|
CUSTOMFIELD_MODELS = (
|
||||||
'provider', 'circuit', # Circuits
|
'provider', 'circuit', # Circuits
|
||||||
'site', 'rack', 'devicetype', 'device', # DCIM
|
'site', 'rack', 'devicetype', 'device', # DCIM
|
||||||
'aggregate', 'prefix', 'ipaddress', 'vlan', 'vrf', # IPAM
|
'aggregate', 'prefix', 'ipaddress', 'vlan', 'vrf', 'service', # IPAM
|
||||||
'tenant', # Tenancy
|
'tenant', # Tenancy
|
||||||
'cluster', 'virtualmachine', # Virtualization
|
'cluster', 'virtualmachine', # Virtualization
|
||||||
)
|
)
|
||||||
|
|
||||||
# Custom field types
|
# Custom field types
|
||||||
|
@ -301,7 +301,7 @@ class AvailableIPSerializer(serializers.Serializer):
|
|||||||
# Services
|
# Services
|
||||||
#
|
#
|
||||||
|
|
||||||
class ServiceSerializer(ValidatedModelSerializer):
|
class ServiceSerializer(CustomFieldModelSerializer):
|
||||||
device = NestedDeviceSerializer(required=False, allow_null=True)
|
device = NestedDeviceSerializer(required=False, allow_null=True)
|
||||||
virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True)
|
virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True)
|
||||||
protocol = ChoiceFieldSerializer(choices=IP_PROTOCOL_CHOICES)
|
protocol = ChoiceFieldSerializer(choices=IP_PROTOCOL_CHOICES)
|
||||||
@ -315,6 +315,6 @@ class ServiceSerializer(ValidatedModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Service
|
model = Service
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'device', 'virtual_machine', 'name', 'port', 'protocol', 'ipaddresses', 'description', 'created',
|
'id', 'device', 'virtual_machine', 'name', 'port', 'protocol', 'ipaddresses', 'description',
|
||||||
'last_updated',
|
'custom_fields', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
|
@ -11,9 +11,9 @@ from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFi
|
|||||||
from tenancy.forms import TenancyForm
|
from tenancy.forms import TenancyForm
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
AnnotatedMultipleChoiceField, APISelect, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
|
AnnotatedMultipleChoiceField, APISelect, BootstrapMixin, BulkEditNullBooleanSelect, ChainedModelChoiceField,
|
||||||
ChainedModelChoiceField, CSVChoiceField, ExpandableIPAddressField, FilterChoiceField, FlexibleModelChoiceField,
|
CSVChoiceField, ExpandableIPAddressField, FilterChoiceField, FlexibleModelChoiceField, Livesearch, ReturnURLForm,
|
||||||
Livesearch, ReturnURLForm, SlugField, add_blank_choice,
|
SlugField, add_blank_choice,
|
||||||
)
|
)
|
||||||
from virtualization.models import VirtualMachine
|
from virtualization.models import VirtualMachine
|
||||||
from .constants import (
|
from .constants import (
|
||||||
@ -917,7 +917,7 @@ class VLANFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
|||||||
# Services
|
# Services
|
||||||
#
|
#
|
||||||
|
|
||||||
class ServiceForm(BootstrapMixin, forms.ModelForm):
|
class ServiceForm(BootstrapMixin, CustomFieldForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Service
|
model = Service
|
||||||
@ -947,7 +947,10 @@ class ServiceForm(BootstrapMixin, forms.ModelForm):
|
|||||||
|
|
||||||
class ServiceFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
class ServiceFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||||
model = Service
|
model = Service
|
||||||
q = forms.CharField(required=False, label='Search')
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
label='Search'
|
||||||
|
)
|
||||||
protocol = forms.ChoiceField(
|
protocol = forms.ChoiceField(
|
||||||
choices=add_blank_choice(IP_PROTOCOL_CHOICES),
|
choices=add_blank_choice(IP_PROTOCOL_CHOICES),
|
||||||
required=False
|
required=False
|
||||||
@ -957,7 +960,7 @@ class ServiceFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ServiceBulkEditForm(BootstrapMixin, BulkEditForm):
|
class ServiceBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||||
pk = forms.ModelMultipleChoiceField(queryset=Service.objects.all(), widget=forms.MultipleHiddenInput)
|
pk = forms.ModelMultipleChoiceField(queryset=Service.objects.all(), widget=forms.MultipleHiddenInput)
|
||||||
protocol = forms.ChoiceField(choices=add_blank_choice(IP_PROTOCOL_CHOICES), required=False)
|
protocol = forms.ChoiceField(choices=add_blank_choice(IP_PROTOCOL_CHOICES), required=False)
|
||||||
port = forms.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(65535)], required=False)
|
port = forms.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(65535)], required=False)
|
||||||
|
@ -835,7 +835,7 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
|||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Service(CreatedUpdatedModel):
|
class Service(CreatedUpdatedModel, CustomFieldModel):
|
||||||
"""
|
"""
|
||||||
A Service represents a layer-four service (e.g. HTTP or SSH) running on a Device or VirtualMachine. A Service may
|
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.
|
optionally be tied to one or more specific IPAddresses belonging to its parent.
|
||||||
@ -875,6 +875,11 @@ class Service(CreatedUpdatedModel):
|
|||||||
max_length=100,
|
max_length=100,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
custom_field_values = GenericRelation(
|
||||||
|
to='extras.CustomFieldValue',
|
||||||
|
content_type_field='obj_type',
|
||||||
|
object_id_field='obj_id'
|
||||||
|
)
|
||||||
|
|
||||||
serializer = 'ipam.api.serializers.ServiceSerializer'
|
serializer = 'ipam.api.serializers.ServiceSerializer'
|
||||||
|
|
||||||
|
@ -32,4 +32,12 @@
|
|||||||
{% render_field form.description %}
|
{% render_field form.description %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if form.custom_fields %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><strong>Custom Fields</strong></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% render_custom_fields form %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
{% extends '_base.html' %}
|
{% extends '_base.html' %}
|
||||||
{% load buttons %}
|
|
||||||
{% load humanize %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% block title %}Services{% endblock %}</h1>
|
<h1>{% block title %}Services{% endblock %}</h1>
|
||||||
|
Reference in New Issue
Block a user