netbox-plugin-dns 1.2.7b2__py3-none-any.whl → 1.3b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of netbox-plugin-dns might be problematic. Click here for more details.

Files changed (73) hide show
  1. netbox_dns/__init__.py +55 -29
  2. netbox_dns/api/field_serializers.py +25 -0
  3. netbox_dns/api/nested_serializers.py +19 -1
  4. netbox_dns/api/serializers_/dnssec_key_template.py +13 -0
  5. netbox_dns/api/serializers_/dnssec_policy.py +30 -0
  6. netbox_dns/api/serializers_/record.py +2 -0
  7. netbox_dns/api/serializers_/record_template.py +2 -0
  8. netbox_dns/api/serializers_/zone.py +10 -1
  9. netbox_dns/choices/dnssec_key_template.py +4 -4
  10. netbox_dns/choices/dnssec_policy.py +2 -2
  11. netbox_dns/choices/record.py +64 -19
  12. netbox_dns/choices/utilities.py +4 -26
  13. netbox_dns/choices/zone.py +96 -1
  14. netbox_dns/fields/choice_array.py +13 -0
  15. netbox_dns/fields/timeperiod.py +15 -13
  16. netbox_dns/filtersets/dnssec_policy.py +25 -1
  17. netbox_dns/filtersets/zone.py +7 -2
  18. netbox_dns/filtersets/zone_template.py +2 -2
  19. netbox_dns/forms/dnssec_key_template.py +2 -1
  20. netbox_dns/forms/dnssec_policy.py +32 -2
  21. netbox_dns/forms/nameserver.py +2 -0
  22. netbox_dns/forms/record_template.py +1 -0
  23. netbox_dns/forms/zone.py +78 -15
  24. netbox_dns/forms/zone_template.py +9 -0
  25. netbox_dns/graphql/enums.py +41 -0
  26. netbox_dns/graphql/filter_lookups.py +13 -0
  27. netbox_dns/graphql/filters/__init__.py +12 -0
  28. netbox_dns/graphql/filters/dnssec_key_template.py +63 -0
  29. netbox_dns/graphql/filters/dnssec_policy.py +123 -0
  30. netbox_dns/graphql/filters/nameserver.py +32 -0
  31. netbox_dns/graphql/filters/record.py +89 -0
  32. netbox_dns/graphql/filters/record_template.py +55 -0
  33. netbox_dns/graphql/filters/registrar.py +30 -0
  34. netbox_dns/graphql/filters/registration_contact.py +27 -0
  35. netbox_dns/graphql/filters/view.py +28 -0
  36. netbox_dns/graphql/filters/zone.py +146 -0
  37. netbox_dns/graphql/filters/zone_template.py +97 -0
  38. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  39. netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
  40. netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +23 -0
  41. netbox_dns/models/dnssec_key_template.py +0 -5
  42. netbox_dns/models/dnssec_policy.py +5 -8
  43. netbox_dns/models/nameserver.py +0 -5
  44. netbox_dns/models/record.py +4 -6
  45. netbox_dns/models/record_template.py +0 -5
  46. netbox_dns/models/registrar.py +0 -5
  47. netbox_dns/models/registration_contact.py +0 -5
  48. netbox_dns/models/view.py +0 -5
  49. netbox_dns/models/zone.py +44 -7
  50. netbox_dns/models/zone_template.py +1 -6
  51. netbox_dns/tables/zone.py +6 -1
  52. netbox_dns/template_content.py +2 -1
  53. netbox_dns/templates/netbox_dns/zone/registration.html +19 -0
  54. netbox_dns/urls.py +7 -0
  55. netbox_dns/utilities/conversions.py +13 -0
  56. netbox_dns/validators/dns_value.py +3 -0
  57. netbox_dns/validators/dnssec.py +10 -8
  58. netbox_dns/views/dnssec_key_template.py +0 -9
  59. netbox_dns/views/dnssec_policy.py +3 -10
  60. netbox_dns/views/nameserver.py +0 -9
  61. netbox_dns/views/record.py +0 -9
  62. netbox_dns/views/record_template.py +0 -3
  63. netbox_dns/views/registrar.py +0 -3
  64. netbox_dns/views/registration_contact.py +0 -3
  65. netbox_dns/views/view.py +0 -9
  66. netbox_dns/views/zone.py +11 -11
  67. netbox_dns/views/zone_template.py +0 -4
  68. {netbox_plugin_dns-1.2.7b2.dist-info → netbox_plugin_dns-1.3b1.dist-info}/METADATA +5 -3
  69. {netbox_plugin_dns-1.2.7b2.dist-info → netbox_plugin_dns-1.3b1.dist-info}/RECORD +72 -58
  70. {netbox_plugin_dns-1.2.7b2.dist-info → netbox_plugin_dns-1.3b1.dist-info}/WHEEL +1 -1
  71. netbox_dns/graphql/filters.py +0 -88
  72. {netbox_plugin_dns-1.2.7b2.dist-info → netbox_plugin_dns-1.3b1.dist-info/licenses}/LICENSE +0 -0
  73. {netbox_plugin_dns-1.2.7b2.dist-info → netbox_plugin_dns-1.3b1.dist-info}/top_level.txt +0 -0
