edx-enterprise-data 10.9.2__py3-none-any.whl → 10.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: edx-enterprise-data
3
- Version: 10.9.2
3
+ Version: 10.10.0
4
4
  Summary: Enterprise Reporting
5
5
  Home-page: https://github.com/openedx/edx-enterprise-data
6
6
  Author: edX
@@ -1,4 +1,4 @@
1
- enterprise_data/__init__.py,sha256=43SJnms4n0HahLVcyoeoXg5lGi892WKLrR8LP-MkYto,124
1
+ enterprise_data/__init__.py,sha256=z8VZBN4L4n3dhorf4GlhRP7qPQKCp334pTYxoE7F_As,125
2
2
  enterprise_data/apps.py,sha256=aF6hZwDfI2oWj95tUTm_2ikHueQj-jLj-u0GrgzpsQI,414
3
3
  enterprise_data/clients.py,sha256=pBuCQOP7NYl264ZbMtZCRPCET1pg0by8w6PVlA-icKA,4995
4
4
  enterprise_data/constants.py,sha256=uCKjfpdlMYFZJsAj3n9RMw4Cmg5_6s3NuwocO-fch3s,238
@@ -153,7 +153,8 @@ enterprise_data_roles/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
153
153
  enterprise_data_roles/tests/factories.py,sha256=VOm0NyOhiKkxl1MRIriRkKSpKypr9-4lG2FrsE2YfKo,1153
154
154
  enterprise_data_roles/tests/test_models.py,sha256=wJv7ywk0BSbjlW_U142h0aFxZleAHyT92nIiPy_ECW4,1476
155
155
  enterprise_reporting/__init__.py,sha256=yQO9ureIxFnl-1a_34H53elDwuAzXrSmhLlzqqD2SJ0,112
156
- enterprise_reporting/delivery_method.py,sha256=bG-JCGhrK3nuC3P6D88zBRSwDJCbaDxN35nNlXzvoRM,4813
156
+ enterprise_reporting/constants.py,sha256=k3IKeKl0Rs6PnPqnnwma9SUNcmO6_6Ma4mLXV5mIrH4,208
157
+ enterprise_reporting/delivery_method.py,sha256=JpNEDT3yk4IV27OsqIq0iLv3xcTkW9B285P91YBUrsA,6109
157
158
  enterprise_reporting/external_resource_link_report.py,sha256=jQ6RS0yec0IhAz4wErQ3q8Yn206R7aQbgcR2c803BLA,8066
158
159
  enterprise_reporting/reporter.py,sha256=3wI46qH-CNCUC5r9-Eme1mQdMjwEsFk9myRb-ajzJkM,13807
159
160
  enterprise_reporting/send_enterprise_reports.py,sha256=W9xc7hu3ZP4zmoIndITc3hdXDbd4A3QEWQN0_ZO1E1A,5270
@@ -167,7 +168,7 @@ enterprise_reporting/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
167
168
  enterprise_reporting/fixtures/enterprise_customer_reporting.json,sha256=nS6E9KHW0Iqk7ZHtTyyVyrztIXxjn9OtBvMJkn7owxc,3959
168
169
  enterprise_reporting/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
169
170
  enterprise_reporting/tests/test_clients.py,sha256=h-h7xBJ6wIBKP-QqRxcJJGiQxLfTOLYByCuWfcCeCy0,8474
170
- enterprise_reporting/tests/test_delivery_method.py,sha256=Zy169SrKz5zWjysI_RhGujuPZWivDR3arm3kxAUBPF8,2598
171
+ enterprise_reporting/tests/test_delivery_method.py,sha256=AU4C6qev9ETr_hQCM1QVN1PKztyJNUGfKXI8XzeIOZ4,4555
171
172
  enterprise_reporting/tests/test_enterprise_client.py,sha256=lpWm0muvA3alRjmlRAezE5901C9DU3WiySH4D5-U3qE,1058
172
173
  enterprise_reporting/tests/test_external_link_report.py,sha256=zdnVOD1qtAp9c5EbIPnD9jcoLtW4iKs7gSVklgBK328,7029
173
174
  enterprise_reporting/tests/test_reporter.py,sha256=PTmkGvPjGEjxiyizL88LAKnaWdvZDgOBjL4QStfOdyw,4057
@@ -175,8 +176,8 @@ enterprise_reporting/tests/test_send_enterprise_reports.py,sha256=zBj7sDvRLJQbRs
175
176
  enterprise_reporting/tests/test_utils.py,sha256=y4t6w9aKra-ftqtUeHvPwOhje-1npz7auV5o74ya8fE,9523
