Skip to content

Commit

Permalink
Add jira connection docs and UI form (#36458)
Browse files Browse the repository at this point in the history
* Add jira connection docs and UI form

* Add support for str and bool in the  extra
  • Loading branch information
shohamy7 committed Dec 30, 2023
1 parent 09603ff commit 31b06d5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 7 deletions.
34 changes: 31 additions & 3 deletions airflow/providers/atlassian/jira/hooks/jira.py
Expand Up @@ -18,11 +18,12 @@
"""Hook for JIRA."""
from __future__ import annotations

import warnings
from typing import Any

from atlassian import Jira

from airflow.exceptions import AirflowException
from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
from airflow.hooks.base import BaseHook


Expand Down Expand Up @@ -56,12 +57,21 @@ def get_conn(self) -> Jira:
conn = self.get_connection(self.jira_conn_id)
if conn.extra is not None:
extra_options = conn.extra_dejson
verify = extra_options.get("verify", verify)
# only required attributes are taken for now,
# more can be added ex: timeout, cloud, session

# verify
if "verify" in extra_options and extra_options["verify"].lower() == "false":
verify = False
if isinstance(verify, str):
warnings.warn(
"Extra parameter `verify` using str is deprecated and will be removed "
"in a future release. Please use `verify` using bool instead.",
AirflowProviderDeprecationWarning,
stacklevel=2,
)
verify = True
if extra_options["verify"].lower() == "false":
verify = False

self.client = Jira(
url=conn.host,
Expand All @@ -72,3 +82,21 @@ def get_conn(self) -> Jira:
)

return self.client

@classmethod
def get_connection_form_widgets(cls) -> dict[str, Any]:
"""Returns connection widgets to add to connection form."""
from flask_babel import lazy_gettext
from wtforms import BooleanField

return {
"verify": BooleanField(lazy_gettext("Verify SSL"), default=True),
}

@classmethod
def get_ui_field_behaviour(cls) -> dict[str, Any]:
"""Returns custom field behaviour."""
return {
"hidden_fields": ["schema", "extra"],
"relabeling": {},
}
44 changes: 44 additions & 0 deletions docs/apache-airflow-providers-atlassian-jira/connections.rst
@@ -0,0 +1,44 @@
.. Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
.. http://www.apache.org/licenses/LICENSE-2.0
.. Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
Jira Connection
===============

The Jira connection type enables connection to Atlassian Jira.

Default Connection IDs
----------------------

Jira Hook uses parameter ``jira_conn_id`` for Connection IDs and the value of the
parameter as ``jira_default`` by default.

Configuring the Connection
--------------------------
Host
The Jira host (should be with scheme).

Port
Specify the port to use for connecting to Jira.

Login
The user that will be used for authentication against the Jira API.

Password
The password of the user that will be used for authentication against the Jira API.

Verify SSL
Whether to verify SSL when connecting to the Jira API (this is ``True`` by default).
1 change: 1 addition & 0 deletions docs/apache-airflow-providers-atlassian-jira/index.rst
Expand Up @@ -34,6 +34,7 @@
:maxdepth: 1
:caption: Guides

Connection types <connections>
Notifications <notifications/index>

.. toctree::
Expand Down
55 changes: 51 additions & 4 deletions tests/providers/atlassian/jira/hooks/test_jira.py
Expand Up @@ -21,32 +21,79 @@

import pytest

from airflow.exceptions import AirflowProviderDeprecationWarning
from airflow.models import Connection
from airflow.providers.atlassian.jira.hooks.jira import JiraHook
from airflow.utils import db

pytestmark = pytest.mark.db_test


jira_client_mock = Mock(name="jira_client")


class TestJiraHook:
depcrecation_message = (
"Extra parameter `verify` using str is deprecated and will be removed "
"in a future release. Please use `verify` using bool instead."
)
conn_id = "jira_default"
conn_id_with_str_verify = "jira_default_with_str"
conn_type = "jira"
host = "https://localhost/jira/"
port = 443
login = "user"
password = "password"
proxies = None

def setup_method(self):
db.merge_conn(
Connection(
conn_id="jira_default",
conn_id=self.conn_id,
conn_type="jira",
host="https://localhost/jira/",
port=443,
login="user",
password="password",
extra='{"verify": false, "project": "AIRFLOW"}',
)
)
db.merge_conn(
Connection(
conn_id=self.conn_id_with_str_verify,
conn_type="jira",
host="https://localhost/jira/",
port=443,
login="user",
password="password",
extra='{"verify": "False", "project": "AIRFLOW"}',
)
)

@patch("airflow.providers.atlassian.jira.hooks.jira.Jira", autospec=True, return_value=jira_client_mock)
def test_jira_client_connection(self, jira_mock):
jira_hook = JiraHook()
jira_hook = JiraHook(proxies=self.proxies)

jira_mock.assert_called_once_with(
url=self.host,
username=self.login,
password=self.password,
verify_ssl=False,
proxies=self.proxies,
)
assert isinstance(jira_hook.client, Mock)
assert jira_hook.client.name == jira_mock.return_value.name

@patch("airflow.providers.atlassian.jira.hooks.jira.Jira", autospec=True, return_value=jira_client_mock)
def test_jira_client_connection_with_str(self, jira_mock):
with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message):
jira_hook = JiraHook(jira_conn_id=self.conn_id_with_str_verify, proxies=self.proxies)

assert jira_mock.called
jira_mock.assert_called_once_with(
url=self.host,
username=self.login,
password=self.password,
verify_ssl=False,
proxies=self.proxies,
)
assert isinstance(jira_hook.client, Mock)
assert jira_hook.client.name == jira_mock.return_value.name

0 comments on commit 31b06d5

Please sign in to comment.