77dc60ea97
This just eliminates all errors on the tests collection. Elimination of failures is left to the next commit.
382 lines
13 KiB
Python
382 lines
13 KiB
Python
import time
|
|
from datetime import datetime
|
|
|
|
import boto3
|
|
import sure # noqa
|
|
from botocore.exceptions import ClientError
|
|
import pytest
|
|
|
|
from moto import mock_ram, mock_organizations
|
|
from moto.core import ACCOUNT_ID
|
|
|
|
|
|
@mock_ram
|
|
def test_create_resource_share():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# when
|
|
response = client.create_resource_share(name="test")
|
|
|
|
# then
|
|
resource = response["resourceShare"]
|
|
resource["allowExternalPrincipals"].should.be.ok
|
|
resource["creationTime"].should.be.a(datetime)
|
|
resource["lastUpdatedTime"].should.be.a(datetime)
|
|
resource["name"].should.equal("test")
|
|
resource["owningAccountId"].should.equal(ACCOUNT_ID)
|
|
resource["resourceShareArn"].should.match(
|
|
r"arn:aws:ram:us-east-1:\d{12}:resource-share/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
)
|
|
resource["status"].should.equal("ACTIVE")
|
|
resource.should_not.have.key("featureSet")
|
|
|
|
# creating a resource share with the name should result in a second one
|
|
# not overwrite/update the old one
|
|
# when
|
|
response = client.create_resource_share(
|
|
name="test",
|
|
allowExternalPrincipals=False,
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(ACCOUNT_ID)
|
|
],
|
|
)
|
|
|
|
# then
|
|
resource = response["resourceShare"]
|
|
resource["allowExternalPrincipals"].should_not.be.ok
|
|
resource["creationTime"].should.be.a(datetime)
|
|
resource["lastUpdatedTime"].should.be.a(datetime)
|
|
resource["name"].should.equal("test")
|
|
resource["owningAccountId"].should.equal(ACCOUNT_ID)
|
|
resource["resourceShareArn"].should.match(
|
|
r"arn:aws:ram:us-east-1:\d{12}:resource-share/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
)
|
|
resource["status"].should.equal("ACTIVE")
|
|
|
|
response = client.get_resource_shares(resourceOwner="SELF")
|
|
response["resourceShares"].should.have.length_of(2)
|
|
|
|
|
|
@mock_ram
|
|
def test_create_resource_share_errors():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# invalid ARN
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_resource_share(name="test", resourceArns=["inalid-arn"])
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("CreateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("MalformedArnException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"The specified resource ARN inalid-arn is not valid. "
|
|
"Verify the ARN and try again."
|
|
)
|
|
|
|
# valid ARN, but not shareable resource type
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_resource_share(
|
|
name="test", resourceArns=["arn:aws:iam::{}:role/test".format(ACCOUNT_ID)]
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("CreateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("MalformedArnException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"You cannot share the selected resource type."
|
|
)
|
|
|
|
# invalid principal ID
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_resource_share(
|
|
name="test",
|
|
principals=["invalid"],
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(
|
|
ACCOUNT_ID
|
|
)
|
|
],
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("CreateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("InvalidParameterException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"Principal ID invalid is malformed. Verify the ID and try again."
|
|
)
|
|
|
|
|
|
@mock_ram
|
|
@mock_organizations
|
|
def test_create_resource_share_with_organization():
|
|
# given
|
|
client = boto3.client("organizations", region_name="us-east-1")
|
|
org_arn = client.create_organization(FeatureSet="ALL")["Organization"]["Arn"]
|
|
root_id = client.list_roots()["Roots"][0]["Id"]
|
|
ou_arn = client.create_organizational_unit(ParentId=root_id, Name="test")[
|
|
"OrganizationalUnit"
|
|
]["Arn"]
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# share in whole Organization
|
|
# when
|
|
response = client.create_resource_share(
|
|
name="test",
|
|
principals=[org_arn],
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(ACCOUNT_ID)
|
|
],
|
|
)
|
|
|
|
# then
|
|
response["resourceShare"]["name"].should.equal("test")
|
|
|
|
# share in an OU
|
|
# when
|
|
response = client.create_resource_share(
|
|
name="test",
|
|
principals=[ou_arn],
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(ACCOUNT_ID)
|
|
],
|
|
)
|
|
|
|
# then
|
|
response["resourceShare"]["name"].should.equal("test")
|
|
|
|
|
|
@mock_ram
|
|
@mock_organizations
|
|
def test_create_resource_share_with_organization_errors():
|
|
# given
|
|
client = boto3.client("organizations", region_name="us-east-1")
|
|
client.create_organization(FeatureSet="ALL")
|
|
root_id = client.list_roots()["Roots"][0]["Id"]
|
|
client.create_organizational_unit(ParentId=root_id, Name="test")
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# unknown Organization
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_resource_share(
|
|
name="test",
|
|
principals=[
|
|
"arn:aws:organizations::{}:organization/o-unknown".format(ACCOUNT_ID)
|
|
],
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(
|
|
ACCOUNT_ID
|
|
)
|
|
],
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("CreateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("UnknownResourceException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"Organization o-unknown could not be found."
|
|
)
|
|
|
|
# unknown OU
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_resource_share(
|
|
name="test",
|
|
principals=[
|
|
"arn:aws:organizations::{}:ou/o-unknown/ou-unknown".format(ACCOUNT_ID)
|
|
],
|
|
resourceArns=[
|
|
"arn:aws:ec2:us-east-1:{}:transit-gateway/tgw-123456789".format(
|
|
ACCOUNT_ID
|
|
)
|
|
],
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("CreateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("UnknownResourceException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"OrganizationalUnit ou-unknown in unknown organization could not be found."
|
|
)
|
|
|
|
|
|
@mock_ram
|
|
def test_get_resource_shares():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
client.create_resource_share(name="test")
|
|
|
|
# when
|
|
response = client.get_resource_shares(resourceOwner="SELF")
|
|
|
|
# then
|
|
response["resourceShares"].should.have.length_of(1)
|
|
resource = response["resourceShares"][0]
|
|
resource["allowExternalPrincipals"].should.be.ok
|
|
resource["creationTime"].should.be.a(datetime)
|
|
resource["featureSet"].should.equal("STANDARD")
|
|
resource["lastUpdatedTime"].should.be.a(datetime)
|
|
resource["name"].should.equal("test")
|
|
resource["owningAccountId"].should.equal(ACCOUNT_ID)
|
|
resource["resourceShareArn"].should.match(
|
|
r"arn:aws:ram:us-east-1:\d{12}:resource-share/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
)
|
|
resource["status"].should.equal("ACTIVE")
|
|
|
|
|
|
@mock_ram
|
|
def test_get_resource_shares_errors():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# invalid resource owner
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.get_resource_shares(resourceOwner="invalid")
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("GetResourceShares")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("InvalidParameterException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"invalid is not a valid resource owner. "
|
|
"Specify either SELF or OTHER-ACCOUNTS and try again."
|
|
)
|
|
|
|
|
|
@mock_ram
|
|
def test_update_resource_share():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
arn = client.create_resource_share(name="test")["resourceShare"]["resourceShareArn"]
|
|
|
|
# when
|
|
time.sleep(0.1)
|
|
response = client.update_resource_share(resourceShareArn=arn, name="test-update")
|
|
|
|
# then
|
|
resource = response["resourceShare"]
|
|
resource["allowExternalPrincipals"].should.be.ok
|
|
resource["name"].should.equal("test-update")
|
|
resource["owningAccountId"].should.equal(ACCOUNT_ID)
|
|
resource["resourceShareArn"].should.match(
|
|
r"arn:aws:ram:us-east-1:\d{12}:resource-share/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
)
|
|
resource["status"].should.equal("ACTIVE")
|
|
resource.should_not.have.key("featureSet")
|
|
creation_time = resource["creationTime"]
|
|
resource["lastUpdatedTime"].should.be.greater_than(creation_time)
|
|
|
|
response = client.get_resource_shares(resourceOwner="SELF")
|
|
response["resourceShares"].should.have.length_of(1)
|
|
|
|
|
|
@mock_ram
|
|
def test_update_resource_share_errors():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# invalid resource owner
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.update_resource_share(
|
|
resourceShareArn="arn:aws:ram:us-east-1:{}:resource-share/not-existing".format(
|
|
ACCOUNT_ID
|
|
),
|
|
name="test-update",
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("UpdateResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("UnknownResourceException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"ResourceShare arn:aws:ram:us-east-1:{}:resource-share/not-existing could not be found.".format(
|
|
ACCOUNT_ID
|
|
)
|
|
)
|
|
|
|
|
|
@mock_ram
|
|
def test_delete_resource_share():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
arn = client.create_resource_share(name="test")["resourceShare"]["resourceShareArn"]
|
|
|
|
# when
|
|
time.sleep(0.1)
|
|
response = client.delete_resource_share(resourceShareArn=arn)
|
|
|
|
# then
|
|
response["returnValue"].should.be.ok
|
|
|
|
response = client.get_resource_shares(resourceOwner="SELF")
|
|
response["resourceShares"].should.have.length_of(1)
|
|
resource = response["resourceShares"][0]
|
|
resource["status"].should.equal("DELETED")
|
|
creation_time = resource["creationTime"]
|
|
resource["lastUpdatedTime"].should.be.greater_than(creation_time)
|
|
|
|
|
|
@mock_ram
|
|
def test_delete_resource_share_errors():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# invalid resource owner
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.delete_resource_share(
|
|
resourceShareArn="arn:aws:ram:us-east-1:{}:resource-share/not-existing".format(
|
|
ACCOUNT_ID
|
|
)
|
|
)
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("DeleteResourceShare")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("UnknownResourceException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"ResourceShare arn:aws:ram:us-east-1:{}:resource-share/not-existing could not be found.".format(
|
|
ACCOUNT_ID
|
|
)
|
|
)
|
|
|
|
|
|
@mock_ram
|
|
@mock_organizations
|
|
def test_enable_sharing_with_aws_organization():
|
|
# given
|
|
client = boto3.client("organizations", region_name="us-east-1")
|
|
client.create_organization(FeatureSet="ALL")
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# when
|
|
response = client.enable_sharing_with_aws_organization()
|
|
|
|
# then
|
|
response["returnValue"].should.be.ok
|
|
|
|
|
|
@mock_ram
|
|
@mock_organizations
|
|
def test_enable_sharing_with_aws_organization_errors():
|
|
# given
|
|
client = boto3.client("ram", region_name="us-east-1")
|
|
|
|
# no Organization defined
|
|
# when
|
|
with pytest.raises(ClientError) as e:
|
|
client.enable_sharing_with_aws_organization()
|
|
ex = e.exception
|
|
ex.operation_name.should.equal("EnableSharingWithAwsOrganization")
|
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
|
ex.response["Error"]["Code"].should.contain("OperationNotPermittedException")
|
|
ex.response["Error"]["Message"].should.equal(
|
|
"Unable to enable sharing with AWS Organizations. "
|
|
"Received AccessDeniedException from AWSOrganizations with the following error message: "
|
|
"You don't have permissions to access this resource."
|
|
)
|