Skip to content

Commit 83834f0

Browse files
SLA Calculations: Remove product grade calculation and consolidate task handlers (#13630)
* Add custom SLA calculation method to Finding model * Refactor SLA expiration date update methods for async processing and improve system settings checks * Update async SLA expiration date update to filter by product ID * Update helpers.py Co-authored-by: valentijnscholten <valentijnscholten@gmail.com> --------- Co-authored-by: valentijnscholten <valentijnscholten@gmail.com>
1 parent 66b7334 commit 83834f0

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

dojo/models.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ def save(self, *args, **kwargs):
10931093
product.async_updating = True
10941094
super(Product, product).save()
10951095
# launch the async task to update all finding sla expiration dates
1096-
from dojo.sla_config.helpers import update_sla_expiration_dates_sla_config_async # noqa: I001, PLC0415 circular import
1097-
update_sla_expiration_dates_sla_config_async(self, products, tuple(severities))
1096+
from dojo.sla_config.helpers import async_update_sla_expiration_dates_sla_config_sync # noqa: I001, PLC0415 circular import
1097+
async_update_sla_expiration_dates_sla_config_sync(self, products, severities=severities)
10981098

10991099
def clean(self):
11001100
sla_days = [self.critical, self.high, self.medium, self.low]
@@ -1255,8 +1255,8 @@ def save(self, *args, **kwargs):
12551255
sla_config.async_updating = True
12561256
super(SLA_Configuration, sla_config).save()
12571257
# launch the async task to update all finding sla expiration dates
1258-
from dojo.sla_config.helpers import update_sla_expiration_dates_product_async # noqa: I001, PLC0415 circular import
1259-
update_sla_expiration_dates_product_async(self, sla_config)
1258+
from dojo.sla_config.helpers import async_update_sla_expiration_dates_sla_config_sync # noqa: I001, PLC0415 circular import
1259+
async_update_sla_expiration_dates_sla_config_sync(sla_config, Product.objects.filter(id=self.id))
12601260

12611261
def get_absolute_url(self):
12621262
return reverse("view_product", args=[str(self.id)])
@@ -3146,16 +3146,25 @@ def get_sla_configuration(self):
31463146
return self.test.engagement.product.sla_configuration
31473147

31483148
def get_sla_period(self):
3149+
# Determine which method to use to calculate the SLA
3150+
from dojo.utils import get_custom_method # noqa: PLC0415 circular import
3151+
if method := get_custom_method("FINDING_SLA_PERIOD_METHOD"):
3152+
return method(self)
3153+
# Run the default method
31493154
sla_configuration = self.get_sla_configuration()
31503155
sla_period = getattr(sla_configuration, self.severity.lower(), None)
31513156
enforce_period = getattr(sla_configuration, str("enforce_" + self.severity.lower()), None)
31523157
return sla_period, enforce_period
31533158

31543159
def set_sla_expiration_date(self):
3160+
# First check if SLA is enabled globally
31553161
system_settings = System_Settings.objects.get()
31563162
if not system_settings.enable_finding_sla:
31573163
return
3164+
# Call the internal method to set the sla expiration date
3165+
self._set_sla_expiration_date()
31583166

3167+
def _set_sla_expiration_date(self):
31593168
# some parsers provide date as a `str` instead of a `date` in which case we need to parse it #12299 on GitHub
31603169
sla_start_date = self.get_sla_start_date()
31613170
if sla_start_date and isinstance(sla_start_date, str):

dojo/sla_config/helpers.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,50 @@
22

33
from dojo.celery import app
44
from dojo.decorators import dojo_async_task
5-
from dojo.models import Finding, Product, SLA_Configuration
6-
from dojo.utils import calculate_grade, mass_model_updater
5+
from dojo.models import Finding, Product, SLA_Configuration, System_Settings
6+
from dojo.utils import get_custom_method, mass_model_updater
77

88
logger = logging.getLogger(__name__)
99

1010

1111
@dojo_async_task
1212
@app.task
13-
def update_sla_expiration_dates_sla_config_async(sla_config, products, severities, *args, **kwargs):
14-
update_sla_expiration_dates_sla_config_sync(sla_config, products, severities)
13+
def async_update_sla_expiration_dates_sla_config_sync(sla_config: SLA_Configuration, products: list[Product], *args, severities: list[str] | None = None, **kwargs):
14+
if method := get_custom_method("FINDING_SLA_EXPIRATION_CALCULATION_METHOD"):
15+
method(sla_config, products, severities=severities)
16+
else:
17+
update_sla_expiration_dates_sla_config_sync(sla_config, products, severities=severities)
1518

1619

17-
@dojo_async_task
18-
@app.task
19-
def update_sla_expiration_dates_product_async(product, sla_config, *args, **kwargs):
20-
update_sla_expiration_dates_sla_config_sync(sla_config, [product])
21-
22-
23-
def update_sla_expiration_dates_sla_config_sync(sla_config, products, severities=None):
20+
def update_sla_expiration_dates_sla_config_sync(sla_config: SLA_Configuration, products: list[Product], severities: list[str] | None = None):
2421
logger.info("Updating finding SLA expiration dates within the %s SLA configuration", sla_config)
22+
# First check if SLA is enabled globally
23+
system_settings = System_Settings.objects.get()
24+
if not system_settings.enable_finding_sla:
25+
return
2526
# update each finding that is within the SLA configuration that was saved
2627
findings = Finding.objects.filter(test__engagement__product__sla_configuration_id=sla_config.id)
2728
if products:
2829
findings = findings.filter(test__engagement__product__in=products)
2930
if severities:
3031
findings = findings.filter(severity__in=severities)
3132

32-
findings = findings.prefetch_related(
33+
findings = (
34+
findings.prefetch_related(
3335
"test",
3436
"test__engagement",
3537
"test__engagement__product",
3638
"test__engagement__product__sla_configuration",
39+
)
40+
.order_by("id")
41+
.only("id", "sla_start_date", "date", "severity", "test")
3742
)
38-
39-
findings = findings.order_by("id").only("id", "sla_start_date", "date", "severity", "test")
40-
43+
# Call the internal method so that we are not checking system settings for each finding
4144
mass_model_updater(Finding, findings, lambda f: f.set_sla_expiration_date(), fields=["sla_expiration_date"])
4245

4346
# reset the async updating flag to false for all products using this sla config
44-
for product in products:
45-
product.async_updating = False
46-
super(Product, product).save()
47-
calculate_grade(product)
47+
# use update as we don't want save() and signals to be triggered
48+
products.update(async_updating=False)
4849

4950
# reset the async updating flag to false for this sla config
5051
sla_config.async_updating = False

0 commit comments

Comments
 (0)