176
177
  enterprise_reporting/tests/test_vertica_client.py,sha256=-R2yNCGUjRtoXwLMBloVFQkFYrJoo613VCr61gwI3kQ,140
177
178
  enterprise_reporting/tests/utils.py,sha256=xms2LM7DV3wczXEfctOK1ddel1EE0J_YSr17UzbCDy4,1401
178
- edx_enterprise_data-10.9.2.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
179
- edx_enterprise_data-10.9.2.dist-info/METADATA,sha256=POBhGmJwAD5O1bHRURgDSxzF7nJ2iOok3jI4MW6BAM0,1684
180
- edx_enterprise_data-10.9.2.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
181
- edx_enterprise_data-10.9.2.dist-info/top_level.txt,sha256=f5F2kU-dob6MqiHJpgZkFzoCD5VMhsdpkTV5n9Tvq3I,59
182
- edx_enterprise_data-10.9.2.dist-info/RECORD,,
179
+ edx_enterprise_data-10.10.0.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
180
+ edx_enterprise_data-10.10.0.dist-info/METADATA,sha256=BbVKWA5HCJ6IBYrXapHWyfhPWtP1t5gFieZAVoFyuUQ,1685
181
+ edx_enterprise_data-10.10.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
182
+ edx_enterprise_data-10.10.0.dist-info/top_level.txt,sha256=f5F2kU-dob6MqiHJpgZkFzoCD5VMhsdpkTV5n9Tvq3I,59
183
+ edx_enterprise_data-10.10.0.dist-info/RECORD,,
@@ -2,4 +2,4 @@
2
2
  Enterprise data api application. This Django app exposes API endpoints used by enterprises.
3
3
  """
4
4
 
5
- __version__ = "10.9.2"
5
+ __version__ = "10.10.0"
@@ -0,0 +1,7 @@
1
+ """
2
+ Constants for enterprise_reporting.
3
+ """
4
+
5
+
6
+ SFTP_OPS_GENIE_EMAIL_ALERT_FROM_EMAIL = "enterprise-analytics@edx.org"
7
+ SFTP_OPS_GENIE_EMAIL_ALERT_EMAILS = ['enterprise-reporting-sftp@2u-internal.opsgenie.net']
@@ -2,15 +2,19 @@
2
2
  Classes that handle sending reports for enterprise customers with specific delivery methods.
3
3
  """
4
4
 
5
-
6
-
7
5
  import logging
8
6
  import os
9
7
  from smtplib import SMTPException
10
8
 
11
9
  import paramiko
12
10
 
13
- from enterprise_reporting.utils import compress_and_encrypt, decrypt_string, send_email_with_attachment
11
+ from enterprise_reporting.constants import SFTP_OPS_GENIE_EMAIL_ALERT_EMAILS, SFTP_OPS_GENIE_EMAIL_ALERT_FROM_EMAIL
12
+ from enterprise_reporting.utils import (
13
+ compress_and_encrypt,
14
+ decrypt_string,
15
+ retry_on_exception,
16
+ send_email_with_attachment,
17
+ )
14
18
 
15
19
  LOGGER = logging.getLogger(__name__)
16
20
 
@@ -97,6 +101,8 @@ class SFTPDeliveryMethod(DeliveryMethod):
97
101
  """
98
102
  Class that handles sending an enterprise report file via SFTP.
99
103
  """
104
+ sender_email = SFTP_OPS_GENIE_EMAIL_ALERT_FROM_EMAIL
105
+ receiver_emails = SFTP_OPS_GENIE_EMAIL_ALERT_EMAILS
100
106
 
101
107
  def __init__(self, reporting_config, password):
102
108
  """Initialize the SFTP Delivery Method."""
@@ -106,9 +112,11 @@ class SFTPDeliveryMethod(DeliveryMethod):
106
112
  self.username = reporting_config['sftp_username']
107
113
  self.file_path = reporting_config['sftp_file_path']
108
114
 
