2023-08-07 16:48:48 +00:00
|
|
|
from uuid import uuid4
|
|
|
|
|
2021-10-16 17:26:09 +00:00
|
|
|
import boto3
|
|
|
|
import pytest
|
2023-11-30 15:55:51 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
from moto import mock_s3
|
|
|
|
|
|
|
|
DEFAULT_REGION_NAME = "us-east-1"
|
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_get_bucket_replication_for_unexisting_bucket():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2021-10-16 17:26:09 +00:00
|
|
|
with pytest.raises(ClientError) as exc:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.get_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
err = exc.value.response["Error"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["Code"] == "NoSuchBucket"
|
|
|
|
assert err["Message"] == "The specified bucket does not exist"
|
|
|
|
assert err["BucketName"] == bucket_name
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_get_bucket_replication_bucket_without_replication():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.get_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
err = exc.value.response["Error"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["Code"] == "ReplicationConfigurationNotFoundError"
|
|
|
|
assert err["Message"] == "The replication configuration was not found"
|
|
|
|
assert err["BucketName"] == bucket_name
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_delete_bucket_replication_unknown_bucket():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2021-10-16 17:26:09 +00:00
|
|
|
with pytest.raises(ClientError) as exc:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.delete_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
err = exc.value.response["Error"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["Code"] == "NoSuchBucket"
|
|
|
|
assert err["Message"] == "The specified bucket does not exist"
|
|
|
|
assert err["BucketName"] == bucket_name
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_delete_bucket_replication_bucket_without_replication():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
# No-op
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.delete_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_create_replication_without_versioning():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_replication(
|
2021-10-16 17:26:09 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
ReplicationConfiguration={
|
|
|
|
"Role": "myrole",
|
|
|
|
"Rules": [
|
|
|
|
{"Destination": {"Bucket": "secondbucket"}, "Status": "Enabled"}
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["Code"] == "InvalidRequest"
|
|
|
|
assert err["Message"] == (
|
2021-10-16 17:26:09 +00:00
|
|
|
"Versioning must be 'Enabled' on the bucket to apply a replication configuration"
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["BucketName"] == bucket_name
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_create_and_retrieve_replication_with_single_rules():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
s3_client.put_bucket_versioning(
|
2021-10-16 17:26:09 +00:00
|
|
|
Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"}
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_replication(
|
2021-10-16 17:26:09 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
ReplicationConfiguration={
|
|
|
|
"Role": "myrole",
|
|
|
|
"Rules": [
|
|
|
|
{
|
|
|
|
"ID": "firstrule",
|
|
|
|
"Priority": 2,
|
|
|
|
"Destination": {"Bucket": "secondbucket"},
|
|
|
|
"Status": "Enabled",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
config = s3_client.get_bucket_replication(Bucket=bucket_name)[
|
|
|
|
"ReplicationConfiguration"
|
|
|
|
]
|
|
|
|
assert config == {
|
|
|
|
"Role": "myrole",
|
|
|
|
"Rules": [
|
|
|
|
{
|
|
|
|
"DeleteMarkerReplication": {"Status": "Disabled"},
|
|
|
|
"Destination": {"Bucket": "secondbucket"},
|
|
|
|
"Filter": {"Prefix": ""},
|
|
|
|
"ID": "firstrule",
|
|
|
|
"Priority": 2,
|
|
|
|
"Status": "Enabled",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
s3_client.delete_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
# Can't retrieve replication that has been deleted
|
|
|
|
with pytest.raises(ClientError) as exc:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.get_bucket_replication(Bucket=bucket_name)
|
2021-10-16 17:26:09 +00:00
|
|
|
err = exc.value.response["Error"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert err["Code"] == "ReplicationConfigurationNotFoundError"
|
|
|
|
assert err["Message"] == "The replication configuration was not found"
|
|
|
|
assert err["BucketName"] == bucket_name
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_s3
|
|
|
|
def test_create_and_retrieve_replication_with_multiple_rules():
|
|
|
|
bucket_name = str(uuid4())
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2021-10-16 17:26:09 +00:00
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
s3_client.put_bucket_versioning(
|
2021-10-16 17:26:09 +00:00
|
|
|
Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"}
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_replication(
|
2021-10-16 17:26:09 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
ReplicationConfiguration={
|
|
|
|
"Role": "myrole",
|
|
|
|
"Rules": [
|
|
|
|
{"Destination": {"Bucket": "secondbucket"}, "Status": "Enabled"},
|
|
|
|
{
|
|
|
|
"ID": "secondrule",
|
|
|
|
"Priority": 2,
|
|
|
|
"Destination": {"Bucket": "thirdbucket"},
|
|
|
|
"Status": "Disabled",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
config = s3_client.get_bucket_replication(Bucket=bucket_name)[
|
|
|
|
"ReplicationConfiguration"
|
|
|
|
]
|
|
|
|
assert config["Role"] == "myrole"
|
2021-10-16 17:26:09 +00:00
|
|
|
rules = config["Rules"]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert len(rules) == 2
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
first_rule = rules[0]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert "ID" in first_rule
|
|
|
|
assert first_rule["Priority"] == 1
|
|
|
|
assert first_rule["Status"] == "Enabled"
|
|
|
|
assert first_rule["Destination"] == {"Bucket": "secondbucket"}
|
2021-10-16 17:26:09 +00:00
|
|
|
|
|
|
|
second = rules[1]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert second["ID"] == "secondrule"
|
|
|
|
assert second["Priority"] == 2
|
|
|
|
assert second["Status"] == "Disabled"
|
|
|
|
assert second["Destination"] == {"Bucket": "thirdbucket"}
|