netbox_dns/__init__.py CHANGED
@@ -3,11 +3,8 @@ from django.core.exceptions import ImproperlyConfigured
3
3
 
4
4
  from netbox.plugins import PluginConfig
5
5
  from netbox.plugins.utils import get_plugin_config
6
- from ipam.choices import IPAddressStatusChoices
7
6
 
8
- from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices, ZoneStatusChoices
9
-
10
- __version__ = "1.2.7-beta2"
7
+ __version__ = "1.3-beta1"
11
8
 
12
9
 
13
10
  def _check_list(setting):
@@ -32,31 +29,64 @@ class DNSConfig(PluginConfig):
32
29
  "zone_soa_retry": 7200,
33
30
  "zone_soa_expire": 2419200,
34
31
  "zone_soa_minimum": 3600,
35
- "zone_active_status": [
36
- ZoneStatusChoices.STATUS_ACTIVE,
37
- ZoneStatusChoices.STATUS_DYNAMIC,
38
- ],
39
- "filter_record_types": [],
40
- "record_active_status": [
41
- RecordStatusChoices.STATUS_ACTIVE,
32
+ "zone_active_status": ["active", "dynamic"],
33
+ "zone_expiration_warning_days": 30,
34
+ "filter_record_types": [
35
+ # Obsolete or experimental RRTypes
36
+ "A6", # RFC 6563: Historic
37
+ "AFSDB", # RFC 5864: Obsolete
38
+ "APL", # RFC 3123: Experimental
39
+ "AVC", # https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template
40
+ "GPOS", # RFC 1712: Experimental
41
+ "KEY", # RFC 3755: Obsolete
42
+ "L32", # RFC 6742: Experimental
43
+ "L64", # RFC 6742: Experimental
44
+ "LP", # RFC 6742: Experimental
45
+ "MB", # RFC 2505: Unlikely to ever be adopted
46
+ "MD", # RFC 973: Obsolete
47
+ "MF", # RFC 973: Obsolete
48
+ "MG", # RFC 2505: Unlikely to ever be adopted
49
+ "MINFO", # RFC 2505: Unlikely to ever be adopted
50
+ "MR", # RFC 2505: Unlikely to ever be adopted
51
+ "NID", # RFC 6742: Experimental
52
+ "NINFO", # Application expired
53
+ "NULL", # RFC 1035: Obsolete
54
+ "NXT", # RFC 3755: Obsolete
55
+ "SIG", # RFC 3755: Obsolete
56
+ "SPF", # RFC 7208: Obsolete
57
+ "WKS", # RFC 1127: Not recommended
58
+ # RRTypes with no current use by any notable application
59
+ # (see https://en.wikipedia.org/wiki/List_of_DNS_record_types)
60
+ "RP",
61
+ "ISDN",
62
+ "RT",
63
+ "X25",
64
+ "NSAP",
65
+ "NSAP_PTR",
66
+ "PX",
67
+ "TYPE0", # Reserved
68
+ "UNSPEC", # Reserved
69
+ # DNSSEC RRTypes that are usually not manually maintained
70
+ "NSEC",
71
+ "NSEC3",
72
+ "RRSIG",
42
73
  ],
74
+ "filter_record_types+": [],
75
+ "custom_record_types": [],
76
+ "record_active_status": ["active"],
43
77
  "dnssync_disabled": False,
44
- "dnssync_ipaddress_active_status": [
45
- IPAddressStatusChoices.STATUS_ACTIVE,
46
- IPAddressStatusChoices.STATUS_DHCP,
47
- IPAddressStatusChoices.STATUS_SLAAC,
48
- ],
78
+ "dnssync_ipaddress_active_status": ["active", "dhcp", "slaac"],
49
79
  "dnssync_conflict_deactivate": False,
50
80
  "dnssync_minimum_zone_labels": 2,
51
81
  "tolerate_characters_in_zone_labels": "",
52
82
  "tolerate_underscores_in_labels": False,
53
83
  "tolerate_leading_underscore_types": [
54
- RecordTypeChoices.CNAME,
55
- RecordTypeChoices.DNAME,
56
- RecordTypeChoices.SRV,
57
- RecordTypeChoices.SVCB,
58
- RecordTypeChoices.TLSA,
59
- RecordTypeChoices.TXT,
84
+ "CNAME",
85
+ "DNAME",
86
+ "SRV",
87
+ "SVCB",
88
+ "TLSA",
89
+ "TXT",
60
90
  ],
61
91
  "tolerate_non_rfc1035_types": [],
62
92
  "enable_root_zones": False,
@@ -94,16 +124,12 @@ class DNSConfig(PluginConfig):
94
124
  "record_active_status",
95
125
  "dnssync_ipaddress_active_status",
96
126
  "tolerate_leading_underscore_types",
127
+ "filter_record_types",
128
+ "filter_record_types+",
129
+ "custom_record_types",
97
130
  ):
