diff options
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rw-r--r-- | awx/locale/en-us/LC_MESSAGES/django.po | 2 | ||||
-rw-r--r-- | awx/main/notifications/rocketchat_backend.py | 5 | ||||
-rw-r--r-- | awx/main/notifications/slack_backend.py | 17 | ||||
-rw-r--r-- | awx/main/tasks.py | 1 | ||||
-rw-r--r-- | awx/main/tests/unit/notifications/test_rocketchat.py | 24 | ||||
-rw-r--r-- | awx/main/tests/unit/notifications/test_slack.py | 73 | ||||
-rw-r--r-- | docs/licenses/slack-sdk.txt (renamed from docs/licenses/slackclient.txt) | 4 | ||||
-rw-r--r-- | requirements/README.md | 6 | ||||
-rw-r--r-- | requirements/requirements.in | 2 | ||||
-rw-r--r-- | requirements/requirements.txt | 8 | ||||
-rw-r--r-- | tools/ansible/roles/dockerfile/templates/Dockerfile.j2 | 5 | ||||
-rw-r--r-- | tools/docker-compose/README.md | 1 | ||||
-rwxr-xr-x | tools/docker-compose/entrypoint.sh | 1 |
14 files changed, 121 insertions, 30 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb1612719f..57c2d79f21 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -110,7 +110,7 @@ For feature work, take a look at the current [Enhancements](https://github.com/a If it has someone assigned to it then that person is the person responsible for working the enhancement. If you feel like you could contribute then reach out to that person. -Fixing bugs, adding translations, and updating the documentation are always appreciated, so reviewing the backlog of issues is always a good place to start. For extra information on debugging tools, see [Debugging](https://github.com/ansible/awx/blob/devel/docs/debugging.md). +Fixing bugs, adding translations, and updating the documentation are always appreciated, so reviewing the backlog of issues is always a good place to start. For extra information on debugging tools, see [Debugging](./docs/debugging/). **NOTE** diff --git a/awx/locale/en-us/LC_MESSAGES/django.po b/awx/locale/en-us/LC_MESSAGES/django.po index b6da611f6a..97dd6807a8 100644 --- a/awx/locale/en-us/LC_MESSAGES/django.po +++ b/awx/locale/en-us/LC_MESSAGES/django.po @@ -4856,7 +4856,7 @@ msgid "Exception connecting to PagerDuty: {}" msgstr "" #: awx/main/notifications/pagerduty_backend.py:87 -#: awx/main/notifications/slack_backend.py:48 +#: awx/main/notifications/slack_backend.py:49 #: awx/main/notifications/twilio_backend.py:47 msgid "Exception sending messages: {}" msgstr "" diff --git a/awx/main/notifications/rocketchat_backend.py b/awx/main/notifications/rocketchat_backend.py index 6d331d9e65..9092b90f17 100644 --- a/awx/main/notifications/rocketchat_backend.py +++ b/awx/main/notifications/rocketchat_backend.py @@ -9,6 +9,7 @@ from django.utils.encoding import smart_text from django.utils.translation import ugettext_lazy as _ from awx.main.notifications.base import AWXBaseEmailBackend +from awx.main.utils import get_awx_http_client_headers from awx.main.notifications.custom_notification_base import CustomNotificationBase logger = logging.getLogger('awx.main.notifications.rocketchat_backend') @@ -38,7 +39,9 @@ class RocketChatBackend(AWXBaseEmailBackend, CustomNotificationBase): if optvalue is not None: payload[optval] = optvalue.strip() - r = requests.post("{}".format(m.recipients()[0]), data=json.dumps(payload), verify=(not self.rocketchat_no_verify_ssl)) + r = requests.post( + "{}".format(m.recipients()[0]), data=json.dumps(payload), headers=get_awx_http_client_headers(), verify=(not self.rocketchat_no_verify_ssl) + ) if r.status_code >= 400: logger.error(smart_text(_("Error sending notification rocket.chat: {}").format(r.status_code))) diff --git a/awx/main/notifications/slack_backend.py b/awx/main/notifications/slack_backend.py index 881abced70..20b7f72f14 100644 --- a/awx/main/notifications/slack_backend.py +++ b/awx/main/notifications/slack_backend.py @@ -2,7 +2,8 @@ # All Rights Reserved. import logging -from slackclient import SlackClient +from slack_sdk import WebClient +from slack_sdk.errors import SlackApiError from django.utils.encoding import smart_text from django.utils.translation import ugettext_lazy as _ @@ -28,7 +29,7 @@ class SlackBackend(AWXBaseEmailBackend, CustomNotificationBase): self.color = hex_color def send_messages(self, messages): - connection = SlackClient(self.token) + client = WebClient(self.token) sent_messages = 0 for m in messages: try: @@ -36,15 +37,15 @@ class SlackBackend(AWXBaseEmailBackend, CustomNotificationBase): if r.startswith('#'): r = r[1:] if self.color: - ret = connection.api_call("chat.postMessage", channel=r, as_user=True, attachments=[{"color": self.color, "text": m.subject}]) + response = client.chat_postMessage(channel=r, as_user=True, attachments=[{"color": self.color, "text": m.subject}]) else: - ret = connection.api_call("chat.postMessage", channel=r, as_user=True, text=m.subject) - logger.debug(ret) - if ret['ok']: + response = client.chat_postMessage(channel=r, as_user=True, text=m.subject) + logger.debug(response) + if response['ok']: sent_messages += 1 else: - raise RuntimeError("Slack Notification unable to send {}: {} ({})".format(r, m.subject, ret['error'])) - except Exception as e: + raise RuntimeError("Slack Notification unable to send {}: {} ({})".format(r, m.subject, response['error'])) + except SlackApiError as e: logger.error(smart_text(_("Exception sending messages: {}").format(e))) if not self.fail_silently: raise diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 01c13bb661..42fb01d253 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -514,6 +514,7 @@ def inspect_execution_nodes(instance_list): logger.warn(f"Registered execution node '{hostname}' (marked disabled by default)") else: logger.warn(f"Unrecognized node on mesh advertising ansible-runner work type: {hostname}") + continue was_lost = instance.is_lost(ref_time=nowtime) last_seen = parse_date(ad['Time']) diff --git a/awx/main/tests/unit/notifications/test_rocketchat.py b/awx/main/tests/unit/notifications/test_rocketchat.py index 8f00d19966..9f087ba98f 100644 --- a/awx/main/tests/unit/notifications/test_rocketchat.py +++ b/awx/main/tests/unit/notifications/test_rocketchat.py @@ -7,8 +7,11 @@ import awx.main.notifications.rocketchat_backend as rocketchat_backend def test_send_messages(): - with mock.patch('awx.main.notifications.rocketchat_backend.requests') as requests_mock: + with mock.patch('awx.main.notifications.rocketchat_backend.requests') as requests_mock, mock.patch( + 'awx.main.notifications.rocketchat_backend.get_awx_http_client_headers' + ) as version_mock: requests_mock.post.return_value.status_code = 201 + version_mock.return_value = {'Content-Type': 'application/json', 'User-Agent': 'AWX 0.0.1.dev (open)'} backend = rocketchat_backend.RocketChatBackend() message = EmailMessage( 'test subject', @@ -23,7 +26,12 @@ def test_send_messages(): message, ] ) - requests_mock.post.assert_called_once_with('http://example.com', data='{"text": "test subject"}', verify=True) + requests_mock.post.assert_called_once_with( + 'http://example.com', + data='{"text": "test subject"}', + headers={'Content-Type': 'application/json', 'User-Agent': 'AWX 0.0.1.dev (open)'}, + verify=True, + ) assert sent_messages == 1 @@ -84,8 +92,11 @@ def test_send_messages_with_icon_url(): def test_send_messages_with_no_verify_ssl(): - with mock.patch('awx.main.notifications.rocketchat_backend.requests') as requests_mock: + with mock.patch('awx.main.notifications.rocketchat_backend.requests') as requests_mock, mock.patch( + 'awx.main.notifications.rocketchat_backend.get_awx_http_client_headers' + ) as version_mock: requests_mock.post.return_value.status_code = 201 + version_mock.return_value = {'Content-Type': 'application/json', 'User-Agent': 'AWX 0.0.1.dev (open)'} backend = rocketchat_backend.RocketChatBackend(rocketchat_no_verify_ssl=True) message = EmailMessage( 'test subject', @@ -100,5 +111,10 @@ def test_send_messages_with_no_verify_ssl(): message, ] ) - requests_mock.post.assert_called_once_with('http://example.com', data='{"text": "test subject"}', verify=False) + requests_mock.post.assert_called_once_with( + 'http://example.com', + data='{"text": "test subject"}', + headers={'Content-Type': 'application/json', 'User-Agent': 'AWX 0.0.1.dev (open)'}, + verify=False, + ) assert sent_messages == 1 diff --git a/awx/main/tests/unit/notifications/test_slack.py b/awx/main/tests/unit/notifications/test_slack.py new file mode 100644 index 0000000000..e4bf3d66ac --- /dev/null +++ b/awx/main/tests/unit/notifications/test_slack.py @@ -0,0 +1,73 @@ +import pytest + +from unittest import mock +from django.core.mail.message import EmailMessage + +import awx.main.notifications.slack_backend as slack_backend + + +def test_send_messages(): + with mock.patch('awx.main.notifications.slack_backend.WebClient') as slack_sdk_mock: + WebClient_mock = slack_sdk_mock.return_value + WebClient_mock.chat_postMessage.return_value = {'ok': True} + backend = slack_backend.SlackBackend('slack_access_token') + message = EmailMessage( + 'test subject', + 'test body', + [], + [ + '#random', + ], + ) + sent_messages = backend.send_messages( + [ + message, + ] + ) + WebClient_mock.chat_postMessage.assert_called_once_with(channel='random', as_user=True, text='test subject') + assert sent_messages == 1 + + +def test_send_messages_with_color(): + with mock.patch('awx.main.notifications.slack_backend.WebClient') as slack_sdk_mock: + WebClient_mock = slack_sdk_mock.return_value + WebClient_mock.chat_postMessage.return_value = {'ok': True} + backend = slack_backend.SlackBackend('slack_access_token', hex_color='#006699') + message = EmailMessage( + 'test subject', + 'test body', + [], + [ + '#random', + ], + ) + sent_messages = backend.send_messages( + [ + message, + ] + ) + + WebClient_mock.chat_postMessage.assert_called_once_with(channel='random', as_user=True, attachments=[{'color': '#006699', 'text': 'test subject'}]) + assert sent_messages == 1 + + +def test_send_messages_fail(): + with mock.patch('awx.main.notifications.slack_backend.WebClient') as slack_sdk_mock, pytest.raises(RuntimeError, match=r'.*not_in_channel.*'): + WebClient_mock = slack_sdk_mock.return_value + WebClient_mock.chat_postMessage.return_value = {'ok': False, 'error': 'not_in_channel'} + backend = slack_backend.SlackBackend('slack_access_token') + message = EmailMessage( + 'test subject', + 'test body', + [], + [ + '#not_existing', + ], + ) + sent_messages = backend.send_messages( + [ + message, + ] + ) + WebClient_mock.chat_postMessage.assert_called_once_with(channel='not_existing', as_user=True, text='test subject') + assert sent_messages == 0 diff --git a/docs/licenses/slackclient.txt b/docs/licenses/slack-sdk.txt index 73da6e9751..c4944b4f8e 100644 --- a/docs/licenses/slackclient.txt +++ b/docs/licenses/slack-sdk.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2016 Slack Technologies, Inc +Copyright (c) 2015- Slack Technologies, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE.
\ No newline at end of file diff --git a/requirements/README.md b/requirements/README.md index b026c20aa7..69ab2d4bcf 100644 --- a/requirements/README.md +++ b/requirements/README.md @@ -108,12 +108,6 @@ Upgrading to 4.0.0 causes error because imports changed. ImportError: cannot import name 'KeyVaultClient' ``` -### slackclient - -Imports as used in `awx/main/notifications/slack_backend.py` changed -in version 2.0. This plugin code will need to change and be re-tested -as the upgrade takes place. - ### django-jsonfield Instead of calling a `loads()` operation, the returned value is casted into diff --git a/requirements/requirements.in b/requirements/requirements.in index 6104cb3a59..79e76250a7 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -50,7 +50,7 @@ social-auth-core==3.3.1 # see UPGRADE BLOCKERs social-auth-app-django==3.1.0 # see UPGRADE BLOCKERs redis requests -slackclient==1.1.2 # see UPGRADE BLOCKERs +slack-sdk tacacs_plus==1.0 # UPGRADE BLOCKER: auth does not work with later versions twilio twisted[tls]>=20.3.0 # CVE-2020-10108, CVE-2020-10109 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 304b73f8a5..63b945ec2f 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -320,7 +320,6 @@ requests==2.23.0 # python-dsv-sdk # python-tss-sdk # requests-oauthlib - # slackclient # social-auth-core # twilio requests-oauthlib==1.3.0 @@ -358,13 +357,12 @@ six==1.14.0 # pyrad # pyrsistent # python-dateutil - # slackclient # social-auth-app-django # social-auth-core # tacacs-plus # twilio # websocket-client -slackclient==1.1.2 +slack-sdk==3.11.2 # via -r /awx_devel/requirements/requirements.in smmap==3.0.1 # via gitdb @@ -399,9 +397,7 @@ uwsgi==2.0.18 uwsgitop==0.11 # via -r /awx_devel/requirements/requirements.in websocket-client==0.57.0 - # via - # kubernetes - # slackclient + # via kubernetes wheel==0.36.2 # via -r /awx_devel/requirements/requirements.in xmlsec==1.3.3 diff --git a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 index 4f8d40fa2d..466d947421 100644 --- a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 +++ b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 @@ -171,6 +171,11 @@ RUN dnf install -y podman RUN echo -e '[engine]\ncgroup_manager = "cgroupfs"\nevents_logger = "file"\nruntime = "crun"' > /etc/containers/containers.conf {% endif %} +# Fix overlay filesystem issue +{% if build_dev|bool %} +RUN sed -i '/^#mount_program/s/^#//' /etc/containers/storage.conf +{% endif %} + # Ensure we must use fully qualified image names # This prevents podman prompt that hangs when trying to pull unqualified images RUN mkdir -p /etc/containers/registries.conf.d/ && echo "unqualified-search-registries = []" >> /etc/containers/registries.conf.d/force-fully-qualified-images.conf && chmod 644 /etc/containers/registries.conf.d/force-fully-qualified-images.conf diff --git a/tools/docker-compose/README.md b/tools/docker-compose/README.md index 88476003fc..5f13612120 100644 --- a/tools/docker-compose/README.md +++ b/tools/docker-compose/README.md @@ -37,6 +37,7 @@ Notable files: - This also installs the `docker` Python module, which is incompatible with [`docker-py`](https://pypi.org/project/docker-py/). If you have previously installed `docker-py`, please uninstall it. - [Docker Compose](https://docs.docker.com/compose/install/). - [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) will need to be installed as we use it to template files needed for the docker-compose. +- OpenSSL. ### Tested Operating Systems diff --git a/tools/docker-compose/entrypoint.sh b/tools/docker-compose/entrypoint.sh index 006435000a..03a3b46616 100755 --- a/tools/docker-compose/entrypoint.sh +++ b/tools/docker-compose/entrypoint.sh @@ -5,6 +5,7 @@ if [ `id -u` -ge 500 ] || [ -z "${CURRENT_UID}" ]; then cat << EOF > /etc/passwd root:x:0:0:root:/root:/bin/bash awx:x:`id -u`:`id -g`:,,,:/var/lib/awx:/bin/bash +nginx:x:`id -u nginx`:`id -g nginx`:Nginx web server:/var/lib/nginx:/sbin/nologin EOF cat <<EOF >> /etc/group |