109
- def send(self, files):
110
- """Send the given files through SFTP."""
111
- data_reports = super().send(files)
115
+ @retry_on_exception(max_retries=3, delay=2, backoff=2)
116
+ def send_over_sftp(self, data_reports):
117
+ """
118
+ Send the reports via SFTP, retry on exception.
119
+ """
112
120
  LOGGER.info('Connecting via SFTP to remote host {} for {}'.format(
113
121
  self.hostname,
114
122
  self.enterprise_customer_name
@@ -129,4 +137,25 @@ class SFTPDeliveryMethod(DeliveryMethod):
129
137
  )
130
138
  sftp.close()
131
139
  ssh.close()
132
- LOGGER.info(f'Successfully sent report via sftp for {self.enterprise_customer_name}')
140
+
141
+ def send(self, files):
142
+ """Send the given files through SFTP."""
143
+ try:
144
+ data_reports = super().send(files)
145
+ self.send_over_sftp(data_reports)
146
+ except Exception: # pylint: disable=broad-except
147
+ email_subject = f'SFTP transmission failed for {self.enterprise_customer_name}'
148
+ email_body = f'Failed to send {self.data_type} report for {self.enterprise_customer_name}'
149
+ LOGGER.exception(f'SFTP transmission failed for {self.enterprise_customer_name}')
150
+ else:
151
+ LOGGER.info(f'Successfully sent report via sftp for {self.enterprise_customer_name}')
152
+ email_subject = f'SFTP transmission successful for {self.enterprise_customer_name}'
153
+ email_body = f'SFTP transmission successful for {self.enterprise_customer_name}'
154
+
155
+ send_email_with_attachment(
156
+ subject=email_subject,
157
+ body=email_body,
158
+ from_email=self.sender_email,
159
+ to_email=self.receiver_emails,
160
+ attachment_data={},
161
+ )
@@ -2,13 +2,12 @@
2
2
  Test delivery methods.
3
3
  """
4
4
 
5
- import sys
6
5
  import unittest
7
6
 
8
7
  import ddt
9
- import pytest
10
8
 
11
- from enterprise_reporting.delivery_method import DeliveryMethod, SFTPDeliveryMethod, SMTPDeliveryMethod
9
+ from mock import patch, MagicMock
10
+ from enterprise_reporting.delivery_method import SFTPDeliveryMethod, SMTPDeliveryMethod
12
11
  from enterprise_reporting.utils import encrypt_string
13
12
 
14
13
  from .utils import create_files, verify_compressed
@@ -73,3 +72,47 @@ class TestDeliveryMethod(unittest.TestCase):
73
72
  else:
74
73
  assert len(delivery_files) == len(delivery_files)
75
74
  assert delivery_files == [file['file'].name for file in files]
75
+
76
+ @patch('enterprise_reporting.delivery_method.send_email_with_attachment')
77
+ def test_verify_sftp_exception_handling(self, mock_send_email_with_attachment):
78
+ """
79
+ Verify that SFTP transmission related exceptions are being handled correctly.
80
+ """
81
+ file_data = [
82
+ {
83
+ 'name': 'A History of Magic.txt',
84
+ 'size': 1000
85
+ },
86
+ {
87
+ 'name': 'Quidditch Through the Ages.txt',
88
+ 'size': 500
89
+ },
90
+ {
91
+ 'name': 'Quidditch Through the Ages.txt',
92
+ 'size': 500
93
+ },
94
+ ]
95
+ files, total_original_size = create_files(file_data)
96
+ sftp_delivery_method = SFTPDeliveryMethod(self.reporting_config, self.password)
97
+
98
+ # Verify failed SFTP transmission.
99
+ with patch('paramiko.SSHClient.connect', side_effect=Exception('SFTP transmission failed')):
100
+ sftp_delivery_method.send([file['file'] for file in files])
101
+ mock_send_email_with_attachment.assert_called_with(
102
+ subject='SFTP transmission failed for bleh-bleh',
103
+ body='Failed to send progress report for bleh-bleh',
104
+ from_email='enterprise-analytics@edx.org',
105
+ to_email=['enterprise-reporting-sftp@2u-internal.opsgenie.net'],
106
+ attachment_data={},
107
+ )
108
+
109
+ # Verify successful SFTP transmission.
110
+ with patch('paramiko.SSHClient', MagicMock()):
111
+ sftp_delivery_method.send([file['file'] for file in files])
112
+ mock_send_email_with_attachment.assert_called_with(
113
+ subject='SFTP transmission successful for bleh-bleh',
114
+ body='SFTP transmission successful for bleh-bleh',
115
+ from_email='enterprise-analytics@edx.org',
116
+ to_email=['enterprise-reporting-sftp@2u-internal.opsgenie.net'],
117
+ attachment_data={},
118
+ )