def test__update_bucket_fails(self, mock_consul): """ Test s3 provisioning fails on bucket update, and retries up to 4 times This can happen when the IAM is updated but the propagation is delayed """ instance = OpenEdXInstanceFactory() instance.s3_access_key = 'test' instance.s3_secret_access_key = 'test' instance.s3_bucket_name = 'test' max_tries = 4 stubber = S3Stubber(s3_client) stubber.stub_create_bucket(location='') for _ in range(max_tries): stubber.stub_put_cors() stubber.add_client_error('put_bucket_lifecycle_configuration') with self.assertLogs('instance.models.instance', level='INFO') as cm: with stubber, self.assertRaises(ClientError): instance._create_bucket(max_tries=max_tries) base_log_text = ( 'INFO:instance.models.instance:instance={} ({!s:.15}) | Retrying bucket configuration' ' due to "", attempt %s of {}.'.format(instance.ref.pk, instance.ref.name, max_tries)) for i in range(1, 1 + max_tries): self.assertIn( base_log_text % i, cm.output, )
def test_provision_s3_unconfigured(self, mock_consul): """ Test s3 provisioning works with default bucket and IAM """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_bucket_name = instance.bucket_name # For stubbing to work correctly with S3Stubber(s3_client) as stubber, IAMStubber( iam_client) as iamstubber: iamstubber.stub_create_user(instance.iam_username) iamstubber.stub_create_access_key(instance.iam_username) iamstubber.stub_put_user_policy(instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy()) stubber.stub_create_bucket(bucket=instance.s3_bucket_name, location='') stubber.stub_put_cors(bucket=instance.s3_bucket_name) stubber.stub_set_expiration(bucket=instance.s3_bucket_name) stubber.stub_versioning(bucket=instance.s3_bucket_name) instance.provision_s3() instance.refresh_from_db() self.assertIsNotNone(instance.s3_bucket_name) self.assertIsNotNone(instance.s3_access_key) self.assertIsNotNone(instance.s3_secret_access_key) self.assertEqual(instance.s3_region, settings.AWS_S3_DEFAULT_REGION) self.assertEqual(instance.s3_hostname, settings.AWS_S3_DEFAULT_HOSTNAME)
def test_provision_s3(self, provision_iam, mock_consul): """ Test s3 provisioning succeeds """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_bucket_name = 'test' instance.s3_region = 'test' if not provision_iam: instance.s3_access_key = 'test' instance.s3_secret_access_key = 'test' with S3Stubber(s3_client) as stubber, IAMStubber( iam_client) as iamstubber: if provision_iam: iamstubber.stub_create_user(instance.iam_username) iamstubber.stub_create_access_key(instance.iam_username) iamstubber.stub_put_user_policy(instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy()) stubber.stub_create_bucket() stubber.stub_put_cors() stubber.stub_set_expiration() stubber.stub_versioning() instance.provision_s3()
def test_deprovision_s3_delete_user_fails(self): """ Test s3 deprovisioning fails on delete_user """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_access_key = 'test_0123456789a' instance.s3_secret_access_key = 'test' instance.s3_bucket_name = 'test' with self.assertLogs("instance.models.instance"): with S3Stubber(s3_client) as stubber, IAMStubber(iam_client) as iamstubber: iamstubber.stub_put_user_policy( instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy() ) stubber.stub_create_bucket(location='') stubber.stub_put_cors() stubber.stub_set_expiration() stubber.stub_versioning() instance.provision_s3() stubber.stub_list_object_versions(result={}) stubber.stub_delete_bucket() iamstubber.stub_delete_access_key(instance.iam_username, instance.s3_access_key) iamstubber.stub_delete_user_policy(instance.iam_username) iamstubber.add_client_error('delete_user') instance.deprovision_s3() # Since it failed deleting the user, access_keys should not be empty instance.refresh_from_db() self.assertEqual(instance.s3_access_key, "test_0123456789a") self.assertEqual(instance.s3_secret_access_key, "test")
def test_deprovision_s3_delete_bucket_fails(self, mock_consul): """ Test s3 deprovisioning fails on delete_bucket """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_access_key = 'test_0123456789a' instance.s3_secret_access_key = 'test' instance.s3_bucket_name = 'test' instance.s3_region = 'test' instance.save() with self.assertLogs("instance.models.instance"): with S3Stubber(s3_client) as stubber, IAMStubber( iam_client) as iamstubber: iamstubber.stub_put_user_policy(instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy()) stubber.stub_create_bucket() stubber.stub_put_cors() stubber.stub_set_expiration() stubber.stub_versioning() instance.provision_s3() stubber.stub_list_object_versions(result={}) stubber.add_client_error('delete_bucket') iamstubber.stub_delete_access_key(instance.iam_username, instance.s3_access_key) iamstubber.stub_delete_user_policy(instance.iam_username) iamstubber.stub_delete_user(instance.iam_username) with self.assertRaises(ClientError): instance.deprovision_s3() instance.refresh_from_db() # Since it failed deleting the bucket, all S3 related information should be left intact. self.assertEqual(instance.s3_bucket_name, "test") self.assertEqual(instance.s3_region, "test") self.assertEqual(instance.s3_access_key, "test_0123456789a") self.assertEqual(instance.s3_secret_access_key, "test")
def test_deprovision_s3_user_does_not_exist(self, mock_consul): """ Test s3 deprovisioning when AIM user does not exist """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_access_key = 'test_0123456789a' instance.s3_secret_access_key = 'test' instance.s3_bucket_name = 'test' instance.save() with self.assertLogs("instance.models.instance"): with S3Stubber(s3_client) as stubber, IAMStubber( iam_client) as iamstubber: iamstubber.stub_put_user_policy(instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy()) stubber.stub_create_bucket(location='') stubber.stub_put_cors() stubber.stub_set_expiration() stubber.stub_versioning() instance.provision_s3() stubber.stub_list_object_versions(result={}) stubber.stub_delete_bucket() iamstubber.add_client_error('delete_access_key', service_error_code='NoSuchEntity') iamstubber.add_client_error('delete_user_policy', service_error_code='NoSuchEntity') iamstubber.add_client_error('delete_user', service_error_code='NoSuchEntity') instance.deprovision_s3() # Since the user and associated acess key and policy don't exist, # the fields should be blanked out. instance.refresh_from_db() self.assertEqual(instance.s3_access_key, "") self.assertEqual(instance.s3_secret_access_key, "")
def test_deprovision_s3(self, mock_consul): """ Test s3 deprovisioning succeeds """ instance = OpenEdXInstanceFactory() instance.storage_type = StorageContainer.S3_STORAGE instance.s3_access_key = 'test_0123456789a' instance.s3_secret_access_key = 'test' instance.s3_bucket_name = 'test' instance.s3_region = 'test' instance.save() with S3Stubber(s3_client) as stubber, IAMStubber( iam_client) as iamstubber: iamstubber.stub_put_user_policy(instance.iam_username, storage.USER_POLICY_NAME, instance.get_s3_policy()) stubber.stub_create_bucket() stubber.stub_put_cors() stubber.stub_set_expiration() stubber.stub_versioning() instance.provision_s3() # Put an object stubber.stub_put_object(b'test', 'test') s3_client.put_object(Body=b'test', Bucket='test', Key='test') # Overwrite object stubber.stub_put_object(b'another_test', 'test') s3_client.put_object(Body=b'another_test', Bucket='test', Key='test') # Put another object stubber.stub_put_object(b'another_test', 'another_test') s3_client.put_object(Body=b'another_test', Bucket='test', Key='another_test') # Delete object stubber.stub_delete_object(key='another_test') s3_client.delete_object(Bucket='test', Key='another_test') # Make sure three versions and a delete marker are removed items = { 'Versions': [{ 'Key': 'test', 'VersionId': '1a' }, { 'Key': 'test', 'VersionId': '2b' }, { 'Key': 'another_test', 'VersionId': '3c' }], 'DeleteMarkers': [{ 'Key': 'another_test', 'VersionId': '4d' }] } stubber.stub_list_object_versions(result=items) stubber.add_response('delete_objects', {}, { 'Bucket': 'test', 'Delete': { 'Objects': [{ 'Key': d['Key'], 'VersionId': d['VersionId'] } for d in items['Versions'] + items['DeleteMarkers']] } }) stubber.stub_list_object_versions(result={}) stubber.stub_delete_bucket() iamstubber.stub_delete_access_key(instance.iam_username, instance.s3_access_key) iamstubber.stub_delete_user_policy(instance.iam_username) iamstubber.stub_delete_user(instance.iam_username) instance.deprovision_s3() instance.refresh_from_db() self.assertEqual(instance.s3_bucket_name, "") self.assertEqual(instance.s3_access_key, "") self.assertEqual(instance.s3_secret_access_key, "") # We always want to preserve information about a client's preferred region, so s3_region should not be empty. self.assertEqual(instance.s3_region, "test")