Skip to content

Commit 6f3ecbd

Browse files
authored
[COST-5772] gracefully handle IntegrityError on ocppvc table (#5528)
* [COST-5772] wrap operations on ocppvc table in a transaction * drop transaction and clean up log msg * log exception and add unit test * clean up unittest
1 parent c3a0164 commit 6f3ecbd

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

koku/masu/database/ocp_report_db_accessor.py

+47-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import uuid
1212

1313
from dateutil.parser import parse
14+
from django.db import IntegrityError
1415
from django.db.models import DecimalField
1516
from django.db.models import F
1617
from django.db.models import Value
@@ -836,7 +837,16 @@ def populate_cluster_table(self, provider, cluster_id, cluster_alias):
836837

837838
def populate_node_table(self, cluster, nodes):
838839
"""Get or create an entry in the OCP node table."""
839-
LOG.info(log_json(msg="populating reporting_ocp_nodes table", schema=self.schema, cluster=cluster))
840+
841+
LOG.info(
842+
log_json(
843+
msg="populating reporting_ocp_nodes table",
844+
schema=self.schema,
845+
cluster_id=cluster.cluster_id,
846+
cluster_alias=cluster.cluster_alias,
847+
)
848+
)
849+
840850
for node in nodes:
841851
tmp_node = OCPNode.objects.filter(
842852
node=node[0], resource_id=node[1], node_capacity_cpu_cores=node[2], cluster=cluster
@@ -856,23 +866,50 @@ def populate_node_table(self, cluster, nodes):
856866

857867
def populate_pvc_table(self, cluster, pvcs):
858868
"""Get or create an entry in the OCP cluster table."""
859-
LOG.info(log_json(msg="populating reporting_ocp_pvcs table", schema=self.schema, cluster=cluster))
869+
870+
LOG.info(
871+
log_json(
872+
msg="populating reporting_ocp_pvcs table",
873+
schema=self.schema,
874+
cluster_id=cluster.cluster_id,
875+
cluster_alias=cluster.cluster_alias,
876+
)
877+
)
878+
860879
for pvc in pvcs:
861-
try:
862-
ocppvc = OCPPVC.objects.get(persistent_volume=pvc[0], persistent_volume_claim=pvc[1], cluster=cluster)
880+
ocppvc = OCPPVC.objects.filter(
881+
persistent_volume=pvc[0], persistent_volume_claim=pvc[1], cluster=cluster
882+
).first()
883+
if ocppvc:
863884
if not ocppvc.csi_volume_handle:
864885
# Update the existing record's csi_volume_handle
865886
ocppvc.csi_volume_handle = pvc[2]
866887
ocppvc.save(update_fields=["csi_volume_handle"])
867-
except OCPPVC.DoesNotExist:
868-
# If the record does not exist, create a new one
869-
OCPPVC.objects.create(
870-
persistent_volume=pvc[0], persistent_volume_claim=pvc[1], csi_volume_handle=pvc[2], cluster=cluster
871-
)
888+
else:
889+
# If the record does not exist, try creating a new one
890+
try:
891+
OCPPVC.objects.create(
892+
persistent_volume=pvc[0],
893+
persistent_volume_claim=pvc[1],
894+
csi_volume_handle=pvc[2],
895+
cluster=cluster,
896+
)
897+
898+
except IntegrityError as e:
899+
LOG.warning(log_json(msg="IntegrityError raised when creating pvc", pvc=pvc), exc_info=e)
872900

873901
def populate_project_table(self, cluster, projects):
874902
"""Get or create an entry in the OCP cluster table."""
875-
LOG.info(log_json(msg="populating reporting_ocp_projects table", schema=self.schema, cluster=cluster))
903+
904+
LOG.info(
905+
log_json(
906+
msg="populating reporting_ocp_projects table",
907+
schema=self.schema,
908+
cluster_id=cluster.cluster_id,
909+
cluster_alias=cluster.cluster_alias,
910+
)
911+
)
912+
876913
for project in projects:
877914
OCPProject.objects.get_or_create(project=project, cluster=cluster)
878915

koku/masu/test/database/test_ocp_report_db_accessor.py

+19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from unittest.mock import patch
1515

1616
from django.conf import settings
17+
from django.db import IntegrityError
1718
from django.db.models import Q
1819
from django.db.models import Sum
1920
from django_tenants.utils import schema_context
@@ -727,6 +728,24 @@ def test_populate_node_table_second_time_no_change(self):
727728
).count()
728729
self.assertEqual(node_count, 1)
729730

731+
@patch("reporting.provider.ocp.models.OCPPVC.objects.create", side_effect=IntegrityError)
732+
@patch("masu.database.ocp_report_db_accessor.LOG.warning")
733+
def test_populate_pvc_table_handles_integrity_error(self, mock_log, mock_create):
734+
"""Test that populating OCPPVC table handles IntegrityError exception."""
735+
736+
pvcs = ["pvc_1", "pvc_2"]
737+
cluster_id = uuid.uuid4()
738+
cluster_alias = "test-cluster-1"
739+
740+
with self.accessor as accessor:
741+
cluster = accessor.populate_cluster_table(self.ocp_provider, cluster_id, cluster_alias)
742+
accessor.populate_pvc_table(cluster, pvcs)
743+
744+
mock_create.assert_called()
745+
self.assertTrue(
746+
any("IntegrityError raised when creating pvc" in str(call) for call in mock_log.call_args_list)
747+
)
748+
730749
def test_delete_infrastructure_raw_cost_from_daily_summary(self):
731750
"""Test that infra raw cost is deleted."""
732751
with self.accessor as acc:

0 commit comments

Comments
 (0)