|
3 | 3 | """
|
4 | 4 |
|
5 | 5 | from django.contrib.postgres.fields import ArrayField
|
| 6 | +from django.core.exceptions import ValidationError |
6 | 7 | from django.db import models
|
7 | 8 | from django.urls import reverse
|
8 | 9 | from django.utils.translation import gettext_lazy as _
|
|
17 | 18 | "ACLExtendedRule",
|
18 | 19 | )
|
19 | 20 |
|
| 21 | +# Error message when the action is 'remark', but no remark is provided. |
| 22 | +ERROR_MESSAGE_NO_REMARK = _("When the action is 'remark', a remark is required.") |
| 23 | + |
| 24 | +# Error message when the action is 'remark', but the source_prefix is set. |
| 25 | +ERROR_MESSAGE_ACTION_REMARK_SOURCE_PREFIX_SET = _("When the action is 'remark', the Source Prefix must not be set.") |
| 26 | + |
| 27 | +# Error message when the action is 'remark', but the source_ports are set. |
| 28 | +ERROR_MESSAGE_ACTION_REMARK_SOURCE_PORTS_SET = _("When the action is 'remark', Source Ports must not be set.") |
| 29 | + |
| 30 | +# Error message when the action is 'remark', but the destination_prefix is set. |
| 31 | +ERROR_MESSAGE_ACTION_REMARK_DESTINATION_PREFIX_SET = _( |
| 32 | + "When the action is 'remark', the Destination Prefix must not be set." |
| 33 | +) |
| 34 | + |
| 35 | +# Error message when the action is 'remark', but the destination_ports are set. |
| 36 | +ERROR_MESSAGE_ACTION_REMARK_DESTINATION_PORTS_SET = _("When the action is 'remark', Destination Ports must not be set.") |
| 37 | + |
| 38 | +# Error message when the action is 'remark', but the protocol is set. |
| 39 | +ERROR_MESSAGE_ACTION_REMARK_PROTOCOL_SET = _("When the action is 'remark', Protocol must not be set.") |
| 40 | + |
| 41 | +# Error message when a remark is provided, but the action is not set to 'remark'. |
| 42 | +ERROR_MESSAGE_REMARK_WITHOUT_ACTION_REMARK = _("A remark cannot be set unless the action is 'remark'.") |
| 43 | + |
20 | 44 |
|
21 | 45 | class ACLRule(NetBoxModel):
|
22 | 46 | """
|
@@ -111,6 +135,31 @@ class Meta(ACLRule.Meta):
|
111 | 135 | verbose_name = _("ACL Standard Rule")
|
112 | 136 | verbose_name_plural = _("ACL Standard Rules")
|
113 | 137 |
|
| 138 | + def clean(self): |
| 139 | + """ |
| 140 | + Validate the ACL Standard Rule inputs. |
| 141 | +
|
| 142 | + If the action is 'remark', then the remark field must be provided (non-empty), |
| 143 | + and the source_prefix field must be empty. |
| 144 | + Conversely, if the remark field is provided, the action must be set to 'remark'. |
| 145 | + """ |
| 146 | + |
| 147 | + super().clean() |
| 148 | + errors = {} |
| 149 | + |
| 150 | + # Validate that only the remark field is filled |
| 151 | + if self.action == ACLRuleActionChoices.ACTION_REMARK: |
| 152 | + if not self.remark: |
| 153 | + errors["remark"] = ERROR_MESSAGE_NO_REMARK |
| 154 | + if self.source_prefix: |
| 155 | + errors["source_prefix"] = ERROR_MESSAGE_ACTION_REMARK_SOURCE_PREFIX_SET |
| 156 | + # Validate that the action is "remark", when the remark field is provided |
| 157 | + elif self.remark: |
| 158 | + errors["remark"] = ERROR_MESSAGE_REMARK_WITHOUT_ACTION_REMARK |
| 159 | + |
| 160 | + if errors: |
| 161 | + raise ValidationError(errors) |
| 162 | + |
114 | 163 |
|
115 | 164 | class ACLExtendedRule(ACLRule):
|
116 | 165 | """
|
@@ -174,5 +223,43 @@ class Meta(ACLRule.Meta):
|
174 | 223 | verbose_name = _("ACL Extended Rule")
|
175 | 224 | verbose_name_plural = _("ACL Extended Rules")
|
176 | 225 |
|
| 226 | + def clean(self): |
| 227 | + """ |
| 228 | + Validate the ACL Extended Rule inputs. |
| 229 | +
|
| 230 | + When the action is 'remark', the remark field must be provided (non-empty), |
| 231 | + and the following fields must be empty: |
| 232 | + - source_prefix |
| 233 | + - source_ports |
| 234 | + - destination_prefix |
| 235 | + - destination_ports |
| 236 | + - protocol |
| 237 | +
|
| 238 | + Conversely, if a remark is provided, the action must be set to 'remark'. |
| 239 | + """ |
| 240 | + super().clean() |
| 241 | + errors = {} |
| 242 | + |
| 243 | + # Validate that only the remark field is filled |
| 244 | + if self.action == ACLRuleActionChoices.ACTION_REMARK: |
| 245 | + if not self.remark: |
| 246 | + errors["remark"] = ERROR_MESSAGE_NO_REMARK |
| 247 | + if self.source_prefix: |
| 248 | + errors["source_prefix"] = ERROR_MESSAGE_ACTION_REMARK_SOURCE_PREFIX_SET |
| 249 | + if self.source_ports: |
| 250 | + errors["source_ports"] = ERROR_MESSAGE_ACTION_REMARK_SOURCE_PORTS_SET |
| 251 | + if self.destination_prefix: |
| 252 | + errors["destination_prefix"] = ERROR_MESSAGE_ACTION_REMARK_DESTINATION_PREFIX_SET |
| 253 | + if self.destination_ports: |
| 254 | + errors["destination_ports"] = ERROR_MESSAGE_ACTION_REMARK_DESTINATION_PORTS_SET |
| 255 | + if self.protocol: |
| 256 | + errors["protocol"] = ERROR_MESSAGE_ACTION_REMARK_PROTOCOL_SET |
| 257 | + # Validate that the action is "remark", when the remark field is provided |
| 258 | + elif self.remark: |
| 259 | + errors["remark"] = ERROR_MESSAGE_REMARK_WITHOUT_ACTION_REMARK |
| 260 | + |
| 261 | + if errors: |
| 262 | + raise ValidationError(errors) |
| 263 | + |
177 | 264 | def get_protocol_color(self):
|
178 | 265 | return ACLProtocolChoices.colors.get(self.protocol)
|
0 commit comments