98
131
  _check_list(setting)
99
132
 
100
- # +
101
- # TODO: Remove this workaround as soon as it's no longer required
102
- #
103
- # Force loading views so the register_model_view is run for all views
104
- # -
105
- import netbox_dns.views # noqa: F401
106
-
107
133
 
108
134
  #
109
135
  # Initialize plugin config
@@ -0,0 +1,25 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+ from rest_framework import serializers
3
+
4
+ from netbox_dns.utilities import iso8601_to_int
5
+
6
+ __all__ = ("TimePeriodField",)
7
+
8
+
9
+ class TimePeriodField(serializers.IntegerField):
10
+ default_error_messages = {
11
+ "invalid": _(
12
+ "Enter a positive integer or an ISO8601 duration (W, M and Y are not supported)."
13
+ ),
14
+ }
15
+
16
+ def to_internal_value(self, data):
17
+ try:
18
+ return iso8601_to_int(data)
19
+ except TypeError:
20
+ raise serializers.ValidationError(
21
+ "Enter a valid integer or ISO 8601 duration (W, M and Y are not supported)."
22
+ )
23
+
24
+ def to_representation(self, value):
25
+ return value
@@ -3,7 +3,7 @@ from rest_framework import serializers
3
3
 
4
4
  from netbox.api.serializers import WritableNestedSerializer
5
5
 
6
- from netbox_dns.models import Zone, Record, ZoneTemplate, RecordTemplate
6
+ from netbox_dns.models import Zone, Record, ZoneTemplate, RecordTemplate, DNSSECPolicy
7
7
  from netbox_dns.api.serializers_.view import ViewSerializer
8
8
 
9
9
 
@@ -12,6 +12,7 @@ __all__ = (
12
12
  "NestedRecordSerializer",
13
13
  "NestedZoneTemplateSerializer",
14
14
  "NestedRecordTemplateSerializer",
15
+ "NestedDNSSECPolicySerializer",
15
16
  )
16
17
 
17
18
 
@@ -127,3 +128,20 @@ class NestedRecordTemplateSerializer(WritableNestedSerializer):
127
128
  "ttl",
128
129
  "description",
129
130
  )
131
+
132
+
133
+ class NestedDNSSECPolicySerializer(WritableNestedSerializer):
134
+ url = serializers.HyperlinkedIdentityField(
135
+ view_name="plugins-api:netbox_dns-api:dnssecpolicy-detail"
136
+ )
137
+
138
+ class Meta:
139
+ model = DNSSECPolicy
140
+ fields = (
141
+ "id",
142
+ "url",
143
+ "display",
144
+ "name",
145
+ "description",
146
+ "status",
147
+ )
@@ -1,3 +1,4 @@
1
+ from django.utils.translation import gettext as _
1
2
  from rest_framework import serializers
2
3
 
3
4
  from netbox.api.serializers import NetBoxModelSerializer
@@ -5,6 +6,9 @@ from tenancy.api.serializers_.tenants import TenantSerializer
5
6
 
6
7
  from netbox_dns.models import DNSSECKeyTemplate
7
8
 
9
+ from ..nested_serializers import NestedDNSSECPolicySerializer
10
+ from ..field_serializers import TimePeriodField
11
+
8
12
 
