|
4 | 4 | from collections.abc import Callable |
5 | 5 | from copy import deepcopy |
6 | 6 | from mimetypes import guess_type |
| 7 | +from urllib.parse import urlparse |
7 | 8 |
|
8 | 9 |
|
9 | 10 | import demistomock as demisto # noqa: F401 |
@@ -3544,11 +3545,24 @@ def jira_test_authorization(client: JiraBaseClient, args: Dict[str, Any]) -> Com |
3544 | 3545 | return CommandResults(readable_output="Successful connection.") |
3545 | 3546 |
|
3546 | 3547 |
|
3547 | | -def jira_test_module(client: JiraBaseClient) -> str: |
3548 | | - """This method will return an error since in order for the user to test the connectivity of the instance, |
3549 | | - they have to run a separate command, therefore, pressing the `test` button on the configuration screen will |
3550 | | - show them the steps in order to test the instance. |
| 3548 | +def jira_test_module(client: JiraBaseClient, params: Dict[str, Any]) -> str: |
3551 | 3549 | """ |
| 3550 | + Tests for basic configuration issues in the instance. |
| 3551 | + Tests the connectivity for basic authentication methods, otherwise provides users with further authentication instructions. |
| 3552 | + """ |
| 3553 | + url = params.get("server_url", "").rstrip("/") |
| 3554 | + cloudid = params.get("cloud_id") |
| 3555 | + |
| 3556 | + if is_jira_cloud_url(url) and not cloudid: |
| 3557 | + raise DemistoException( |
| 3558 | + "Cloud ID is required for Jira Cloud instances. Refer to the integration help section for more information." |
| 3559 | + ) |
| 3560 | + if cloudid and url != "https://api.atlassian.com/ex/jira": |
| 3561 | + raise DemistoException( |
| 3562 | + "Jira Cloud instances must use the default Server URL: `https://api.atlassian.com/ex/jira`." |
| 3563 | + " Please update the Server URL in the instance configuration." |
| 3564 | + ) |
| 3565 | + |
3552 | 3566 | if client.is_basic_auth or client.is_pat_auth: |
3553 | 3567 | client.jira_test_instance_connection() # raises on failure |
3554 | 3568 | return "ok" |
@@ -4745,6 +4759,59 @@ def validate_auth_params(username: str, api_key: str, client_id: str, client_sec |
4745 | 4759 | raise DemistoException("To use OAuth 2.0, the 'Client ID' and 'Client Secret' parameters are mandatory.") |
4746 | 4760 |
|
4747 | 4761 |
|
| 4762 | +def is_jira_cloud_url(url: str) -> bool: |
| 4763 | + """ |
| 4764 | + Check if the given URL is a Jira Cloud Server URL. |
| 4765 | +
|
| 4766 | + Args: |
| 4767 | + url (str): The URL to parse. |
| 4768 | +
|
| 4769 | + Returns: |
| 4770 | + bool: True if the URL is a Jira Cloud URL, False otherwise. |
| 4771 | + """ |
| 4772 | + try: |
| 4773 | + hostname = urlparse(url).hostname or "" |
| 4774 | + return hostname.endswith((".atlassian.net", ".atlassian.com")) |
| 4775 | + |
| 4776 | + except (ValueError, AttributeError): |
| 4777 | + return False |
| 4778 | + |
| 4779 | + |
| 4780 | +def add_config_error_messages(err: str, cloud_id: str, server_url: str) -> str: |
| 4781 | + """ |
| 4782 | + Provide additional information for error messages that result from incorrect configurations. |
| 4783 | +
|
| 4784 | + Args: |
| 4785 | + err (str): The original error message. |
| 4786 | + cloud_id (str): The cloud ID. |
| 4787 | + server_url (str): The server URL. |
| 4788 | +
|
| 4789 | + Returns: |
| 4790 | + str: The error message with additional information if applicable. |
| 4791 | + """ |
| 4792 | + |
| 4793 | + if "404" in err and cloud_id and server_url.rstrip("/") != "https://api.atlassian.com/ex/jira": |
| 4794 | + err = f""" |
| 4795 | +(Error 404) Jira Cloud instances must use the default Server URL: `https://api.atlassian.com/ex/jira`. |
| 4796 | +Update the Server URL in the instance configuration and try again. |
| 4797 | +
|
| 4798 | +
|
| 4799 | +Original error: {err} |
| 4800 | + """ |
| 4801 | + |
| 4802 | + elif "410" in err and not cloud_id and is_jira_cloud_url(server_url): |
| 4803 | + err = f""" |
| 4804 | +(Error 410) The requested endpoint has been removed from Jira On-Prem. |
| 4805 | +This appears to be a Jira Cloud instance. Please update the Cloud ID in the instance configuration and try again. |
| 4806 | +Refer to the integration help section for more information. |
| 4807 | +
|
| 4808 | +
|
| 4809 | +Original error: {err} |
| 4810 | + """ |
| 4811 | + |
| 4812 | + return err |
| 4813 | + |
| 4814 | + |
4748 | 4815 | def main(): # pragma: no cover |
4749 | 4816 | params: Dict[str, Any] = demisto.params() |
4750 | 4817 | args = map_v2_args_to_v3(demisto.args()) |
@@ -4865,7 +4932,7 @@ def main(): # pragma: no cover |
4865 | 4932 | demisto.debug(f"The configured Jira client is: {type(client)}") |
4866 | 4933 |
|
4867 | 4934 | if command == "test-module": |
4868 | | - return_results(jira_test_module(client=client)) |
| 4935 | + return_results(jira_test_module(client=client, params=params)) |
4869 | 4936 | elif command in commands: |
4870 | 4937 | return_results(commands[command](client, args)) |
4871 | 4938 | elif command == "fetch-incidents": |
@@ -4920,7 +4987,9 @@ def main(): # pragma: no cover |
4920 | 4987 | raise NotImplementedError(f"{command} command is not implemented.") |
4921 | 4988 |
|
4922 | 4989 | except Exception as e: |
4923 | | - return_error(str(e)) |
| 4990 | + err = add_config_error_messages(str(e), cloud_id, server_url) |
| 4991 | + |
| 4992 | + return_error(err) |
4924 | 4993 |
|
4925 | 4994 |
|
4926 | 4995 | if __name__ in ["__main__", "builtin", "builtins"]: |
|
0 commit comments