Skip to content

Commit 59c6692

Browse files
authored
Merge pull request #13786 from valentijnscholten/jira-rate-limiting
JIRA: add retry/rate limit support
2 parents c69eb0e + ef3e19d commit 59c6692

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

docs/content/en/share_your_findings/troubleshooting_jira.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,34 @@ To correct this issue, you can add the 'Epic Name' field to your Project's issue
101101

102102
![image](images/epic_name_error.png)
103103

104+
## Configuring JIRA Connection Retries and Timeouts
105+
106+
DefectDojo's JIRA integration includes configurable retry and timeout settings to handle rate limiting and connection issues. These settings are important for maintaining system responsiveness, especially when using Celery workers.
107+
108+
### Available Configuration Variables
109+
110+
The following environment variables control JIRA connection behavior:
111+
112+
- **`DD_JIRA_MAX_RETRIES`** (default: `3`): Maximum number of retry attempts for recoverable errors. The integration will automatically retry on HTTP 429 (Too Many Requests), HTTP 503 (Service Unavailable), and connection errors. See the [JIRA rate limiting documentation](https://developer.atlassian.com/cloud/jira/platform/rate-limiting/) for more information.
113+
114+
- **`DD_JIRA_CONNECT_TIMEOUT`** (default: `10` seconds): Connection timeout for establishing a connection to the JIRA server.
115+
116+
- **`DD_JIRA_READ_TIMEOUT`** (default: `30` seconds): Read timeout for waiting for a response from the JIRA server after the connection is established.
117+
118+
**Note on Rate Limiting**: The jira library has a built-in maximum wait time of 60 seconds for rate limiting retries. If JIRA's `Retry-After` header indicates a wait time longer than 60 seconds, the request will fail and not be retried. This is a limitation of the jira library version currently in use.
119+
120+
### Why Conservative Values Matter
121+
122+
**Important**: It is recommended to use conservative (lower) values for these settings. Here's why:
123+
124+
1. **Celery Task Blocking**: JIRA operations in DefectDojo run as asynchronous Celery tasks. When a task is waiting for a retry delay, it blocks that Celery worker from processing other tasks.
125+
126+
2. **Worker Pool Exhaustion**: If multiple JIRA operations are retrying with long delays, you can quickly exhaust your Celery worker pool, causing other tasks (not just JIRA-related) to queue up and wait.
127+
128+
3. **System Responsiveness**: Long retry delays can make the system appear unresponsive, especially during JIRA outages or rate limiting events.
129+
130+
JIRA Rate limiting is new, so please let us know on Slack or GitHub what works best for you.
131+
104132
## Jira and DefectDojo are out of sync
105133

106134
Sometimes Jira is down, or DefectDojo is down, or there was bug in a webhook. In this case, Jira can become out of sync with DefectDojo. If this is the case for lots of issues, manual reconciliation might not be feasible. For this scenario there is the management command 'jira_status_reconciliation'.

dojo/jira_link/helper.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,14 +433,19 @@ def has_jira_configured(obj):
433433

434434

435435
def connect_to_jira(jira_server, jira_username, jira_password):
436+
max_retries = getattr(settings, "JIRA_MAX_RETRIES", 3)
437+
timeout = getattr(settings, "JIRA_TIMEOUT", (10, 30))
438+
436439
return JIRA(
437440
server=jira_server,
438441
basic_auth=(jira_username, jira_password),
439-
max_retries=0,
442+
max_retries=max_retries,
443+
timeout=timeout,
440444
options={
441445
"verify": settings.JIRA_SSL_VERIFY,
442446
"headers": settings.ADDITIONAL_HEADERS,
443-
})
447+
},
448+
)
444449

445450

446451
def get_jira_connect_method():

dojo/settings/settings.dist.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@
249249
# When interacting with jira tickets that attached finding groups, we should no be opening any findings
250250
# on the DefectDojo side because jira has no way of knowing if a finding really should be reopened or not
251251
DD_JIRA_WEBHOOK_ALLOW_FINDING_GROUP_REOPEN=(bool, False),
252+
# JIRA connection retry and timeout settings: https://developer.atlassian.com/cloud/jira/platform/rate-limiting/
253+
# Maximum number of retry attempts for recoverable errors (429, 503, ConnectionError)
254+
# See https://jira.readthedocs.io/ for more in the jira library used by DefectDojo
255+
# Note: The jira library has a built-in maximum wait time of 60s for rate limiting retries.
256+
# If JIRA's Retry-After header indicates a wait time longer than 60s, the request will fail and not be retried.
257+
DD_JIRA_MAX_RETRIES=(int, 3),
258+
# Connection timeout (seconds) for establishing a connection to the JIRA server
259+
DD_JIRA_CONNECT_TIMEOUT=(int, 10),
260+
# Read timeout (seconds) for waiting for a response from the JIRA server
261+
DD_JIRA_READ_TIMEOUT=(int, 30),
252262
# You can set extra Jira issue types via a simple env var that supports a csv format, like "Work Item,Vulnerability"
253263
DD_JIRA_EXTRA_ISSUE_TYPES=(str, ""),
254264
# if you want to keep logging to the console but in json format, change this here to 'json_console'
@@ -1714,6 +1724,12 @@ def saml2_attrib_map_format(din):
17141724
JIRA_SSL_VERIFY = env("DD_JIRA_SSL_VERIFY")
17151725
JIRA_DESCRIPTION_MAX_LENGTH = env("DD_JIRA_DESCRIPTION_MAX_LENGTH")
17161726
JIRA_WEBHOOK_ALLOW_FINDING_GROUP_REOPEN = env("DD_JIRA_WEBHOOK_ALLOW_FINDING_GROUP_REOPEN")
1727+
# JIRA connection retry and timeout settings
1728+
JIRA_MAX_RETRIES = env("DD_JIRA_MAX_RETRIES")
1729+
JIRA_CONNECT_TIMEOUT = env("DD_JIRA_CONNECT_TIMEOUT")
1730+
JIRA_READ_TIMEOUT = env("DD_JIRA_READ_TIMEOUT")
1731+
# Combine timeouts into a tuple for the JIRA library: (connect_timeout, read_timeout)
1732+
JIRA_TIMEOUT = (JIRA_CONNECT_TIMEOUT, JIRA_READ_TIMEOUT)
17171733

17181734
# ------------------------------------------------------------------------------
17191735
# LOGGING

0 commit comments

Comments
 (0)