9
13
  __all__ = ("DNSSECKeyTemplateSerializer",)
10
14
 
@@ -13,6 +17,14 @@ class DNSSECKeyTemplateSerializer(NetBoxModelSerializer):
13
17
  url = serializers.HyperlinkedIdentityField(
14
18
  view_name="plugins-api:netbox_dns-api:dnsseckeytemplate-detail"
15
19
  )
20
+ lifetime = TimePeriodField(required=False, allow_null=True)
21
+ policies = NestedDNSSECPolicySerializer(
22
+ many=True,
23
+ read_only=True,
24
+ required=False,
25
+ default=None,
26
+ help_text=_("Policies using this Key Template"),
27
+ )
16
28
  tenant = TenantSerializer(required=False, allow_null=True)
17
29
 
18
30
  class Meta:
@@ -23,6 +35,7 @@ class DNSSECKeyTemplateSerializer(NetBoxModelSerializer):
23
35
  "display",
24
36
  "name",
25
37
  "description",
38
+ "policies",
26
39
  "tags",
27
40
  "type",
28
41
  "lifetime",
@@ -7,6 +7,8 @@ from tenancy.api.serializers_.tenants import TenantSerializer
7
7
  from netbox_dns.models import DNSSECPolicy
8
8
 
9
9
  from .dnssec_key_template import DNSSECKeyTemplateSerializer
10
+ from ..nested_serializers import NestedZoneSerializer, NestedZoneTemplateSerializer
11
+ from ..field_serializers import TimePeriodField
10
12
 
11
13
 
12
14
  __all__ = ("DNSSECPolicySerializer",)
@@ -24,6 +26,32 @@ class DNSSECPolicySerializer(NetBoxModelSerializer):
24
26
  default=None,
25
27
  help_text=_("Key templates assigned to the policy"),
26
28
  )
29
+ dnskey_ttl = TimePeriodField(required=False, allow_null=True)
30
+ purge_keys = TimePeriodField(required=False, allow_null=True)
31
+ publish_safety = TimePeriodField(required=False, allow_null=True)
32
+ retire_safety = TimePeriodField(required=False, allow_null=True)
33
+ signatures_jitter = TimePeriodField(required=False, allow_null=True)
34
+ signatures_refresh = TimePeriodField(required=False, allow_null=True)
35
+ signatures_validity = TimePeriodField(required=False, allow_null=True)
36
+ signatures_validity_dnskey = TimePeriodField(required=False, allow_null=True)
37
+ max_zone_ttl = TimePeriodField(required=False, allow_null=True)
38
+ zone_propagation_delay = TimePeriodField(required=False, allow_null=True)
39
+ parent_ds_ttl = TimePeriodField(required=False, allow_null=True)
40
+ parent_propagation_delay = TimePeriodField(required=False, allow_null=True)
41
+ zones = NestedZoneSerializer(
42
+ many=True,
43
+ read_only=True,
44
+ required=False,
45
+ default=None,
46
+ help_text=_("Zones this policy is assigned to"),
47
+ )
48
+ zone_templates = NestedZoneTemplateSerializer(
49
+ many=True,
50
+ read_only=True,
51
+ required=False,
52
+ default=None,
53
+ help_text=_("Zone templates this policy is assigned to"),
54
+ )
27
55
  tenant = TenantSerializer(required=False, allow_null=True)
28
56
 
29
57
  class Meta:
@@ -37,6 +65,8 @@ class DNSSECPolicySerializer(NetBoxModelSerializer):
37
65
  "status",
38
66
  "tags",
39
67
  "key_templates",
68
+ "zones",
69
+ "zone_templates",
40
70
  "dnskey_ttl",
41
71
  "purge_keys",
42
72
  "publish_safety",
@@ -8,6 +8,7 @@ from tenancy.api.serializers import TenantSerializer
8
8
  from netbox_dns.models import Record
9
9
 
10
10
  from ..nested_serializers import NestedZoneSerializer, NestedRecordSerializer
11
+ from ..field_serializers import TimePeriodField
11
12
 
12
13
 
13
14
  __all__ = ("RecordSerializer",)
@@ -17,6 +18,7 @@ class RecordSerializer(NetBoxModelSerializer):
17
18
  url = serializers.HyperlinkedIdentityField(
18
19
  view_name="plugins-api:netbox_dns-api:record-detail"
19
20
  )
