Я пишу тесты на Python, чтобы убедиться, что Amazon S3 (сервис в целом) работает должным образом.
Настройка: CodePipeline использует CodeBuild для создания корзины S3 с использованием шаблона CloudFormation, затем запускает другое задание CodeBuild для запуска тестов python для S3, созданного на предыдущем шаге.
Мне нужно написать тесты для этих двух требований:
"Unauthorized users shall receive a 403 response when attempting to modify an S3 bucket."
а также
"Authorized users shall be able to successfully access and modify an S3 bucket."
Второй тест не проблема, но я не уверен, как написать первый тест.
Мой вопрос: как я могу получить тест python для тестирования корзины S3 как неавторизованный пользователь? CodeBuild уже имеет разрешения на доступ к корзинам S3, поэтому я не уверен, как сделать так, чтобы тесты (которые запускаются с помощью CodeBuild) НЕ имели разрешения на доступ к ним и получение нужного мне 403.
Вот некоторые подробности, которые могут оказаться полезными:
Конвейер состоит из 4 этапов: источник, сборка, развертывание, проверка сборки и удаление. На этапе развертывания ведра S3, которые мне нужно протестировать, устанавливаются с использованием стека CloudFormation. На этапе buildtest я фактически запускаю эти тесты python, поэтому я полагаю, что именно здесь мне нужно будет реализовать решение этой проблемы.
В конце концов, весь этот процесс будет инициирован с помощью шаблона CloudFormation, который СОЗДАЕТ конвейер, в котором будут все эти фазы. Но сейчас он просто использует конвейер из Консоли AWS. Я упоминаю об этом только в том случае, если что-то возможно (или невозможно) из CloudFormation для выполнения этой работы, что может (не) быть доступно в CodeBuild.
К сожалению, у меня не так много кода на Python, которым я мог бы поделиться здесь, поскольку это первый тест, который мне нужно написать, и я понятия не имею, как к нему подойти. Но что я могу вам сказать, так это то, что я использую Boto3 и запускаю тесты с помощью unittest. Я нахожу сегменты, проверяя текущие стеки в CloudFormation и проверяя, какой из них соответствует имени тестового стека, а затем беру ресурс S3 из этого стека. Это ведро, которое я тестирую. Так или иначе, мне нужно увидеть это ведро, попытаться получить к нему доступ и получить отказ в одном тесте, а затем получить доступ в другом тесте.
#python 3.6
import os
import boto3
import unittest
rootstack = os.getenv('RootStackName') # environment variable in the build
region = 'us-west-2'
buckets = {}
class TestS3(unittest.TestCase):
def setUp(self):
self.customBucket = None
self.customBucket = buckets['customBucket']
if self.customBucket is None:
raise ValueError('Test bucket not found in test setUp!')
def test_bucket_accessible_if_authorized(self):
# Authorized user can access the bucket
self.assertEqual(????)
def test_bucket_cant_be_accessed_if_unauthorized(self):
# Unauthorized user CANNOT access the bucket
self.assertEqual(????)
if __name__=='__main__':
try:
cfn = boto3.client('cloudformation', region_name=region)
response = cfn.describe_stack_resources(StackName=rootstack)
resources = response['StackResources']
for resource in resources:
if resource['ResourceType'] == 'AWS::S3::Bucket':
print('FOUND THE CUSTOM BUCKET')
buckets['customBucket'] = resource
unittest.main(verbosity=2)
except Exception as e:
print("Unknown Error, %s" %(e))
Я не уверен, что вы имеете в виду, говоря о создании другого соединения. это что-то, что я написал бы на Python или конфигурацию где-нибудь в CodeBuild?
Вы говорите о тестах Python для доступа к AWS S3. Эти тесты, вероятно, используют boto3, а вы просто инициализируете клиента с учетными данными по умолчанию из вашей среды. Однако вы можете принудительно указать определенные учетные данные в этом клиентском init. У вас может быть один с учетными данными по умолчанию, а другой - с конкретными. Поскольку в вашем вопросе нет подробностей, особенно кода, мы не можем быть более конкретными.
Вы правы в том, что я использую boto3, но я не выполняю эти тесты локально. Все это происходит в CodeBuild, который использует разрешения, предоставленные ему с его ролью IAM. Хм, возможно, мне следует просто сделать еще одну фазу конвейера, ту, которая даст этому второму проекту в CodeBuild другую роль. Это кажется неуклюжим решением - две совершенно разные фазы конвейера, просто чтобы обойти эту проблему. Я опубликую код, который кажется актуальным, но дайте мне знать, будет ли полезнее увидеть что-нибудь еще.





В итоге я решил просто изменить учетные данные в коде, прежде чем пытаться получить доступ к корзинам и объектам S3. Если я получил AccessDenied, это подтверждает, что безопасность работает должным образом.
Например:
def test_unauthorized_read(self):
# unauthorized users will 'Access Denied' if attempting to list the S3 bucket
cantListBuckets = False
# the user assigned in the next line has NO permissions to access any service
client = boto3.client(service_name='s3',
aws_access_key_id='AKIBI6SPIAUZ6LTGA4BQ',
aws_secret_access_key='HyqAJOXgqt6kCOSay/2eH6J3FYcbwjNTjTyhtHOQ'
)
try:
buckets = client.list_buckets()
except botocore.exceptions.ClientError as e:
if 'AccessDenied' in str(e):
cantListBuckets = True
self.assertTrue(cantListBuckets)
Не идеально ... не стесняйтесь публиковать лучшие подходы.
не лучшая идея оставлять ключ в почте
Разве вы не можете создать другое соединение и заменить учетные данные другим набором, у которого нет доступа к вашему S3?