mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-19 04:58:09 +00:00
Do not fail task on notification failure (#2435)
* Do not fail task on notification failure * Need to throw on the last iteration in order for it to go to poison queue * lint
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Iterator, List, Optional, Tuple, Union
|
from typing import Iterator, List, Optional, Tuple, Union
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from azure.devops.connection import Connection
|
from azure.devops.connection import Connection
|
||||||
from azure.devops.credentials import BasicAuthentication
|
from azure.devops.credentials import BasicAuthentication
|
||||||
@ -28,7 +29,7 @@ from onefuzztypes.models import ADOTemplate, RegressionReport, Report
|
|||||||
from onefuzztypes.primitives import Container
|
from onefuzztypes.primitives import Container
|
||||||
|
|
||||||
from ..secrets import get_secret_string_value
|
from ..secrets import get_secret_string_value
|
||||||
from .common import Render, fail_task
|
from .common import Render, log_failed_notification
|
||||||
|
|
||||||
|
|
||||||
class AdoNotificationException(Exception):
|
class AdoNotificationException(Exception):
|
||||||
@ -84,7 +85,7 @@ class ADO:
|
|||||||
value = self.render(self.config.project)
|
value = self.render(self.config.project)
|
||||||
else:
|
else:
|
||||||
value = self.render(self.config.ado_fields[key])
|
value = self.render(self.config.ado_fields[key])
|
||||||
filters[key.lower()] = value
|
filters[key.lower()] = value
|
||||||
|
|
||||||
valid_fields = get_valid_fields(
|
valid_fields = get_valid_fields(
|
||||||
self.client, project=filters.get("system.teamproject")
|
self.client, project=filters.get("system.teamproject")
|
||||||
@ -251,6 +252,7 @@ def notify_ado(
|
|||||||
filename: str,
|
filename: str,
|
||||||
report: Union[Report, RegressionReport],
|
report: Union[Report, RegressionReport],
|
||||||
fail_task_on_transient_error: bool,
|
fail_task_on_transient_error: bool,
|
||||||
|
notification_id: UUID,
|
||||||
) -> None:
|
) -> None:
|
||||||
if isinstance(report, RegressionReport):
|
if isinstance(report, RegressionReport):
|
||||||
logging.info(
|
logging.info(
|
||||||
@ -285,4 +287,8 @@ def notify_ado(
|
|||||||
f"transient ADO notification failure {notification_info}"
|
f"transient ADO notification failure {notification_info}"
|
||||||
) from err
|
) from err
|
||||||
else:
|
else:
|
||||||
fail_task(report, err)
|
log_failed_notification(report, err, notification_id)
|
||||||
|
raise AdoNotificationException(
|
||||||
|
"Sending file changed event for notification %s to poison queue"
|
||||||
|
% notification_id
|
||||||
|
) from err
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from jinja2.sandbox import SandboxedEnvironment
|
from jinja2.sandbox import SandboxedEnvironment
|
||||||
from onefuzztypes.enums import ErrorCode
|
from onefuzztypes.models import Report
|
||||||
from onefuzztypes.models import Error, Report
|
|
||||||
from onefuzztypes.primitives import Container
|
from onefuzztypes.primitives import Container
|
||||||
|
|
||||||
from ..azure.containers import auth_download_url
|
from ..azure.containers import auth_download_url
|
||||||
@ -18,23 +18,17 @@ from ..tasks.config import get_setup_container
|
|||||||
from ..tasks.main import Task
|
from ..tasks.main import Task
|
||||||
|
|
||||||
|
|
||||||
def fail_task(report: Report, error: Exception) -> None:
|
def log_failed_notification(
|
||||||
|
report: Report, error: Exception, notification_id: UUID
|
||||||
|
) -> None:
|
||||||
logging.error(
|
logging.error(
|
||||||
"notification failed: job_id:%s task_id:%s err:%s",
|
"notification failed: notification_id:%s job_id:%s task_id:%s err:%s",
|
||||||
|
notification_id,
|
||||||
report.job_id,
|
report.job_id,
|
||||||
report.task_id,
|
report.task_id,
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
|
|
||||||
task = Task.get(report.job_id, report.task_id)
|
|
||||||
if task:
|
|
||||||
task.mark_failed(
|
|
||||||
Error(
|
|
||||||
code=ErrorCode.NOTIFICATION_FAILURE,
|
|
||||||
errors=["notification failed", str(error)],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Render:
|
class Render:
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from github3 import login
|
from github3 import login
|
||||||
from github3.exceptions import GitHubException
|
from github3.exceptions import GitHubException
|
||||||
@ -19,7 +20,7 @@ from onefuzztypes.models import (
|
|||||||
from onefuzztypes.primitives import Container
|
from onefuzztypes.primitives import Container
|
||||||
|
|
||||||
from ..secrets import get_secret_obj
|
from ..secrets import get_secret_obj
|
||||||
from .common import Render, fail_task
|
from .common import Render, log_failed_notification
|
||||||
|
|
||||||
|
|
||||||
class GithubIssue:
|
class GithubIssue:
|
||||||
@ -113,6 +114,7 @@ def github_issue(
|
|||||||
container: Container,
|
container: Container,
|
||||||
filename: str,
|
filename: str,
|
||||||
report: Optional[Union[Report, RegressionReport]],
|
report: Optional[Union[Report, RegressionReport]],
|
||||||
|
notification_id: UUID,
|
||||||
) -> None:
|
) -> None:
|
||||||
if report is None:
|
if report is None:
|
||||||
return
|
return
|
||||||
@ -129,4 +131,8 @@ def github_issue(
|
|||||||
handler = GithubIssue(config, container, filename, report)
|
handler = GithubIssue(config, container, filename, report)
|
||||||
handler.process()
|
handler.process()
|
||||||
except (GitHubException, ValueError) as err:
|
except (GitHubException, ValueError) as err:
|
||||||
fail_task(report, err)
|
log_failed_notification(report, err, notification_id)
|
||||||
|
raise GitHubException(
|
||||||
|
"Sending file change event for notification %s to poison queue"
|
||||||
|
% notification_id
|
||||||
|
) from err
|
||||||
|
@ -141,7 +141,13 @@ def new_files(
|
|||||||
done.append(notification.config)
|
done.append(notification.config)
|
||||||
|
|
||||||
if isinstance(notification.config, TeamsTemplate):
|
if isinstance(notification.config, TeamsTemplate):
|
||||||
notify_teams(notification.config, container, filename, report)
|
notify_teams(
|
||||||
|
notification.config,
|
||||||
|
container,
|
||||||
|
filename,
|
||||||
|
report,
|
||||||
|
notification.notification_id,
|
||||||
|
)
|
||||||
|
|
||||||
if not report:
|
if not report:
|
||||||
continue
|
continue
|
||||||
@ -153,10 +159,17 @@ def new_files(
|
|||||||
filename,
|
filename,
|
||||||
report,
|
report,
|
||||||
fail_task_on_transient_error,
|
fail_task_on_transient_error,
|
||||||
|
notification.notification_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(notification.config, GithubIssueTemplate):
|
if isinstance(notification.config, GithubIssueTemplate):
|
||||||
github_issue(notification.config, container, filename, report)
|
github_issue(
|
||||||
|
notification.config,
|
||||||
|
container,
|
||||||
|
filename,
|
||||||
|
report,
|
||||||
|
notification.notification_id,
|
||||||
|
)
|
||||||
|
|
||||||
for (task, containers) in get_queue_tasks():
|
for (task, containers) in get_queue_tasks():
|
||||||
if container in containers:
|
if container in containers:
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from onefuzztypes.models import RegressionReport, Report, TeamsTemplate
|
from onefuzztypes.models import RegressionReport, Report, TeamsTemplate
|
||||||
@ -34,6 +35,7 @@ def send_teams_webhook(
|
|||||||
title: str,
|
title: str,
|
||||||
facts: List[Dict[str, str]],
|
facts: List[Dict[str, str]],
|
||||||
text: Optional[str],
|
text: Optional[str],
|
||||||
|
notification_id: UUID,
|
||||||
) -> None:
|
) -> None:
|
||||||
title = markdown_escape(title)
|
title = markdown_escape(title)
|
||||||
|
|
||||||
@ -50,7 +52,12 @@ def send_teams_webhook(
|
|||||||
config_url = get_secret_string_value(config.url)
|
config_url = get_secret_string_value(config.url)
|
||||||
response = requests.post(config_url, json=message)
|
response = requests.post(config_url, json=message)
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
logging.error("webhook failed %s %s", response.status_code, response.content)
|
logging.error(
|
||||||
|
"webhook failed notification_id:%s %s %s",
|
||||||
|
notification_id,
|
||||||
|
response.status_code,
|
||||||
|
response.content,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def notify_teams(
|
def notify_teams(
|
||||||
@ -58,6 +65,7 @@ def notify_teams(
|
|||||||
container: Container,
|
container: Container,
|
||||||
filename: str,
|
filename: str,
|
||||||
report: Optional[Union[Report, RegressionReport]],
|
report: Optional[Union[Report, RegressionReport]],
|
||||||
|
notification_id: UUID,
|
||||||
) -> None:
|
) -> None:
|
||||||
text = None
|
text = None
|
||||||
facts: List[Dict[str, str]] = []
|
facts: List[Dict[str, str]] = []
|
||||||
@ -130,4 +138,4 @@ def notify_teams(
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
send_teams_webhook(config, title, facts, text)
|
send_teams_webhook(config, title, facts, text, notification_id)
|
||||||
|
Reference in New Issue
Block a user