21
+ ttl = TimePeriodField(required=False, allow_null=True)
20
22
  ptr_record = NestedRecordSerializer(
21
23
  many=False,
22
24
  read_only=True,
@@ -7,6 +7,7 @@ from tenancy.api.serializers import TenantSerializer
7
7
  from netbox_dns.models import RecordTemplate
8
8
 
9
9
  from ..nested_serializers import NestedZoneTemplateSerializer
10
+ from ..field_serializers import TimePeriodField
10
11
 
11
12
 
12
13
  __all__ = ("RecordTemplateSerializer",)
@@ -16,6 +17,7 @@ class RecordTemplateSerializer(NetBoxModelSerializer):
16
17
  url = serializers.HyperlinkedIdentityField(
17
18
  view_name="plugins-api:netbox_dns-api:recordtemplate-detail"
18
19
  )
20
+ ttl = TimePeriodField(required=False, allow_null=True)
19
21
  tenant = TenantSerializer(nested=True, required=False, allow_null=True)
20
22
  zone_templates = NestedZoneTemplateSerializer(
21
23
  many=True,
@@ -12,6 +12,7 @@ from .zone_template import ZoneTemplateSerializer
12
12
  from .dnssec_policy import DNSSECPolicySerializer
13
13
 
14
14
  from ..nested_serializers import NestedZoneSerializer
15
+ from ..field_serializers import TimePeriodField
15
16
 
16
17
  from netbox_dns.models import Zone
17
18
 
@@ -38,6 +39,8 @@ class ZoneSerializer(NetBoxModelSerializer):
38
39
  required=False,
39
40
  help_text=_("Nameservers for the zone"),
40
41
  )
42
+ default_ttl = TimePeriodField(required=False, allow_null=True)
43
+ soa_ttl = TimePeriodField(required=False, allow_null=True)
41
44
  soa_mname = NameServerSerializer(
42
45
  nested=True,
43
46
  many=False,
@@ -51,6 +54,10 @@ class ZoneSerializer(NetBoxModelSerializer):
51
54
  required=False,
52
55
  help_text=_("Contact email for the zone"),
53
56
  )
57
+ soa_refresh = TimePeriodField(required=False, allow_null=True)
58
+ soa_retry = TimePeriodField(required=False, allow_null=True)
59
+ soa_expire = TimePeriodField(required=False, allow_null=True)
60
+ soa_minimum = TimePeriodField(required=False, allow_null=True)
54
61
  rfc2317_parent_zone = NestedZoneSerializer(
55
62
  many=False,
56
63
  read_only=True,
@@ -120,7 +127,7 @@ class ZoneSerializer(NetBoxModelSerializer):
120
127
  tenant = TenantSerializer(nested=True, required=False, allow_null=True)
121
128
 
122
129
  def validate(self, data):
123
- if (template := data.get("template")) is not None:
130
+ if isinstance(data, dict) and (template := data.get("template")) is not None:
124
131
  template.apply_to_zone_data(data)
125
132
 
126
133
  return super().validate(data)
@@ -185,6 +192,8 @@ class ZoneSerializer(NetBoxModelSerializer):
185
192
  "inline_signing",
186
193
  "registrar",
187
194
  "registry_domain_id",
195
+ "expiration_date",
196
+ "domain_status",
188
197
  "registrant",
189
198
  "tech_c",
190
199
  "admin_c",
@@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _
4
4
 
5
5
  from utilities.choices import ChoiceSet
6
6
 
7
- from .utilities import define_choice_attributes
7
+ from .utilities import initialize_choice_names
8
8
 
9
9
  DEPRECATED_ALGORITHMS = (
10
10
  Algorithm.RSAMD5,
@@ -54,10 +54,10 @@ class DNSSECKeyTemplateKeySizeChoices(ChoiceSet):
54
54
  ]
55
55
 
56
56
 
57
- @define_choice_attributes()
57
+ @initialize_choice_names
58
58
  class DNSSECKeyTemplateAlgorithmChoices(ChoiceSet):
59
59
  CHOICES = [
60
- (algorithm.name, algorithm.name)
61
- for algorithm in sorted(Algorithm, key=lambda a: a.name)
60
+ (algorithm.name, f"{algorithm.name} ({algorithm.value})")
61
+ for algorithm in sorted(Algorithm, key=lambda a: a.value)
62
62
  if algorithm.value < 252 and algorithm not in DEPRECATED_ALGORITHMS
63
63
  ]
@@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _
4
4
 
5
5
  from utilities.choices import ChoiceSet
6
6
 
7
- from .utilities import define_choice_attributes
7
+ from .utilities import initialize_choice_names
8
8
 
9
9
  DEPRECATED_DIGESTS = (
10
10
  DSDigest.NULL,
@@ -19,7 +19,7 @@ __all__ = (
19
19
  )
20
20
 
21
21
 
22
- @define_choice_attributes()
22
+ @initialize_choice_names
23
23
  class DNSSECPolicyDigestChoices(ChoiceSet):
24
24
  CHOICES = [
25
25
  (digest.name, digest.name)
@@ -3,8 +3,9 @@ from dns import rdatatype, rdataclass
3
3
  from django.utils.translation import gettext_lazy as _
4
4
 
5
5
  from utilities.choices import ChoiceSet
6
+ from netbox.plugins.utils import get_plugin_config
6
7
 
7
- from .utilities import define_choice_attributes
8
+ from .utilities import initialize_choice_names
8
9
 
9
10
 
10
11
  __all__ = (
@@ -15,34 +16,78 @@ __all__ = (
15
16
  )
16
17
 
17
18
 
18
- @define_choice_attributes()
19
+ def _get_config_option(option_name):
20
+ return get_plugin_config("netbox_dns", option_name, []) + get_plugin_config(
21
+ "netbox_dns", f"{option_name}+", []
22
+ )
23
+
24
+
25
+ class RecordTypeNames:
26
+ def __init__(self):
27
+ self.record_type_names = sorted(
28
+ [
29
+ rdtype.name
30
+ for rdtype in rdatatype.RdataType
31
+ if not rdatatype.is_metatype(rdtype)
32
+ ]
33
+ + _get_config_option("custom_record_types")
34
+ )
35
+
36
+ def __iter__(self):
37
+ for rdtype_name in self.record_type_names:
38
+ yield rdtype_name
39
+
40
+
41
+ class RecordSelectableTypeNames:
42
+ def __init__(self, exclude_types=[]):
43
+ self.record_type_names = sorted(
44
+ [
45
+ rdtype.name
46
+ for rdtype in rdatatype.RdataType
47
+ if not rdatatype.is_metatype(rdtype)
48
+ and rdtype.name not in _get_config_option("filter_record_types")
49
+ ]
50
+ + _get_config_option("custom_record_types")
51
+ )
52
+
53
+ def __iter__(self):
54
+ for rdtype_name in self.record_type_names:
55
+ yield rdtype_name
56
+
57
+
58
+ class RecordClassNames:
59
+ def __iter__(self):
60
+ for rdclass in rdataclass.RdataClass:
61
+ yield rdclass.name
62
+
63
+
64
+ @initialize_choice_names
19
65
  class RecordTypeChoices(ChoiceSet):
20
- CHOICES = [
21
- (rdtype.name, rdtype.name)
22
- for rdtype in sorted(rdatatype.RdataType, key=lambda a: a.name)
23
- if not rdatatype.is_metatype(rdtype)
24
- ]
66
+ def choices():
67
+ return RecordTypeNames()
68
+
69
+ CHOICES = [(name, name) for name in choices()]
70
+
25
71
  SINGLETONS = [
26
72
  rdtype.name for rdtype in rdatatype.RdataType if rdatatype.is_singleton(rdtype)
27
73
  ]
74
+ CUSTOM_TYPES = _get_config_option("custom_record_types")
28
75
 
29
76
 
30
- @define_choice_attributes(filter_name="filter_record_types")
77
+ @initialize_choice_names
31
78
  class RecordSelectableTypeChoices(ChoiceSet):
32
- CHOICES = [
33
- (rdtype.name, rdtype.name)
34
- for rdtype in sorted(rdatatype.RdataType, key=lambda a: a.name)
35
- if not rdatatype.is_metatype(rdtype)
36
- ]
79
+ def choices():
80
+ return RecordSelectableTypeNames()
81
+
82
+ CHOICES = [(name, name) for name in choices()]
37
83
 
38
84
 
39
- @define_choice_attributes()
85
+ @initialize_choice_names
40
86
  class RecordClassChoices(ChoiceSet):
41
- CHOICES = [
42
- (rdclass.name, rdclass.name)
43
- for rdclass in sorted(rdataclass.RdataClass)
44
- if not rdataclass.is_metaclass(rdclass)
45
- ]
87
+ def choices():
88
+ return RecordClassNames()
89
+
90
+ CHOICES = [(name, name) for name in choices()]
46
91
 
47
92
 
48
93
  class RecordStatusChoices(ChoiceSet):
@@ -1,26 +1,4 @@
1
- from django.core.exceptions import ImproperlyConfigured
2
-
3
- from netbox.plugins.utils import get_plugin_config
4
-
5
-
6
- def define_choice_attributes(filter_name=None):
7
- try:
8
- if filter_name is not None:
9
- filter_choices = get_plugin_config("netbox_dns", filter_name, [])
10
- else:
11
- filter_choices = []
12
- except ImproperlyConfigured:
13
- filter_choices = []
14
-
15
- def decorator(cls):
16
- choices = []
17
- for choice in cls._choices:
18
- if choice[0] not in filter_choices:
19
- setattr(cls, choice[0], choice[0])
20
- choices.append(choice)
21
- cls._choices = choices
22
- cls.CHOICES = choices
23
-
24
- return cls
25
-
26
- return decorator
1
+ def initialize_choice_names(cls):
2
+ for choice in cls.CHOICES:
3
+ setattr(cls, choice[0], choice[0])
4
+ return cls
@@ -3,7 +3,10 @@ from django.utils.translation import gettext_lazy as _
3
3
  from utilities.choices import ChoiceSet
4
4
 
5
5
 
6
- __all__ = ("ZoneStatusChoices",)
6
+ __all__ = (
7
+ "ZoneStatusChoices",
8
+ "ZoneEPPStatusChoices",
9
+ )
7
10
 
8
11
 
9
12
  class ZoneStatusChoices(ChoiceSet):
@@ -22,3 +25,95 @@ class ZoneStatusChoices(ChoiceSet):
22
25
  (STATUS_PARKED, _("Parked"), "gray"),
23
26
  (STATUS_DYNAMIC, _("Dynamic"), "orange"),
24
27
  ]
28
+
29
+
30
+ class ZoneEPPStatusChoices(ChoiceSet):
31
+ """
32
+ Reflects the EPP status of a zone registered as a domain. See
33
+ https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en
34
+ for details.
35
+ """
36
+
37
+ key = "Zone.epp_status"
38
+
39
+ EPP_STATUS_ADD_PERIOD = "addPeriod"
40
+ EPP_STATUS_AUTO_RENEW_PERIOD = "autoRenewPeriod"
41
+ EPP_STATUS_INACTIVE = "inactive"
42
+ EPP_STATUS_OK = "ok"
43
+ EPP_STATUS_PENDING_CREATE = "pendingCreate"
44
+ EPP_STATUS_PENDING_DELETE = "pendingDelete"
45
+ EPP_STATUS_PENDING_RENEW = "pendingRenew"
46
+ EPP_STATUS_PENDING_RESTORE = "pendingRestore"
47
+ EPP_STATUS_PENDING_TRANSFER = "pendingTransfer"
48
+ EPP_STATUS_PENDING_UPDATE = "pendingUpdate"
49
+ EPP_STATUS_REDEMPTION_PERIOD = "redemptionPeriod"
50
+ EPP_STATUS_RENEW_PERIOD = "renewPeriod"
51
+ EPP_STATUS_SERVER_DELETE_PROHIBITED = "serverDeleteProhibited"
52
+ EPP_STATUS_SERVER_HOLD = "serverHold"
53
+ EPP_STATUS_SERVER_RENER_PROHIBITED = "serverRenewProhibited"
54
+ EPP_STATUS_SERVER_TRANSFER_PROHIBITED = "serverTransferProhibited"
55
+ EPP_STATUS_SERVER_UPDATE_PROHIBITED = "serverUpdateProhibited"
56
+ EPP_STATUS_TRANSFER_PERIOD = "transferPeriod"
57
+ EPP_STATUS_CLIENT_DELETE_PROHIBITED = "clientDeleteProhibited"
58
+ EPP_STATUS_CLIENT_HOLD = "clientHold"
59
+ EPP_STATUS_CLIENT_RENEW_PROHIBITED = "clientRenewProhibited"
60
+ EPP_STATUS_CLIENT_TRANSFER_PROHIBITED = "clientTransferProhibited"
61
+ EPP_STATUS_CLIENT_UPDATE_PROHIBITED = "clientUpdateProhibited"
62
+
63
+ CHOICES = [
64
+ (EPP_STATUS_ADD_PERIOD, EPP_STATUS_ADD_PERIOD, "blue"),
65
+ (EPP_STATUS_AUTO_RENEW_PERIOD, EPP_STATUS_AUTO_RENEW_PERIOD, "blue"),
66
+ (EPP_STATUS_INACTIVE, EPP_STATUS_INACTIVE, "blue"),
67
+ (EPP_STATUS_OK, EPP_STATUS_OK, "blue"),
68
+ (EPP_STATUS_PENDING_CREATE, EPP_STATUS_PENDING_CREATE, "blue"),
69
+ (EPP_STATUS_PENDING_DELETE, EPP_STATUS_PENDING_DELETE, "blue"),
70
+ (EPP_STATUS_PENDING_RENEW, EPP_STATUS_PENDING_RENEW, "blue"),
71
+ (EPP_STATUS_PENDING_RESTORE, EPP_STATUS_PENDING_RESTORE, "blue"),
72
+ (EPP_STATUS_PENDING_TRANSFER, EPP_STATUS_PENDING_TRANSFER, "blue"),
73
+ (EPP_STATUS_PENDING_UPDATE, EPP_STATUS_PENDING_UPDATE, "blue"),
74
+ (EPP_STATUS_REDEMPTION_PERIOD, EPP_STATUS_REDEMPTION_PERIOD, "blue"),
75
+ (EPP_STATUS_RENEW_PERIOD, EPP_STATUS_RENEW_PERIOD, "blue"),
76
+ (
77
+ EPP_STATUS_SERVER_DELETE_PROHIBITED,
78
+ EPP_STATUS_SERVER_DELETE_PROHIBITED,
79
+ "blue",
80
+ ),
81
+ (EPP_STATUS_SERVER_HOLD, EPP_STATUS_SERVER_HOLD, "blue"),
82
+ (
83
+ EPP_STATUS_SERVER_RENER_PROHIBITED,
84
+ EPP_STATUS_SERVER_RENER_PROHIBITED,
85
+ "blue",
86
+ ),
87
+ (
88
+ EPP_STATUS_SERVER_TRANSFER_PROHIBITED,
89
+ EPP_STATUS_SERVER_TRANSFER_PROHIBITED,
90
+ "blue",
91
+ ),
92
+ (
93
+ EPP_STATUS_SERVER_UPDATE_PROHIBITED,
94
+ EPP_STATUS_SERVER_UPDATE_PROHIBITED,
95
+ "blue",
96
+ ),
97
+ (EPP_STATUS_TRANSFER_PERIOD, EPP_STATUS_TRANSFER_PERIOD, "blue"),
98
+ (
99
+ EPP_STATUS_CLIENT_DELETE_PROHIBITED,
100
+ EPP_STATUS_CLIENT_DELETE_PROHIBITED,
101
+ "cyan",
102
+ ),
103
+ (EPP_STATUS_CLIENT_HOLD, EPP_STATUS_CLIENT_HOLD, "cyan"),
104
+ (
105
+ EPP_STATUS_CLIENT_RENEW_PROHIBITED,
106
+ EPP_STATUS_CLIENT_RENEW_PROHIBITED,
107
+ "cyan",
108
+ ),
109
+ (
110
+ EPP_STATUS_CLIENT_TRANSFER_PROHIBITED,
111
+ EPP_STATUS_CLIENT_TRANSFER_PROHIBITED,
112
+ "cyan",
113
+ ),
114
+ (
115
+ EPP_STATUS_CLIENT_UPDATE_PROHIBITED,
116
+ EPP_STATUS_CLIENT_UPDATE_PROHIBITED,
117
+ "cyan",
118
+ ),
119
+ ]
@@ -1,5 +1,15 @@
1
1
  from django import forms
2
2
  from django.contrib.postgres.fields import ArrayField
3
+ from django.db.models import Transform, IntegerField
4
+
5
+
6
+ class ArrayLength(Transform):
7
+ lookup_name = "length"
8
+ function = "cardinality"
9
+
10
+ @property
11
+ def output_field(self):
12
+ return IntegerField()
3
13
 
4
14
 
5
15
  class _TypedMultipleChoiceField(forms.TypedMultipleChoiceField):
@@ -18,3 +28,6 @@ class ChoiceArrayField(ArrayField):
18
28
  coerce=self.base_field.to_python,
19
29
  **kwargs,
20
30
  )
31
+
32
+
33
+ ChoiceArrayField.register_lookup(ArrayLength)