Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0527e88d46
541 changed files with 75504 additions and 51429 deletions
|
|
@ -1,8 +1,9 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
# Disable extra logging for tests
|
||||
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('boto3').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('botocore').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('nose').setLevel(logging.CRITICAL)
|
||||
logging.getLogger("boto").setLevel(logging.CRITICAL)
|
||||
logging.getLogger("boto3").setLevel(logging.CRITICAL)
|
||||
logging.getLogger("botocore").setLevel(logging.CRITICAL)
|
||||
logging.getLogger("nose").setLevel(logging.CRITICAL)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
"""
|
||||
Patch courtesy of:
|
||||
https://marmida.com/blog/index.php/2012/08/08/monkey-patching-assert_raises/
|
||||
|
|
@ -19,7 +20,6 @@ try:
|
|||
except TypeError:
|
||||
# this version of assert_raises doesn't support the 1-arg version
|
||||
class AssertRaisesContext(object):
|
||||
|
||||
def __init__(self, expected):
|
||||
self.expected = expected
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ class requires_boto_gte(object):
|
|||
|
||||
|
||||
class disable_on_py3(object):
|
||||
|
||||
def __call__(self, test):
|
||||
if not six.PY3:
|
||||
return test
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEUDCCAjgCCQDfXZHMio+6oDANBgkqhkiG9w0BAQ0FADBjMQswCQYDVQQGEwJH
|
||||
MIIEUDCCAjgCCQDfXZHMio+6oDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJH
|
||||
QjESMBAGA1UECAwJQmVya3NoaXJlMQ8wDQYDVQQHDAZTbG91Z2gxEzARBgNVBAoM
|
||||
Ck1vdG9TZXJ2ZXIxCzAJBgNVBAsMAlFBMQ0wCwYDVQQDDARNb3RvMB4XDTE3MDky
|
||||
MTIxMjQ1MFoXDTI3MDkxOTIxMjQ1MFowcTELMAkGA1UEBhMCR0IxEjAQBgNVBAgM
|
||||
Ck1vdG9TZXJ2ZXIxCzAJBgNVBAsMAlFBMQ0wCwYDVQQDDARNb3RvMB4XDTE5MTAy
|
||||
MTEzMjczMVoXDTQ5MTIzMTEzMjczNFowcTELMAkGA1UEBhMCR0IxEjAQBgNVBAgM
|
||||
CUJlcmtzaGlyZTEPMA0GA1UEBwwGU2xvdWdoMRMwEQYDVQQKDApNb3RvU2VydmVy
|
||||
MRMwEQYDVQQLDApPcGVyYXRpb25zMRMwEQYDVQQDDAoqLm1vdG8uY29tMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzC/oBkzwiIBEceSC/tSD7hkqs8AW
|
||||
|
|
@ -11,16 +11,16 @@ niDXbMgAQE9oxUxtkFESxiNa+EbAMLBFtBkPRvc3iKXh/cfLo7yP8VdqEIDmJCB/
|
|||
vpjJvf6HnrNJ7keQR+oGJNf7jVaCgOVdJ4lt7+98YDVde7jLx1DN+QbvViJQl60n
|
||||
K3bmfuLiiw8154Eyi9DOcJE8AB+W7KpPdrmbPisR1EiqY0i0L62ZixN0rPi5hHF+
|
||||
ozwURL1axcmLjlhIFi8YhBCNcY6ThE7jrqgLIq1n6d8ezRxjDKmqfH1spQIDAQAB
|
||||
MA0GCSqGSIb3DQEBDQUAA4ICAQCgl/EfjE0Jh3cqQgoOlaFq6L1iJVgy5sYKCC4r
|
||||
OU4dHgifZ6/grqCJesGiS1Vh4L8XklN++C2aSL73lVtxXoCSopP8Yj0rOGeA6b+7
|
||||
Fetm4ZQYF61QtahC0L2fkvKXR+uz1I85ndSoMJPT8lbm7sYJuL81Si32NOo6kC6y
|
||||
4eKzV4KznxdAf6XaQMKtMIyXO3PWTrjm5ayzS6UsmnBvULGDCaAQznFlVFdGNSHx
|
||||
CaENICR0CBcB+vbL7FPC683a4afceM+aMcMVElWG5q8fxtgbL/aPhzfonhDGWOM4
|
||||
Rdg8x+yDdi7swxmWlcW5wlP8LpLxN/S3GR9j9IyelxUGmb20yTph3i1K6RM/Fm2W
|
||||
PI8xdneA6qycUAJo93NfaCuNK7yBfK3uDLqmWlGh3xCG+I1JETLRbxYBWiqeVTb3
|
||||
qjHMrsgqTqjcaCiKR/5H2eVkdcr8mLxrV5niyBItDl1xGxj4LF8hDLormhaCjiBb
|
||||
N1cMq5saj/BpoIanlqOWby6uRMYlZvuhwKQGPVWgfuRWKFzGbMWyPCxATbiU89Wb
|
||||
IykNkT1zTCE/eZwH12T4A7jrBiWq8WNfIST0Z7MReE6Oz+M9Pxx7DyDzSb2Y1RmU
|
||||
xNYd8CavZLCfns00xZSo+10deMoKVS9GgxSHcS4ELaVaBQwu35emiMJSLcK7iNGE
|
||||
I4WVSA==
|
||||
MA0GCSqGSIb3DQEBCwUAA4ICAQAOwvJjY1cLIBVGCDPkkxH4xCP6+QRdm7bqF7X5
|
||||
DNZ70YcJ27GldrEPmKX8C1RvkC4oCsaytl8Hlw3ZcS1GvwBxTVlnYIE6nLPPi1ix
|
||||
LvYYgoq+Mjk/2XPCnU/6cqJhb5INskg9s0o15jv27cUIgWVMnj+d5lvSiy1HhdYM
|
||||
wvuQzXELjhe/rHw1/BFGaBV2vd7einUQwla50UZLcsj6FwWSIsv7EB4GaY/G0XqC
|
||||
Mai2PltBgBPFqsZo27uBeVfxqMZtwAQlr4iWwWZm1haDy6D4GFCSR8E/gtlyhiN4
|
||||
MOk1cmr9PSOMB3CWqKjkx7lPMOQT/f+gxlCnupNHsHcZGvQV4mCPiU+lLwp+8z/s
|
||||
bupQwRvu1SwSUD2rIsVeUuSP3hbMcfhiZA50lenQNApimgrThdPUoFXi07FUdL+F
|
||||
1QCk6cvA48KzGRo+bPSfZQusj51k/2+hl4sHHZdWg6mGAIY9InMKmPDE4VzM8hro
|
||||
fr2fJLqKQ4h+xKbEYnvPEPttUdJbvUgr9TKKVw+m3lmW9SktzE5KtvWvN6daTj9Z
|
||||
oHDJkOyko3uyTzk+HwWDC/pQ2cC+iF1MjIHi72U9ibObSODg/d9cMH3XJTnZ9W3+
|
||||
He9iuH4dJpKnVjnJ5NKt7IOrPHID77160hpwF1dim22ZRp508eYapRzgawPMpCcd
|
||||
a6YipQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
|||
|
|
@ -9,112 +9,109 @@ import uuid
|
|||
from botocore.exceptions import ClientError
|
||||
|
||||
from moto import mock_acm
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
|
||||
RESOURCE_FOLDER = os.path.join(os.path.dirname(__file__), 'resources')
|
||||
_GET_RESOURCE = lambda x: open(os.path.join(RESOURCE_FOLDER, x), 'rb').read()
|
||||
CA_CRT = _GET_RESOURCE('ca.pem')
|
||||
CA_KEY = _GET_RESOURCE('ca.key')
|
||||
SERVER_CRT = _GET_RESOURCE('star_moto_com.pem')
|
||||
SERVER_COMMON_NAME = '*.moto.com'
|
||||
SERVER_CRT_BAD = _GET_RESOURCE('star_moto_com-bad.pem')
|
||||
SERVER_KEY = _GET_RESOURCE('star_moto_com.key')
|
||||
BAD_ARN = 'arn:aws:acm:us-east-2:123456789012:certificate/_0000000-0000-0000-0000-000000000000'
|
||||
RESOURCE_FOLDER = os.path.join(os.path.dirname(__file__), "resources")
|
||||
_GET_RESOURCE = lambda x: open(os.path.join(RESOURCE_FOLDER, x), "rb").read()
|
||||
CA_CRT = _GET_RESOURCE("ca.pem")
|
||||
CA_KEY = _GET_RESOURCE("ca.key")
|
||||
SERVER_CRT = _GET_RESOURCE("star_moto_com.pem")
|
||||
SERVER_COMMON_NAME = "*.moto.com"
|
||||
SERVER_CRT_BAD = _GET_RESOURCE("star_moto_com-bad.pem")
|
||||
SERVER_KEY = _GET_RESOURCE("star_moto_com.key")
|
||||
BAD_ARN = "arn:aws:acm:us-east-2:{}:certificate/_0000000-0000-0000-0000-000000000000".format(
|
||||
ACCOUNT_ID
|
||||
)
|
||||
|
||||
|
||||
def _import_cert(client):
|
||||
response = client.import_certificate(
|
||||
Certificate=SERVER_CRT,
|
||||
PrivateKey=SERVER_KEY,
|
||||
CertificateChain=CA_CRT
|
||||
Certificate=SERVER_CRT, PrivateKey=SERVER_KEY, CertificateChain=CA_CRT
|
||||
)
|
||||
return response['CertificateArn']
|
||||
return response["CertificateArn"]
|
||||
|
||||
|
||||
# Also tests GetCertificate
|
||||
@mock_acm
|
||||
def test_import_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
resp = client.import_certificate(
|
||||
Certificate=SERVER_CRT,
|
||||
PrivateKey=SERVER_KEY,
|
||||
CertificateChain=CA_CRT
|
||||
Certificate=SERVER_CRT, PrivateKey=SERVER_KEY, CertificateChain=CA_CRT
|
||||
)
|
||||
resp = client.get_certificate(CertificateArn=resp['CertificateArn'])
|
||||
resp = client.get_certificate(CertificateArn=resp["CertificateArn"])
|
||||
|
||||
resp['Certificate'].should.equal(SERVER_CRT.decode())
|
||||
resp.should.contain('CertificateChain')
|
||||
resp["Certificate"].should.equal(SERVER_CRT.decode())
|
||||
resp.should.contain("CertificateChain")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_import_bad_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.import_certificate(
|
||||
Certificate=SERVER_CRT_BAD,
|
||||
PrivateKey=SERVER_KEY,
|
||||
)
|
||||
client.import_certificate(Certificate=SERVER_CRT_BAD, PrivateKey=SERVER_KEY)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ValidationException')
|
||||
err.response["Error"]["Code"].should.equal("ValidationException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ValidationException')
|
||||
raise RuntimeError("Should of raised ValidationException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_list_certificates():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
resp = client.list_certificates()
|
||||
len(resp['CertificateSummaryList']).should.equal(1)
|
||||
len(resp["CertificateSummaryList"]).should.equal(1)
|
||||
|
||||
resp['CertificateSummaryList'][0]['CertificateArn'].should.equal(arn)
|
||||
resp['CertificateSummaryList'][0]['DomainName'].should.equal(SERVER_COMMON_NAME)
|
||||
resp["CertificateSummaryList"][0]["CertificateArn"].should.equal(arn)
|
||||
resp["CertificateSummaryList"][0]["DomainName"].should.equal(SERVER_COMMON_NAME)
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_list_certificates_by_status():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
issued_arn = _import_cert(client)
|
||||
pending_arn = client.request_certificate(DomainName='google.com')['CertificateArn']
|
||||
pending_arn = client.request_certificate(DomainName="google.com")["CertificateArn"]
|
||||
|
||||
resp = client.list_certificates()
|
||||
len(resp['CertificateSummaryList']).should.equal(2)
|
||||
resp = client.list_certificates(CertificateStatuses=['EXPIRED', 'INACTIVE'])
|
||||
len(resp['CertificateSummaryList']).should.equal(0)
|
||||
resp = client.list_certificates(CertificateStatuses=['PENDING_VALIDATION'])
|
||||
len(resp['CertificateSummaryList']).should.equal(1)
|
||||
resp['CertificateSummaryList'][0]['CertificateArn'].should.equal(pending_arn)
|
||||
len(resp["CertificateSummaryList"]).should.equal(2)
|
||||
resp = client.list_certificates(CertificateStatuses=["EXPIRED", "INACTIVE"])
|
||||
len(resp["CertificateSummaryList"]).should.equal(0)
|
||||
resp = client.list_certificates(CertificateStatuses=["PENDING_VALIDATION"])
|
||||
len(resp["CertificateSummaryList"]).should.equal(1)
|
||||
resp["CertificateSummaryList"][0]["CertificateArn"].should.equal(pending_arn)
|
||||
|
||||
resp = client.list_certificates(CertificateStatuses=['ISSUED'])
|
||||
len(resp['CertificateSummaryList']).should.equal(1)
|
||||
resp['CertificateSummaryList'][0]['CertificateArn'].should.equal(issued_arn)
|
||||
resp = client.list_certificates(CertificateStatuses=['ISSUED', 'PENDING_VALIDATION'])
|
||||
len(resp['CertificateSummaryList']).should.equal(2)
|
||||
arns = {cert['CertificateArn'] for cert in resp['CertificateSummaryList']}
|
||||
resp = client.list_certificates(CertificateStatuses=["ISSUED"])
|
||||
len(resp["CertificateSummaryList"]).should.equal(1)
|
||||
resp["CertificateSummaryList"][0]["CertificateArn"].should.equal(issued_arn)
|
||||
resp = client.list_certificates(
|
||||
CertificateStatuses=["ISSUED", "PENDING_VALIDATION"]
|
||||
)
|
||||
len(resp["CertificateSummaryList"]).should.equal(2)
|
||||
arns = {cert["CertificateArn"] for cert in resp["CertificateSummaryList"]}
|
||||
arns.should.contain(issued_arn)
|
||||
arns.should.contain(pending_arn)
|
||||
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_get_invalid_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.get_certificate(CertificateArn=BAD_ARN)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
# Also tests deleting invalid certificate
|
||||
@mock_acm
|
||||
def test_delete_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
# If it does not raise an error and the next call does, all is fine
|
||||
|
|
@ -123,222 +120,209 @@ def test_delete_certificate():
|
|||
try:
|
||||
client.delete_certificate(CertificateArn=arn)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_describe_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
resp = client.describe_certificate(CertificateArn=arn)
|
||||
resp['Certificate']['CertificateArn'].should.equal(arn)
|
||||
resp['Certificate']['DomainName'].should.equal(SERVER_COMMON_NAME)
|
||||
resp['Certificate']['Issuer'].should.equal('Moto')
|
||||
resp['Certificate']['KeyAlgorithm'].should.equal('RSA_2048')
|
||||
resp['Certificate']['Status'].should.equal('ISSUED')
|
||||
resp['Certificate']['Type'].should.equal('IMPORTED')
|
||||
resp["Certificate"]["CertificateArn"].should.equal(arn)
|
||||
resp["Certificate"]["DomainName"].should.equal(SERVER_COMMON_NAME)
|
||||
resp["Certificate"]["Issuer"].should.equal("Moto")
|
||||
resp["Certificate"]["KeyAlgorithm"].should.equal("RSA_2048")
|
||||
resp["Certificate"]["Status"].should.equal("ISSUED")
|
||||
resp["Certificate"]["Type"].should.equal("IMPORTED")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_describe_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.describe_certificate(CertificateArn=BAD_ARN)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
# Also tests ListTagsForCertificate
|
||||
@mock_acm
|
||||
def test_add_tags_to_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
client.add_tags_to_certificate(
|
||||
CertificateArn=arn,
|
||||
Tags=[
|
||||
{'Key': 'key1', 'Value': 'value1'},
|
||||
{'Key': 'key2'},
|
||||
]
|
||||
CertificateArn=arn, Tags=[{"Key": "key1", "Value": "value1"}, {"Key": "key2"}]
|
||||
)
|
||||
|
||||
resp = client.list_tags_for_certificate(CertificateArn=arn)
|
||||
tags = {item['Key']: item.get('Value', '__NONE__') for item in resp['Tags']}
|
||||
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
|
||||
|
||||
tags.should.contain('key1')
|
||||
tags.should.contain('key2')
|
||||
tags['key1'].should.equal('value1')
|
||||
tags.should.contain("key1")
|
||||
tags.should.contain("key2")
|
||||
tags["key1"].should.equal("value1")
|
||||
|
||||
# This way, it ensures that we can detect if None is passed back when it shouldnt,
|
||||
# as we store keys without values with a value of None, but it shouldnt be passed back
|
||||
tags['key2'].should.equal('__NONE__')
|
||||
tags["key2"].should.equal("__NONE__")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_add_tags_to_invalid_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.add_tags_to_certificate(
|
||||
CertificateArn=BAD_ARN,
|
||||
Tags=[
|
||||
{'Key': 'key1', 'Value': 'value1'},
|
||||
{'Key': 'key2'},
|
||||
]
|
||||
Tags=[{"Key": "key1", "Value": "value1"}, {"Key": "key2"}],
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_list_tags_for_invalid_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.list_tags_for_certificate(CertificateArn=BAD_ARN)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_remove_tags_from_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
client.add_tags_to_certificate(
|
||||
CertificateArn=arn,
|
||||
Tags=[
|
||||
{'Key': 'key1', 'Value': 'value1'},
|
||||
{'Key': 'key2'},
|
||||
{'Key': 'key3', 'Value': 'value3'},
|
||||
{'Key': 'key4', 'Value': 'value4'},
|
||||
]
|
||||
{"Key": "key1", "Value": "value1"},
|
||||
{"Key": "key2"},
|
||||
{"Key": "key3", "Value": "value3"},
|
||||
{"Key": "key4", "Value": "value4"},
|
||||
],
|
||||
)
|
||||
|
||||
client.remove_tags_from_certificate(
|
||||
CertificateArn=arn,
|
||||
Tags=[
|
||||
{'Key': 'key1', 'Value': 'value2'}, # Should not remove as doesnt match
|
||||
{'Key': 'key2'}, # Single key removal
|
||||
{'Key': 'key3', 'Value': 'value3'}, # Exact match removal
|
||||
{'Key': 'key4'} # Partial match removal
|
||||
]
|
||||
{"Key": "key1", "Value": "value2"}, # Should not remove as doesnt match
|
||||
{"Key": "key2"}, # Single key removal
|
||||
{"Key": "key3", "Value": "value3"}, # Exact match removal
|
||||
{"Key": "key4"}, # Partial match removal
|
||||
],
|
||||
)
|
||||
|
||||
resp = client.list_tags_for_certificate(CertificateArn=arn)
|
||||
tags = {item['Key']: item.get('Value', '__NONE__') for item in resp['Tags']}
|
||||
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
|
||||
|
||||
for key in ('key2', 'key3', 'key4'):
|
||||
for key in ("key2", "key3", "key4"):
|
||||
tags.should_not.contain(key)
|
||||
|
||||
tags.should.contain('key1')
|
||||
tags.should.contain("key1")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_remove_tags_from_invalid_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.remove_tags_from_certificate(
|
||||
CertificateArn=BAD_ARN,
|
||||
Tags=[
|
||||
{'Key': 'key1', 'Value': 'value1'},
|
||||
{'Key': 'key2'},
|
||||
]
|
||||
Tags=[{"Key": "key1", "Value": "value1"}, {"Key": "key2"}],
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_resend_validation_email():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
client.resend_validation_email(
|
||||
CertificateArn=arn,
|
||||
Domain='*.moto.com',
|
||||
ValidationDomain='NOTUSEDYET'
|
||||
CertificateArn=arn, Domain="*.moto.com", ValidationDomain="NOTUSEDYET"
|
||||
)
|
||||
# Returns nothing, boto would raise Exceptions otherwise
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_resend_validation_email_invalid():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
arn = _import_cert(client)
|
||||
|
||||
try:
|
||||
client.resend_validation_email(
|
||||
CertificateArn=arn,
|
||||
Domain='no-match.moto.com',
|
||||
ValidationDomain='NOTUSEDYET'
|
||||
Domain="no-match.moto.com",
|
||||
ValidationDomain="NOTUSEDYET",
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('InvalidDomainValidationOptionsException')
|
||||
err.response["Error"]["Code"].should.equal(
|
||||
"InvalidDomainValidationOptionsException"
|
||||
)
|
||||
else:
|
||||
raise RuntimeError('Should of raised InvalidDomainValidationOptionsException')
|
||||
raise RuntimeError("Should of raised InvalidDomainValidationOptionsException")
|
||||
|
||||
try:
|
||||
client.resend_validation_email(
|
||||
CertificateArn=BAD_ARN,
|
||||
Domain='no-match.moto.com',
|
||||
ValidationDomain='NOTUSEDYET'
|
||||
Domain="no-match.moto.com",
|
||||
ValidationDomain="NOTUSEDYET",
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
else:
|
||||
raise RuntimeError('Should of raised ResourceNotFoundException')
|
||||
raise RuntimeError("Should of raised ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_request_certificate():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
token = str(uuid.uuid4())
|
||||
|
||||
resp = client.request_certificate(
|
||||
DomainName='google.com',
|
||||
DomainName="google.com",
|
||||
IdempotencyToken=token,
|
||||
SubjectAlternativeNames=['google.com', 'www.google.com', 'mail.google.com'],
|
||||
SubjectAlternativeNames=["google.com", "www.google.com", "mail.google.com"],
|
||||
)
|
||||
resp.should.contain('CertificateArn')
|
||||
arn = resp['CertificateArn']
|
||||
resp.should.contain("CertificateArn")
|
||||
arn = resp["CertificateArn"]
|
||||
arn.should.match(r"arn:aws:acm:eu-central-1:\d{12}:certificate/")
|
||||
|
||||
resp = client.request_certificate(
|
||||
DomainName='google.com',
|
||||
DomainName="google.com",
|
||||
IdempotencyToken=token,
|
||||
SubjectAlternativeNames=['google.com', 'www.google.com', 'mail.google.com'],
|
||||
SubjectAlternativeNames=["google.com", "www.google.com", "mail.google.com"],
|
||||
)
|
||||
resp['CertificateArn'].should.equal(arn)
|
||||
resp["CertificateArn"].should.equal(arn)
|
||||
|
||||
|
||||
@mock_acm
|
||||
def test_request_certificate_no_san():
|
||||
client = boto3.client('acm', region_name='eu-central-1')
|
||||
client = boto3.client("acm", region_name="eu-central-1")
|
||||
|
||||
resp = client.request_certificate(
|
||||
DomainName='google.com'
|
||||
)
|
||||
resp.should.contain('CertificateArn')
|
||||
resp = client.request_certificate(DomainName="google.com")
|
||||
resp.should.contain("CertificateArn")
|
||||
|
||||
resp2 = client.describe_certificate(CertificateArn=resp["CertificateArn"])
|
||||
resp2.should.contain("Certificate")
|
||||
|
||||
resp2 = client.describe_certificate(
|
||||
CertificateArn=resp['CertificateArn']
|
||||
)
|
||||
resp2.should.contain('Certificate')
|
||||
|
||||
# # Also tests the SAN code
|
||||
# # requires Pull: https://github.com/spulec/freezegun/pull/210
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,88 +4,100 @@ import json
|
|||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
"""
|
||||
Test the different server responses
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
def test_list_apis():
|
||||
backend = server.create_backend_app('apigateway')
|
||||
backend = server.create_backend_app("apigateway")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get('/restapis')
|
||||
res = test_client.get("/restapis")
|
||||
res.data.should.equal(b'{"item": []}')
|
||||
|
||||
|
||||
def test_usage_plans_apis():
|
||||
backend = server.create_backend_app('apigateway')
|
||||
backend = server.create_backend_app("apigateway")
|
||||
test_client = backend.test_client()
|
||||
|
||||
# List usage plans (expect empty)
|
||||
res = test_client.get('/usageplans')
|
||||
res = test_client.get("/usageplans")
|
||||
json.loads(res.data)["item"].should.have.length_of(0)
|
||||
|
||||
# Create usage plan
|
||||
res = test_client.post('/usageplans', data=json.dumps({'name': 'test'}))
|
||||
res = test_client.post("/usageplans", data=json.dumps({"name": "test"}))
|
||||
created_plan = json.loads(res.data)
|
||||
created_plan['name'].should.equal('test')
|
||||
created_plan["name"].should.equal("test")
|
||||
|
||||
# List usage plans (expect 1 plan)
|
||||
res = test_client.get('/usageplans')
|
||||
res = test_client.get("/usageplans")
|
||||
json.loads(res.data)["item"].should.have.length_of(1)
|
||||
|
||||
# Get single usage plan
|
||||
res = test_client.get('/usageplans/{0}'.format(created_plan["id"]))
|
||||
res = test_client.get("/usageplans/{0}".format(created_plan["id"]))
|
||||
fetched_plan = json.loads(res.data)
|
||||
fetched_plan.should.equal(created_plan)
|
||||
|
||||
# Delete usage plan
|
||||
res = test_client.delete('/usageplans/{0}'.format(created_plan["id"]))
|
||||
res.data.should.equal(b'{}')
|
||||
res = test_client.delete("/usageplans/{0}".format(created_plan["id"]))
|
||||
res.data.should.equal(b"{}")
|
||||
|
||||
# List usage plans (expect empty again)
|
||||
res = test_client.get('/usageplans')
|
||||
res = test_client.get("/usageplans")
|
||||
json.loads(res.data)["item"].should.have.length_of(0)
|
||||
|
||||
|
||||
def test_usage_plans_keys():
|
||||
backend = server.create_backend_app('apigateway')
|
||||
backend = server.create_backend_app("apigateway")
|
||||
test_client = backend.test_client()
|
||||
usage_plan_id = 'test_plan_id'
|
||||
usage_plan_id = "test_plan_id"
|
||||
|
||||
# Create API key to be used in tests
|
||||
res = test_client.post('/apikeys', data=json.dumps({'name': 'test'}))
|
||||
res = test_client.post("/apikeys", data=json.dumps({"name": "test"}))
|
||||
created_api_key = json.loads(res.data)
|
||||
|
||||
# List usage plans keys (expect empty)
|
||||
res = test_client.get('/usageplans/{0}/keys'.format(usage_plan_id))
|
||||
res = test_client.get("/usageplans/{0}/keys".format(usage_plan_id))
|
||||
json.loads(res.data)["item"].should.have.length_of(0)
|
||||
|
||||
# Create usage plan key
|
||||
res = test_client.post('/usageplans/{0}/keys'.format(usage_plan_id), data=json.dumps({'keyId': created_api_key["id"], 'keyType': 'API_KEY'}))
|
||||
res = test_client.post(
|
||||
"/usageplans/{0}/keys".format(usage_plan_id),
|
||||
data=json.dumps({"keyId": created_api_key["id"], "keyType": "API_KEY"}),
|
||||
)
|
||||
created_usage_plan_key = json.loads(res.data)
|
||||
|
||||
# List usage plans keys (expect 1 key)
|
||||
res = test_client.get('/usageplans/{0}/keys'.format(usage_plan_id))
|
||||
res = test_client.get("/usageplans/{0}/keys".format(usage_plan_id))
|
||||
json.loads(res.data)["item"].should.have.length_of(1)
|
||||
|
||||
# Get single usage plan key
|
||||
res = test_client.get('/usageplans/{0}/keys/{1}'.format(usage_plan_id, created_api_key["id"]))
|
||||
res = test_client.get(
|
||||
"/usageplans/{0}/keys/{1}".format(usage_plan_id, created_api_key["id"])
|
||||
)
|
||||
fetched_plan_key = json.loads(res.data)
|
||||
fetched_plan_key.should.equal(created_usage_plan_key)
|
||||
|
||||
# Delete usage plan key
|
||||
res = test_client.delete('/usageplans/{0}/keys/{1}'.format(usage_plan_id, created_api_key["id"]))
|
||||
res.data.should.equal(b'{}')
|
||||
res = test_client.delete(
|
||||
"/usageplans/{0}/keys/{1}".format(usage_plan_id, created_api_key["id"])
|
||||
)
|
||||
res.data.should.equal(b"{}")
|
||||
|
||||
# List usage plans keys (expect to be empty again)
|
||||
res = test_client.get('/usageplans/{0}/keys'.format(usage_plan_id))
|
||||
res = test_client.get("/usageplans/{0}/keys".format(usage_plan_id))
|
||||
json.loads(res.data)["item"].should.have.length_of(0)
|
||||
|
||||
|
||||
def test_create_usage_plans_key_non_existent_api_key():
|
||||
backend = server.create_backend_app('apigateway')
|
||||
backend = server.create_backend_app("apigateway")
|
||||
test_client = backend.test_client()
|
||||
usage_plan_id = 'test_plan_id'
|
||||
usage_plan_id = "test_plan_id"
|
||||
|
||||
# Create usage plan key with non-existent api key
|
||||
res = test_client.post('/usageplans/{0}/keys'.format(usage_plan_id), data=json.dumps({'keyId': 'non-existent', 'keyType': 'API_KEY'}))
|
||||
res = test_client.post(
|
||||
"/usageplans/{0}/keys".format(usage_plan_id),
|
||||
data=json.dumps({"keyId": "non-existent", "keyType": "API_KEY"}),
|
||||
)
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
|
|
|
|||
59
tests/test_athena/test_athena.py
Normal file
59
tests/test_athena/test_athena.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
import boto3
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_athena
|
||||
|
||||
|
||||
@mock_athena
|
||||
def test_create_work_group():
|
||||
client = boto3.client("athena", region_name="us-east-1")
|
||||
|
||||
response = client.create_work_group(
|
||||
Name="athena_workgroup",
|
||||
Description="Test work group",
|
||||
Configuration={
|
||||
"ResultConfiguration": {
|
||||
"OutputLocation": "s3://bucket-name/prefix/",
|
||||
"EncryptionConfiguration": {
|
||||
"EncryptionOption": "SSE_KMS",
|
||||
"KmsKey": "aws:arn:kms:1233456789:us-east-1:key/number-1",
|
||||
},
|
||||
}
|
||||
},
|
||||
Tags=[],
|
||||
)
|
||||
|
||||
try:
|
||||
# The second time should throw an error
|
||||
response = client.create_work_group(
|
||||
Name="athena_workgroup",
|
||||
Description="duplicate",
|
||||
Configuration={
|
||||
"ResultConfiguration": {
|
||||
"OutputLocation": "s3://bucket-name/prefix/",
|
||||
"EncryptionConfiguration": {
|
||||
"EncryptionOption": "SSE_KMS",
|
||||
"KmsKey": "aws:arn:kms:1233456789:us-east-1:key/number-1",
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response["Error"]["Code"].should.equal("InvalidRequestException")
|
||||
err.response["Error"]["Message"].should.equal("WorkGroup already exists")
|
||||
else:
|
||||
raise RuntimeError("Should have raised ResourceNotFoundException")
|
||||
|
||||
# Then test the work group appears in the work group list
|
||||
response = client.list_work_groups()
|
||||
|
||||
response["WorkGroups"].should.have.length_of(1)
|
||||
work_group = response["WorkGroups"][0]
|
||||
work_group["Name"].should.equal("athena_workgroup")
|
||||
work_group["Description"].should.equal("Test work group")
|
||||
work_group["State"].should.equal("ENABLED")
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,127 +2,134 @@ from __future__ import unicode_literals
|
|||
import boto3
|
||||
|
||||
import sure # noqa
|
||||
from moto import mock_autoscaling, mock_ec2, mock_elbv2
|
||||
from moto import mock_autoscaling, mock_ec2, mock_elbv2
|
||||
|
||||
from utils import setup_networking
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@mock_autoscaling
|
||||
def test_attach_detach_target_groups():
|
||||
mocked_networking = setup_networking()
|
||||
INSTANCE_COUNT = 2
|
||||
client = boto3.client('autoscaling', region_name='us-east-1')
|
||||
elbv2_client = boto3.client('elbv2', region_name='us-east-1')
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
elbv2_client = boto3.client("elbv2", region_name="us-east-1")
|
||||
|
||||
response = elbv2_client.create_target_group(
|
||||
Name='a-target',
|
||||
Protocol='HTTP',
|
||||
Name="a-target",
|
||||
Protocol="HTTP",
|
||||
Port=8080,
|
||||
VpcId=mocked_networking['vpc'],
|
||||
HealthCheckProtocol='HTTP',
|
||||
HealthCheckPort='8080',
|
||||
HealthCheckPath='/',
|
||||
VpcId=mocked_networking["vpc"],
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="8080",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=5,
|
||||
HealthCheckTimeoutSeconds=5,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={'HttpCode': '200'})
|
||||
target_group_arn = response['TargetGroups'][0]['TargetGroupArn']
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
target_group_arn = response["TargetGroups"][0]["TargetGroupArn"]
|
||||
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName='test_launch_configuration')
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
)
|
||||
|
||||
# create asg, attach to target group on create
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName='test_asg',
|
||||
LaunchConfigurationName='test_launch_configuration',
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
MaxSize=INSTANCE_COUNT,
|
||||
DesiredCapacity=INSTANCE_COUNT,
|
||||
TargetGroupARNs=[target_group_arn],
|
||||
VPCZoneIdentifier=mocked_networking['subnet1'])
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
)
|
||||
# create asg without attaching to target group
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName='test_asg2',
|
||||
LaunchConfigurationName='test_launch_configuration',
|
||||
AutoScalingGroupName="test_asg2",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
MaxSize=INSTANCE_COUNT,
|
||||
DesiredCapacity=INSTANCE_COUNT,
|
||||
VPCZoneIdentifier=mocked_networking['subnet2'])
|
||||
VPCZoneIdentifier=mocked_networking["subnet2"],
|
||||
)
|
||||
|
||||
response = client.describe_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg')
|
||||
list(response['LoadBalancerTargetGroups']).should.have.length_of(1)
|
||||
AutoScalingGroupName="test_asg"
|
||||
)
|
||||
list(response["LoadBalancerTargetGroups"]).should.have.length_of(1)
|
||||
|
||||
response = elbv2_client.describe_target_health(
|
||||
TargetGroupArn=target_group_arn)
|
||||
list(response['TargetHealthDescriptions']).should.have.length_of(INSTANCE_COUNT)
|
||||
response = elbv2_client.describe_target_health(TargetGroupArn=target_group_arn)
|
||||
list(response["TargetHealthDescriptions"]).should.have.length_of(INSTANCE_COUNT)
|
||||
|
||||
client.attach_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg2',
|
||||
TargetGroupARNs=[target_group_arn])
|
||||
AutoScalingGroupName="test_asg2", TargetGroupARNs=[target_group_arn]
|
||||
)
|
||||
|
||||
response = elbv2_client.describe_target_health(
|
||||
TargetGroupArn=target_group_arn)
|
||||
list(response['TargetHealthDescriptions']).should.have.length_of(INSTANCE_COUNT * 2)
|
||||
response = elbv2_client.describe_target_health(TargetGroupArn=target_group_arn)
|
||||
list(response["TargetHealthDescriptions"]).should.have.length_of(INSTANCE_COUNT * 2)
|
||||
|
||||
response = client.detach_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg2',
|
||||
TargetGroupARNs=[target_group_arn])
|
||||
response = elbv2_client.describe_target_health(
|
||||
TargetGroupArn=target_group_arn)
|
||||
list(response['TargetHealthDescriptions']).should.have.length_of(INSTANCE_COUNT)
|
||||
AutoScalingGroupName="test_asg2", TargetGroupARNs=[target_group_arn]
|
||||
)
|
||||
response = elbv2_client.describe_target_health(TargetGroupArn=target_group_arn)
|
||||
list(response["TargetHealthDescriptions"]).should.have.length_of(INSTANCE_COUNT)
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@mock_autoscaling
|
||||
def test_detach_all_target_groups():
|
||||
mocked_networking = setup_networking()
|
||||
INSTANCE_COUNT = 2
|
||||
client = boto3.client('autoscaling', region_name='us-east-1')
|
||||
elbv2_client = boto3.client('elbv2', region_name='us-east-1')
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
elbv2_client = boto3.client("elbv2", region_name="us-east-1")
|
||||
|
||||
response = elbv2_client.create_target_group(
|
||||
Name='a-target',
|
||||
Protocol='HTTP',
|
||||
Name="a-target",
|
||||
Protocol="HTTP",
|
||||
Port=8080,
|
||||
VpcId=mocked_networking['vpc'],
|
||||
HealthCheckProtocol='HTTP',
|
||||
HealthCheckPort='8080',
|
||||
HealthCheckPath='/',
|
||||
VpcId=mocked_networking["vpc"],
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="8080",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=5,
|
||||
HealthCheckTimeoutSeconds=5,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={'HttpCode': '200'})
|
||||
target_group_arn = response['TargetGroups'][0]['TargetGroupArn']
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
target_group_arn = response["TargetGroups"][0]["TargetGroupArn"]
|
||||
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName='test_launch_configuration')
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
)
|
||||
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName='test_asg',
|
||||
LaunchConfigurationName='test_launch_configuration',
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
MaxSize=INSTANCE_COUNT,
|
||||
DesiredCapacity=INSTANCE_COUNT,
|
||||
TargetGroupARNs=[target_group_arn],
|
||||
VPCZoneIdentifier=mocked_networking['subnet1'])
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
)
|
||||
|
||||
response = client.describe_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg')
|
||||
list(response['LoadBalancerTargetGroups']).should.have.length_of(1)
|
||||
AutoScalingGroupName="test_asg"
|
||||
)
|
||||
list(response["LoadBalancerTargetGroups"]).should.have.length_of(1)
|
||||
|
||||
response = elbv2_client.describe_target_health(
|
||||
TargetGroupArn=target_group_arn)
|
||||
list(response['TargetHealthDescriptions']).should.have.length_of(INSTANCE_COUNT)
|
||||
response = elbv2_client.describe_target_health(TargetGroupArn=target_group_arn)
|
||||
list(response["TargetHealthDescriptions"]).should.have.length_of(INSTANCE_COUNT)
|
||||
|
||||
response = client.detach_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg',
|
||||
TargetGroupARNs=[target_group_arn])
|
||||
AutoScalingGroupName="test_asg", TargetGroupARNs=[target_group_arn]
|
||||
)
|
||||
|
||||
response = elbv2_client.describe_target_health(
|
||||
TargetGroupArn=target_group_arn)
|
||||
list(response['TargetHealthDescriptions']).should.have.length_of(0)
|
||||
response = elbv2_client.describe_target_health(TargetGroupArn=target_group_arn)
|
||||
list(response["TargetHealthDescriptions"]).should.have.length_of(0)
|
||||
response = client.describe_load_balancer_target_groups(
|
||||
AutoScalingGroupName='test_asg')
|
||||
list(response['LoadBalancerTargetGroups']).should.have.length_of(0)
|
||||
AutoScalingGroupName="test_asg"
|
||||
)
|
||||
list(response["LoadBalancerTargetGroups"]).should.have.length_of(0)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import sure # noqa
|
|||
|
||||
from moto import mock_autoscaling_deprecated
|
||||
from moto import mock_autoscaling
|
||||
from moto.core import ACCOUNT_ID
|
||||
from tests.helpers import requires_boto_gte
|
||||
|
||||
|
||||
|
|
@ -15,29 +16,31 @@ from tests.helpers import requires_boto_gte
|
|||
def test_create_launch_configuration():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='t1.micro',
|
||||
key_name='the_keys',
|
||||
name="tester",
|
||||
image_id="ami-abcd1234",
|
||||
instance_type="t1.micro",
|
||||
key_name="the_keys",
|
||||
security_groups=["default", "default2"],
|
||||
user_data=b"This is some user_data",
|
||||
instance_monitoring=True,
|
||||
instance_profile_name='arn:aws:iam::123456789012:instance-profile/testing',
|
||||
instance_profile_name="arn:aws:iam::{}:instance-profile/testing".format(
|
||||
ACCOUNT_ID
|
||||
),
|
||||
spot_price=0.1,
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
launch_config = conn.get_all_launch_configurations()[0]
|
||||
launch_config.name.should.equal('tester')
|
||||
launch_config.image_id.should.equal('ami-abcd1234')
|
||||
launch_config.instance_type.should.equal('t1.micro')
|
||||
launch_config.key_name.should.equal('the_keys')
|
||||
set(launch_config.security_groups).should.equal(
|
||||
set(['default', 'default2']))
|
||||
launch_config.name.should.equal("tester")
|
||||
launch_config.image_id.should.equal("ami-abcd1234")
|
||||
launch_config.instance_type.should.equal("t1.micro")
|
||||
launch_config.key_name.should.equal("the_keys")
|
||||
set(launch_config.security_groups).should.equal(set(["default", "default2"]))
|
||||
launch_config.user_data.should.equal(b"This is some user_data")
|
||||
launch_config.instance_monitoring.enabled.should.equal('true')
|
||||
launch_config.instance_monitoring.enabled.should.equal("true")
|
||||
launch_config.instance_profile_name.should.equal(
|
||||
'arn:aws:iam::123456789012:instance-profile/testing')
|
||||
"arn:aws:iam::{}:instance-profile/testing".format(ACCOUNT_ID)
|
||||
)
|
||||
launch_config.spot_price.should.equal(0.1)
|
||||
|
||||
|
||||
|
|
@ -47,64 +50,67 @@ def test_create_launch_configuration_with_block_device_mappings():
|
|||
block_device_mapping = BlockDeviceMapping()
|
||||
|
||||
ephemeral_drive = BlockDeviceType()
|
||||
ephemeral_drive.ephemeral_name = 'ephemeral0'
|
||||
block_device_mapping['/dev/xvdb'] = ephemeral_drive
|
||||
ephemeral_drive.ephemeral_name = "ephemeral0"
|
||||
block_device_mapping["/dev/xvdb"] = ephemeral_drive
|
||||
|
||||
snapshot_drive = BlockDeviceType()
|
||||
snapshot_drive.snapshot_id = "snap-1234abcd"
|
||||
snapshot_drive.volume_type = "standard"
|
||||
block_device_mapping['/dev/xvdp'] = snapshot_drive
|
||||
block_device_mapping["/dev/xvdp"] = snapshot_drive
|
||||
|
||||
ebs_drive = BlockDeviceType()
|
||||
ebs_drive.volume_type = "io1"
|
||||
ebs_drive.size = 100
|
||||
ebs_drive.iops = 1000
|
||||
ebs_drive.delete_on_termination = False
|
||||
block_device_mapping['/dev/xvdh'] = ebs_drive
|
||||
block_device_mapping["/dev/xvdh"] = ebs_drive
|
||||
|
||||
conn = boto.connect_autoscale(use_block_device_types=True)
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
key_name='the_keys',
|
||||
name="tester",
|
||||
image_id="ami-abcd1234",
|
||||
instance_type="m1.small",
|
||||
key_name="the_keys",
|
||||
security_groups=["default", "default2"],
|
||||
user_data=b"This is some user_data",
|
||||
instance_monitoring=True,
|
||||
instance_profile_name='arn:aws:iam::123456789012:instance-profile/testing',
|
||||
instance_profile_name="arn:aws:iam::{}:instance-profile/testing".format(
|
||||
ACCOUNT_ID
|
||||
),
|
||||
spot_price=0.1,
|
||||
block_device_mappings=[block_device_mapping]
|
||||
block_device_mappings=[block_device_mapping],
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
launch_config = conn.get_all_launch_configurations()[0]
|
||||
launch_config.name.should.equal('tester')
|
||||
launch_config.image_id.should.equal('ami-abcd1234')
|
||||
launch_config.instance_type.should.equal('m1.small')
|
||||
launch_config.key_name.should.equal('the_keys')
|
||||
set(launch_config.security_groups).should.equal(
|
||||
set(['default', 'default2']))
|
||||
launch_config.name.should.equal("tester")
|
||||
launch_config.image_id.should.equal("ami-abcd1234")
|
||||
launch_config.instance_type.should.equal("m1.small")
|
||||
launch_config.key_name.should.equal("the_keys")
|
||||
set(launch_config.security_groups).should.equal(set(["default", "default2"]))
|
||||
launch_config.user_data.should.equal(b"This is some user_data")
|
||||
launch_config.instance_monitoring.enabled.should.equal('true')
|
||||
launch_config.instance_monitoring.enabled.should.equal("true")
|
||||
launch_config.instance_profile_name.should.equal(
|
||||
'arn:aws:iam::123456789012:instance-profile/testing')
|
||||
"arn:aws:iam::{}:instance-profile/testing".format(ACCOUNT_ID)
|
||||
)
|
||||
launch_config.spot_price.should.equal(0.1)
|
||||
len(launch_config.block_device_mappings).should.equal(3)
|
||||
|
||||
returned_mapping = launch_config.block_device_mappings
|
||||
|
||||
set(returned_mapping.keys()).should.equal(
|
||||
set(['/dev/xvdb', '/dev/xvdp', '/dev/xvdh']))
|
||||
set(["/dev/xvdb", "/dev/xvdp", "/dev/xvdh"])
|
||||
)
|
||||
|
||||
returned_mapping['/dev/xvdh'].iops.should.equal(1000)
|
||||
returned_mapping['/dev/xvdh'].size.should.equal(100)
|
||||
returned_mapping['/dev/xvdh'].volume_type.should.equal("io1")
|
||||
returned_mapping['/dev/xvdh'].delete_on_termination.should.be.false
|
||||
returned_mapping["/dev/xvdh"].iops.should.equal(1000)
|
||||
returned_mapping["/dev/xvdh"].size.should.equal(100)
|
||||
returned_mapping["/dev/xvdh"].volume_type.should.equal("io1")
|
||||
returned_mapping["/dev/xvdh"].delete_on_termination.should.be.false
|
||||
|
||||
returned_mapping['/dev/xvdp'].snapshot_id.should.equal("snap-1234abcd")
|
||||
returned_mapping['/dev/xvdp'].volume_type.should.equal("standard")
|
||||
returned_mapping["/dev/xvdp"].snapshot_id.should.equal("snap-1234abcd")
|
||||
returned_mapping["/dev/xvdp"].volume_type.should.equal("standard")
|
||||
|
||||
returned_mapping['/dev/xvdb'].ephemeral_name.should.equal('ephemeral0')
|
||||
returned_mapping["/dev/xvdb"].ephemeral_name.should.equal("ephemeral0")
|
||||
|
||||
|
||||
@requires_boto_gte("2.12")
|
||||
|
|
@ -112,9 +118,7 @@ def test_create_launch_configuration_with_block_device_mappings():
|
|||
def test_create_launch_configuration_for_2_12():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
ebs_optimized=True,
|
||||
name="tester", image_id="ami-abcd1234", ebs_optimized=True
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
|
|
@ -127,9 +131,7 @@ def test_create_launch_configuration_for_2_12():
|
|||
def test_create_launch_configuration_using_ip_association():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
associate_public_ip_address=True,
|
||||
name="tester", image_id="ami-abcd1234", associate_public_ip_address=True
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
|
|
@ -141,10 +143,7 @@ def test_create_launch_configuration_using_ip_association():
|
|||
@mock_autoscaling_deprecated
|
||||
def test_create_launch_configuration_using_ip_association_should_default_to_false():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
)
|
||||
config = LaunchConfiguration(name="tester", image_id="ami-abcd1234")
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
launch_config = conn.get_all_launch_configurations()[0]
|
||||
|
|
@ -157,22 +156,20 @@ def test_create_launch_configuration_defaults():
|
|||
are assigned for the other attributes """
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
launch_config = conn.get_all_launch_configurations()[0]
|
||||
launch_config.name.should.equal('tester')
|
||||
launch_config.image_id.should.equal('ami-abcd1234')
|
||||
launch_config.instance_type.should.equal('m1.small')
|
||||
launch_config.name.should.equal("tester")
|
||||
launch_config.image_id.should.equal("ami-abcd1234")
|
||||
launch_config.instance_type.should.equal("m1.small")
|
||||
|
||||
# Defaults
|
||||
launch_config.key_name.should.equal('')
|
||||
launch_config.key_name.should.equal("")
|
||||
list(launch_config.security_groups).should.equal([])
|
||||
launch_config.user_data.should.equal(b"")
|
||||
launch_config.instance_monitoring.enabled.should.equal('false')
|
||||
launch_config.instance_monitoring.enabled.should.equal("false")
|
||||
launch_config.instance_profile_name.should.equal(None)
|
||||
launch_config.spot_price.should.equal(None)
|
||||
|
||||
|
|
@ -181,10 +178,7 @@ def test_create_launch_configuration_defaults():
|
|||
@mock_autoscaling_deprecated
|
||||
def test_create_launch_configuration_defaults_for_2_12():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
)
|
||||
config = LaunchConfiguration(name="tester", image_id="ami-abcd1234")
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
launch_config = conn.get_all_launch_configurations()[0]
|
||||
|
|
@ -195,51 +189,48 @@ def test_create_launch_configuration_defaults_for_2_12():
|
|||
def test_launch_configuration_describe_filter():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
config.name = 'tester2'
|
||||
config.name = "tester2"
|
||||
conn.create_launch_configuration(config)
|
||||
config.name = 'tester3'
|
||||
config.name = "tester3"
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
conn.get_all_launch_configurations(
|
||||
names=['tester', 'tester2']).should.have.length_of(2)
|
||||
names=["tester", "tester2"]
|
||||
).should.have.length_of(2)
|
||||
conn.get_all_launch_configurations().should.have.length_of(3)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_launch_configuration_describe_paginated():
|
||||
conn = boto3.client('autoscaling', region_name='us-east-1')
|
||||
conn = boto3.client("autoscaling", region_name="us-east-1")
|
||||
for i in range(51):
|
||||
conn.create_launch_configuration(LaunchConfigurationName='TestLC%d' % i)
|
||||
conn.create_launch_configuration(LaunchConfigurationName="TestLC%d" % i)
|
||||
|
||||
response = conn.describe_launch_configurations()
|
||||
lcs = response["LaunchConfigurations"]
|
||||
marker = response["NextToken"]
|
||||
lcs.should.have.length_of(50)
|
||||
marker.should.equal(lcs[-1]['LaunchConfigurationName'])
|
||||
marker.should.equal(lcs[-1]["LaunchConfigurationName"])
|
||||
|
||||
response2 = conn.describe_launch_configurations(NextToken=marker)
|
||||
|
||||
lcs.extend(response2["LaunchConfigurations"])
|
||||
lcs.should.have.length_of(51)
|
||||
assert 'NextToken' not in response2.keys()
|
||||
assert "NextToken" not in response2.keys()
|
||||
|
||||
|
||||
@mock_autoscaling_deprecated
|
||||
def test_launch_configuration_delete():
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
conn.get_all_launch_configurations().should.have.length_of(1)
|
||||
|
||||
conn.delete_launch_configuration('tester')
|
||||
conn.delete_launch_configuration("tester")
|
||||
conn.get_all_launch_configurations().should.have.length_of(0)
|
||||
|
|
|
|||
|
|
@ -14,18 +14,16 @@ def setup_autoscale_group():
|
|||
mocked_networking = setup_networking_deprecated()
|
||||
conn = boto.connect_autoscale()
|
||||
config = LaunchConfiguration(
|
||||
name='tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
|
||||
)
|
||||
conn.create_launch_configuration(config)
|
||||
|
||||
group = AutoScalingGroup(
|
||||
name='tester_group',
|
||||
name="tester_group",
|
||||
max_size=2,
|
||||
min_size=2,
|
||||
launch_config=config,
|
||||
vpc_zone_identifier=mocked_networking['subnet1'],
|
||||
vpc_zone_identifier=mocked_networking["subnet1"],
|
||||
)
|
||||
conn.create_auto_scaling_group(group)
|
||||
return group
|
||||
|
|
@ -36,18 +34,18 @@ def test_create_policy():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
cooldown=60,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
||||
policy = conn.get_all_policies()[0]
|
||||
policy.name.should.equal('ScaleUp')
|
||||
policy.adjustment_type.should.equal('ExactCapacity')
|
||||
policy.as_name.should.equal('tester_group')
|
||||
policy.name.should.equal("ScaleUp")
|
||||
policy.adjustment_type.should.equal("ExactCapacity")
|
||||
policy.as_name.should.equal("tester_group")
|
||||
policy.scaling_adjustment.should.equal(3)
|
||||
policy.cooldown.should.equal(60)
|
||||
|
||||
|
|
@ -57,15 +55,15 @@ def test_create_policy_default_values():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
||||
policy = conn.get_all_policies()[0]
|
||||
policy.name.should.equal('ScaleUp')
|
||||
policy.name.should.equal("ScaleUp")
|
||||
|
||||
# Defaults
|
||||
policy.cooldown.should.equal(300)
|
||||
|
|
@ -76,9 +74,9 @@ def test_update_policy():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
@ -88,9 +86,9 @@ def test_update_policy():
|
|||
|
||||
# Now update it by creating another with the same name
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=2,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
@ -103,16 +101,16 @@ def test_delete_policy():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
||||
conn.get_all_policies().should.have.length_of(1)
|
||||
|
||||
conn.delete_policy('ScaleUp')
|
||||
conn.delete_policy("ScaleUp")
|
||||
conn.get_all_policies().should.have.length_of(0)
|
||||
|
||||
|
||||
|
|
@ -121,9 +119,9 @@ def test_execute_policy_exact_capacity():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ExactCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ExactCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
@ -139,9 +137,9 @@ def test_execute_policy_positive_change_in_capacity():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='ChangeInCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="ChangeInCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=3,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
@ -157,9 +155,9 @@ def test_execute_policy_percent_change_in_capacity():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='PercentChangeInCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="PercentChangeInCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=50,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
@ -178,9 +176,9 @@ def test_execute_policy_small_percent_change_in_capacity():
|
|||
setup_autoscale_group()
|
||||
conn = boto.connect_autoscale()
|
||||
policy = ScalingPolicy(
|
||||
name='ScaleUp',
|
||||
adjustment_type='PercentChangeInCapacity',
|
||||
as_name='tester_group',
|
||||
name="ScaleUp",
|
||||
adjustment_type="PercentChangeInCapacity",
|
||||
as_name="tester_group",
|
||||
scaling_adjustment=1,
|
||||
)
|
||||
conn.create_scaling_policy(policy)
|
||||
|
|
|
|||
|
|
@ -3,16 +3,16 @@ import sure # noqa
|
|||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
"""
|
||||
Test the different server responses
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
def test_describe_autoscaling_groups():
|
||||
backend = server.create_backend_app("autoscaling")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get('/?Action=DescribeLaunchConfigurations')
|
||||
res = test_client.get("/?Action=DescribeLaunchConfigurations")
|
||||
|
||||
res.data.should.contain(b'<DescribeLaunchConfigurationsResponse')
|
||||
res.data.should.contain(b'<LaunchConfigurations>')
|
||||
res.data.should.contain(b"<DescribeLaunchConfigurationsResponse")
|
||||
res.data.should.contain(b"<LaunchConfigurations>")
|
||||
|
|
|
|||
|
|
@ -6,43 +6,36 @@ from moto import mock_ec2, mock_ec2_deprecated
|
|||
|
||||
@mock_ec2
|
||||
def setup_networking():
|
||||
ec2 = boto3.resource('ec2', region_name='us-east-1')
|
||||
vpc = ec2.create_vpc(CidrBlock='10.11.0.0/16')
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
vpc = ec2.create_vpc(CidrBlock="10.11.0.0/16")
|
||||
subnet1 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock='10.11.1.0/24',
|
||||
AvailabilityZone='us-east-1a')
|
||||
VpcId=vpc.id, CidrBlock="10.11.1.0/24", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
subnet2 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock='10.11.2.0/24',
|
||||
AvailabilityZone='us-east-1b')
|
||||
return {'vpc': vpc.id, 'subnet1': subnet1.id, 'subnet2': subnet2.id}
|
||||
VpcId=vpc.id, CidrBlock="10.11.2.0/24", AvailabilityZone="us-east-1b"
|
||||
)
|
||||
return {"vpc": vpc.id, "subnet1": subnet1.id, "subnet2": subnet2.id}
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def setup_networking_deprecated():
|
||||
conn = boto_vpc.connect_to_region('us-east-1')
|
||||
conn = boto_vpc.connect_to_region("us-east-1")
|
||||
vpc = conn.create_vpc("10.11.0.0/16")
|
||||
subnet1 = conn.create_subnet(
|
||||
vpc.id,
|
||||
"10.11.1.0/24",
|
||||
availability_zone='us-east-1a')
|
||||
subnet2 = conn.create_subnet(
|
||||
vpc.id,
|
||||
"10.11.2.0/24",
|
||||
availability_zone='us-east-1b')
|
||||
return {'vpc': vpc.id, 'subnet1': subnet1.id, 'subnet2': subnet2.id}
|
||||
subnet1 = conn.create_subnet(vpc.id, "10.11.1.0/24", availability_zone="us-east-1a")
|
||||
subnet2 = conn.create_subnet(vpc.id, "10.11.2.0/24", availability_zone="us-east-1b")
|
||||
return {"vpc": vpc.id, "subnet1": subnet1.id, "subnet2": subnet2.id}
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def setup_instance_with_networking(image_id, instance_type):
|
||||
mock_data = setup_networking()
|
||||
ec2 = boto3.resource('ec2', region_name='us-east-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
instances = ec2.create_instances(
|
||||
ImageId=image_id,
|
||||
InstanceType=instance_type,
|
||||
MaxCount=1,
|
||||
MinCount=1,
|
||||
SubnetId=mock_data['subnet1']
|
||||
SubnetId=mock_data["subnet1"],
|
||||
)
|
||||
mock_data['instance'] = instances[0].id
|
||||
mock_data["instance"] = instances[0].id
|
||||
return mock_data
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
138
tests/test_awslambda/test_lambda_cloudformation.py
Normal file
138
tests/test_awslambda/test_lambda_cloudformation.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import boto3
|
||||
import io
|
||||
import sure # noqa
|
||||
import zipfile
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_cloudformation, mock_iam, mock_lambda, mock_s3
|
||||
from nose.tools import assert_raises
|
||||
from string import Template
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
def _process_lambda(func_str):
|
||||
zip_output = io.BytesIO()
|
||||
zip_file = zipfile.ZipFile(zip_output, "w", zipfile.ZIP_DEFLATED)
|
||||
zip_file.writestr("lambda_function.py", func_str)
|
||||
zip_file.close()
|
||||
zip_output.seek(0)
|
||||
return zip_output.read()
|
||||
|
||||
|
||||
def get_zip_file():
|
||||
pfunc = """
|
||||
def lambda_handler1(event, context):
|
||||
return event
|
||||
def lambda_handler2(event, context):
|
||||
return event
|
||||
"""
|
||||
return _process_lambda(pfunc)
|
||||
|
||||
|
||||
template = Template(
|
||||
"""{
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"LF3ABOV": {
|
||||
"Type": "AWS::Lambda::Function",
|
||||
"Properties": {
|
||||
"Handler": "$handler",
|
||||
"Role": "$role_arn",
|
||||
"Runtime": "$runtime",
|
||||
"Code": {
|
||||
"S3Bucket": "$bucket_name",
|
||||
"S3Key": "$key"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
def test_lambda_can_be_updated_by_cloudformation():
|
||||
s3 = boto3.client("s3", "us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
lmbda = boto3.client("lambda", region_name="us-east-1")
|
||||
body2, stack = create_stack(cf, s3)
|
||||
created_fn_name = get_created_function_name(cf, stack)
|
||||
# Verify function has been created
|
||||
created_fn = lmbda.get_function(FunctionName=created_fn_name)
|
||||
created_fn["Configuration"]["Handler"].should.equal(
|
||||
"lambda_function.lambda_handler1"
|
||||
)
|
||||
created_fn["Configuration"]["Runtime"].should.equal("python3.7")
|
||||
created_fn["Code"]["Location"].should.match("/test1.zip")
|
||||
# Update CF stack
|
||||
cf.update_stack(StackName="teststack", TemplateBody=body2)
|
||||
updated_fn_name = get_created_function_name(cf, stack)
|
||||
# Verify function has been updated
|
||||
updated_fn = lmbda.get_function(FunctionName=updated_fn_name)
|
||||
updated_fn["Configuration"]["FunctionArn"].should.equal(
|
||||
created_fn["Configuration"]["FunctionArn"]
|
||||
)
|
||||
updated_fn["Configuration"]["Handler"].should.equal(
|
||||
"lambda_function.lambda_handler2"
|
||||
)
|
||||
updated_fn["Configuration"]["Runtime"].should.equal("python3.8")
|
||||
updated_fn["Code"]["Location"].should.match("/test2.zip")
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
def test_lambda_can_be_deleted_by_cloudformation():
|
||||
s3 = boto3.client("s3", "us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
lmbda = boto3.client("lambda", region_name="us-east-1")
|
||||
_, stack = create_stack(cf, s3)
|
||||
created_fn_name = get_created_function_name(cf, stack)
|
||||
# Delete Stack
|
||||
cf.delete_stack(StackName=stack["StackId"])
|
||||
# Verify function was deleted
|
||||
with assert_raises(ClientError) as e:
|
||||
lmbda.get_function(FunctionName=created_fn_name)
|
||||
e.exception.response["Error"]["Code"].should.equal("404")
|
||||
|
||||
|
||||
def create_stack(cf, s3):
|
||||
bucket_name = str(uuid4())
|
||||
s3.create_bucket(Bucket=bucket_name)
|
||||
s3.put_object(Bucket=bucket_name, Key="test1.zip", Body=get_zip_file())
|
||||
s3.put_object(Bucket=bucket_name, Key="test2.zip", Body=get_zip_file())
|
||||
body1 = get_template(bucket_name, "1", "python3.7")
|
||||
body2 = get_template(bucket_name, "2", "python3.8")
|
||||
stack = cf.create_stack(StackName="teststack", TemplateBody=body1)
|
||||
return body2, stack
|
||||
|
||||
|
||||
def get_created_function_name(cf, stack):
|
||||
res = cf.list_stack_resources(StackName=stack["StackId"])
|
||||
return res["StackResourceSummaries"][0]["PhysicalResourceId"]
|
||||
|
||||
|
||||
def get_template(bucket_name, version, runtime):
|
||||
key = "test" + version + ".zip"
|
||||
handler = "lambda_function.lambda_handler" + version
|
||||
return template.substitute(
|
||||
bucket_name=bucket_name,
|
||||
key=key,
|
||||
handler=handler,
|
||||
role_arn=get_role_arn(),
|
||||
runtime=runtime,
|
||||
)
|
||||
|
||||
|
||||
def get_role_arn():
|
||||
with mock_iam():
|
||||
iam = boto3.client("iam", region_name="us-west-2")
|
||||
try:
|
||||
return iam.get_role(RoleName="my-role")["Role"]["Arn"]
|
||||
except ClientError:
|
||||
return iam.create_role(
|
||||
RoleName="my-role",
|
||||
AssumeRolePolicyDocument="some policy",
|
||||
Path="/my-path/",
|
||||
)["Role"]["Arn"]
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -5,20 +5,29 @@ import datetime
|
|||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
import sure # noqa
|
||||
from moto import mock_batch, mock_iam, mock_ec2, mock_ecs, mock_logs, mock_cloudformation
|
||||
from moto import (
|
||||
mock_batch,
|
||||
mock_iam,
|
||||
mock_ec2,
|
||||
mock_ecs,
|
||||
mock_logs,
|
||||
mock_cloudformation,
|
||||
)
|
||||
import functools
|
||||
import nose
|
||||
import json
|
||||
|
||||
DEFAULT_REGION = 'eu-central-1'
|
||||
DEFAULT_REGION = "eu-central-1"
|
||||
|
||||
|
||||
def _get_clients():
|
||||
return boto3.client('ec2', region_name=DEFAULT_REGION), \
|
||||
boto3.client('iam', region_name=DEFAULT_REGION), \
|
||||
boto3.client('ecs', region_name=DEFAULT_REGION), \
|
||||
boto3.client('logs', region_name=DEFAULT_REGION), \
|
||||
boto3.client('batch', region_name=DEFAULT_REGION)
|
||||
return (
|
||||
boto3.client("ec2", region_name=DEFAULT_REGION),
|
||||
boto3.client("iam", region_name=DEFAULT_REGION),
|
||||
boto3.client("ecs", region_name=DEFAULT_REGION),
|
||||
boto3.client("logs", region_name=DEFAULT_REGION),
|
||||
boto3.client("batch", region_name=DEFAULT_REGION),
|
||||
)
|
||||
|
||||
|
||||
def _setup(ec2_client, iam_client):
|
||||
|
|
@ -27,26 +36,25 @@ def _setup(ec2_client, iam_client):
|
|||
:return: VPC ID, Subnet ID, Security group ID, IAM Role ARN
|
||||
:rtype: tuple
|
||||
"""
|
||||
resp = ec2_client.create_vpc(CidrBlock='172.30.0.0/24')
|
||||
vpc_id = resp['Vpc']['VpcId']
|
||||
resp = ec2_client.create_vpc(CidrBlock="172.30.0.0/24")
|
||||
vpc_id = resp["Vpc"]["VpcId"]
|
||||
resp = ec2_client.create_subnet(
|
||||
AvailabilityZone='eu-central-1a',
|
||||
CidrBlock='172.30.0.0/25',
|
||||
VpcId=vpc_id
|
||||
AvailabilityZone="eu-central-1a", CidrBlock="172.30.0.0/25", VpcId=vpc_id
|
||||
)
|
||||
subnet_id = resp['Subnet']['SubnetId']
|
||||
subnet_id = resp["Subnet"]["SubnetId"]
|
||||
resp = ec2_client.create_security_group(
|
||||
Description='test_sg_desc',
|
||||
GroupName='test_sg',
|
||||
VpcId=vpc_id
|
||||
Description="test_sg_desc", GroupName="test_sg", VpcId=vpc_id
|
||||
)
|
||||
sg_id = resp['GroupId']
|
||||
sg_id = resp["GroupId"]
|
||||
|
||||
resp = iam_client.create_role(
|
||||
RoleName='TestRole',
|
||||
AssumeRolePolicyDocument='some_policy'
|
||||
RoleName="TestRole", AssumeRolePolicyDocument="some_policy"
|
||||
)
|
||||
iam_arn = resp["Role"]["Arn"]
|
||||
iam_client.create_instance_profile(InstanceProfileName="TestRole")
|
||||
iam_client.add_role_to_instance_profile(
|
||||
InstanceProfileName="TestRole", RoleName="TestRole"
|
||||
)
|
||||
iam_arn = resp['Role']['Arn']
|
||||
|
||||
return vpc_id, subnet_id, sg_id, iam_arn
|
||||
|
||||
|
|
@ -61,7 +69,7 @@ def test_create_env_cf():
|
|||
vpc_id, subnet_id, sg_id, iam_arn = _setup(ec2_client, iam_client)
|
||||
|
||||
create_environment_template = {
|
||||
'Resources': {
|
||||
"Resources": {
|
||||
"ComputeEnvironment": {
|
||||
"Type": "AWS::Batch::ComputeEnvironment",
|
||||
"Properties": {
|
||||
|
|
@ -71,32 +79,35 @@ def test_create_env_cf():
|
|||
"MinvCpus": 0,
|
||||
"DesiredvCpus": 0,
|
||||
"MaxvCpus": 64,
|
||||
"InstanceTypes": [
|
||||
"optimal"
|
||||
],
|
||||
"InstanceTypes": ["optimal"],
|
||||
"Subnets": [subnet_id],
|
||||
"SecurityGroupIds": [sg_id],
|
||||
"InstanceRole": iam_arn
|
||||
"InstanceRole": iam_arn.replace("role", "instance-profile"),
|
||||
},
|
||||
"ServiceRole": iam_arn
|
||||
}
|
||||
"ServiceRole": iam_arn,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
cf_json = json.dumps(create_environment_template)
|
||||
|
||||
cf_conn = boto3.client('cloudformation', DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(
|
||||
StackName='test_stack',
|
||||
TemplateBody=cf_json,
|
||||
)['StackId']
|
||||
cf_conn = boto3.client("cloudformation", DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(StackName="test_stack", TemplateBody=cf_json)[
|
||||
"StackId"
|
||||
]
|
||||
|
||||
stack_resources = cf_conn.list_stack_resources(StackName=stack_id)
|
||||
|
||||
stack_resources['StackResourceSummaries'][0]['ResourceStatus'].should.equal('CREATE_COMPLETE')
|
||||
stack_resources["StackResourceSummaries"][0]["ResourceStatus"].should.equal(
|
||||
"CREATE_COMPLETE"
|
||||
)
|
||||
# Spot checks on the ARN
|
||||
stack_resources['StackResourceSummaries'][0]['PhysicalResourceId'].startswith('arn:aws:batch:')
|
||||
stack_resources['StackResourceSummaries'][0]['PhysicalResourceId'].should.contain('test_stack')
|
||||
stack_resources["StackResourceSummaries"][0]["PhysicalResourceId"].startswith(
|
||||
"arn:aws:batch:"
|
||||
)
|
||||
stack_resources["StackResourceSummaries"][0]["PhysicalResourceId"].should.contain(
|
||||
"test_stack"
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
|
|
@ -109,7 +120,7 @@ def test_create_job_queue_cf():
|
|||
vpc_id, subnet_id, sg_id, iam_arn = _setup(ec2_client, iam_client)
|
||||
|
||||
create_environment_template = {
|
||||
'Resources': {
|
||||
"Resources": {
|
||||
"ComputeEnvironment": {
|
||||
"Type": "AWS::Batch::ComputeEnvironment",
|
||||
"Properties": {
|
||||
|
|
@ -119,17 +130,14 @@ def test_create_job_queue_cf():
|
|||
"MinvCpus": 0,
|
||||
"DesiredvCpus": 0,
|
||||
"MaxvCpus": 64,
|
||||
"InstanceTypes": [
|
||||
"optimal"
|
||||
],
|
||||
"InstanceTypes": ["optimal"],
|
||||
"Subnets": [subnet_id],
|
||||
"SecurityGroupIds": [sg_id],
|
||||
"InstanceRole": iam_arn
|
||||
"InstanceRole": iam_arn.replace("role", "instance-profile"),
|
||||
},
|
||||
"ServiceRole": iam_arn
|
||||
}
|
||||
"ServiceRole": iam_arn,
|
||||
},
|
||||
},
|
||||
|
||||
"JobQueue": {
|
||||
"Type": "AWS::Batch::JobQueue",
|
||||
"Properties": {
|
||||
|
|
@ -137,31 +145,35 @@ def test_create_job_queue_cf():
|
|||
"ComputeEnvironmentOrder": [
|
||||
{
|
||||
"Order": 1,
|
||||
"ComputeEnvironment": {"Ref": "ComputeEnvironment"}
|
||||
"ComputeEnvironment": {"Ref": "ComputeEnvironment"},
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
cf_json = json.dumps(create_environment_template)
|
||||
|
||||
cf_conn = boto3.client('cloudformation', DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(
|
||||
StackName='test_stack',
|
||||
TemplateBody=cf_json,
|
||||
)['StackId']
|
||||
cf_conn = boto3.client("cloudformation", DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(StackName="test_stack", TemplateBody=cf_json)[
|
||||
"StackId"
|
||||
]
|
||||
|
||||
stack_resources = cf_conn.list_stack_resources(StackName=stack_id)
|
||||
len(stack_resources['StackResourceSummaries']).should.equal(2)
|
||||
len(stack_resources["StackResourceSummaries"]).should.equal(2)
|
||||
|
||||
job_queue_resource = list(filter(lambda item: item['ResourceType'] == 'AWS::Batch::JobQueue', stack_resources['StackResourceSummaries']))[0]
|
||||
job_queue_resource = list(
|
||||
filter(
|
||||
lambda item: item["ResourceType"] == "AWS::Batch::JobQueue",
|
||||
stack_resources["StackResourceSummaries"],
|
||||
)
|
||||
)[0]
|
||||
|
||||
job_queue_resource['ResourceStatus'].should.equal('CREATE_COMPLETE')
|
||||
job_queue_resource["ResourceStatus"].should.equal("CREATE_COMPLETE")
|
||||
# Spot checks on the ARN
|
||||
job_queue_resource['PhysicalResourceId'].startswith('arn:aws:batch:')
|
||||
job_queue_resource['PhysicalResourceId'].should.contain('test_stack')
|
||||
job_queue_resource['PhysicalResourceId'].should.contain('job-queue/')
|
||||
job_queue_resource["PhysicalResourceId"].startswith("arn:aws:batch:")
|
||||
job_queue_resource["PhysicalResourceId"].should.contain("test_stack")
|
||||
job_queue_resource["PhysicalResourceId"].should.contain("job-queue/")
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
|
|
@ -174,7 +186,7 @@ def test_create_job_def_cf():
|
|||
vpc_id, subnet_id, sg_id, iam_arn = _setup(ec2_client, iam_client)
|
||||
|
||||
create_environment_template = {
|
||||
'Resources': {
|
||||
"Resources": {
|
||||
"ComputeEnvironment": {
|
||||
"Type": "AWS::Batch::ComputeEnvironment",
|
||||
"Properties": {
|
||||
|
|
@ -184,17 +196,14 @@ def test_create_job_def_cf():
|
|||
"MinvCpus": 0,
|
||||
"DesiredvCpus": 0,
|
||||
"MaxvCpus": 64,
|
||||
"InstanceTypes": [
|
||||
"optimal"
|
||||
],
|
||||
"InstanceTypes": ["optimal"],
|
||||
"Subnets": [subnet_id],
|
||||
"SecurityGroupIds": [sg_id],
|
||||
"InstanceRole": iam_arn
|
||||
"InstanceRole": iam_arn.replace("role", "instance-profile"),
|
||||
},
|
||||
"ServiceRole": iam_arn
|
||||
}
|
||||
"ServiceRole": iam_arn,
|
||||
},
|
||||
},
|
||||
|
||||
"JobQueue": {
|
||||
"Type": "AWS::Batch::JobQueue",
|
||||
"Properties": {
|
||||
|
|
@ -202,46 +211,54 @@ def test_create_job_def_cf():
|
|||
"ComputeEnvironmentOrder": [
|
||||
{
|
||||
"Order": 1,
|
||||
"ComputeEnvironment": {"Ref": "ComputeEnvironment"}
|
||||
"ComputeEnvironment": {"Ref": "ComputeEnvironment"},
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
"JobDefinition": {
|
||||
"Type": "AWS::Batch::JobDefinition",
|
||||
"Properties": {
|
||||
"Type": "container",
|
||||
"ContainerProperties": {
|
||||
"Image": {
|
||||
"Fn::Join": ["", ["137112412989.dkr.ecr.", {"Ref": "AWS::Region"}, ".amazonaws.com/amazonlinux:latest"]]
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"137112412989.dkr.ecr.",
|
||||
{"Ref": "AWS::Region"},
|
||||
".amazonaws.com/amazonlinux:latest",
|
||||
],
|
||||
]
|
||||
},
|
||||
"Vcpus": 2,
|
||||
"Memory": 2000,
|
||||
"Command": ["echo", "Hello world"]
|
||||
"Command": ["echo", "Hello world"],
|
||||
},
|
||||
"RetryStrategy": {
|
||||
"Attempts": 1
|
||||
}
|
||||
}
|
||||
"RetryStrategy": {"Attempts": 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
cf_json = json.dumps(create_environment_template)
|
||||
|
||||
cf_conn = boto3.client('cloudformation', DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(
|
||||
StackName='test_stack',
|
||||
TemplateBody=cf_json,
|
||||
)['StackId']
|
||||
cf_conn = boto3.client("cloudformation", DEFAULT_REGION)
|
||||
stack_id = cf_conn.create_stack(StackName="test_stack", TemplateBody=cf_json)[
|
||||
"StackId"
|
||||
]
|
||||
|
||||
stack_resources = cf_conn.list_stack_resources(StackName=stack_id)
|
||||
len(stack_resources['StackResourceSummaries']).should.equal(3)
|
||||
len(stack_resources["StackResourceSummaries"]).should.equal(3)
|
||||
|
||||
job_def_resource = list(filter(lambda item: item['ResourceType'] == 'AWS::Batch::JobDefinition', stack_resources['StackResourceSummaries']))[0]
|
||||
job_def_resource = list(
|
||||
filter(
|
||||
lambda item: item["ResourceType"] == "AWS::Batch::JobDefinition",
|
||||
stack_resources["StackResourceSummaries"],
|
||||
)
|
||||
)[0]
|
||||
|
||||
job_def_resource['ResourceStatus'].should.equal('CREATE_COMPLETE')
|
||||
job_def_resource["ResourceStatus"].should.equal("CREATE_COMPLETE")
|
||||
# Spot checks on the ARN
|
||||
job_def_resource['PhysicalResourceId'].startswith('arn:aws:batch:')
|
||||
job_def_resource['PhysicalResourceId'].should.contain('test_stack-JobDef')
|
||||
job_def_resource['PhysicalResourceId'].should.contain('job-definition/')
|
||||
job_def_resource["PhysicalResourceId"].startswith("arn:aws:batch:")
|
||||
job_def_resource["PhysicalResourceId"].should.contain("test_stack-JobDef")
|
||||
job_def_resource["PhysicalResourceId"].should.contain("job-definition/")
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import sure # noqa
|
|||
import moto.server as server
|
||||
from moto import mock_batch
|
||||
|
||||
'''
|
||||
"""
|
||||
Test the different server responses
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
@mock_batch
|
||||
|
|
@ -15,5 +15,5 @@ def test_batch_list():
|
|||
backend = server.create_backend_app("batch")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get('/v1/describecomputeenvironments')
|
||||
res = test_client.get("/v1/describecomputeenvironments")
|
||||
res.status_code.should.equal(200)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
template = {
|
||||
"Resources": {
|
||||
"EC2EIP": {
|
||||
"Type": "AWS::EC2::EIP"
|
||||
}
|
||||
}
|
||||
}
|
||||
template = {"Resources": {"EC2EIP": {"Type": "AWS::EC2::EIP"}}}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,11 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
template = {
|
||||
"Resources": {
|
||||
"EC2EIP": {
|
||||
"Type": "AWS::EC2::EIP"
|
||||
}
|
||||
},
|
||||
"Resources": {"EC2EIP": {"Type": "AWS::EC2::EIP"}},
|
||||
"Outputs": {
|
||||
"EIP": {
|
||||
"Description": "EIP for joining",
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
":",
|
||||
[
|
||||
"test eip",
|
||||
{"Ref": "EC2EIP"}
|
||||
]
|
||||
]
|
||||
}
|
||||
"Value": {"Fn::Join": [":", ["test eip", {"Ref": "EC2EIP"}]]},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,38 +2,45 @@ from __future__ import unicode_literals
|
|||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "AWS CloudFormation Sample Template to create a KMS Key. The Fn::GetAtt is used to retrieve the ARN",
|
||||
|
||||
"Resources" : {
|
||||
"myKey" : {
|
||||
"Type" : "AWS::KMS::Key",
|
||||
"Properties" : {
|
||||
"Resources": {
|
||||
"myKey": {
|
||||
"Type": "AWS::KMS::Key",
|
||||
"Properties": {
|
||||
"Description": "Sample KmsKey",
|
||||
"EnableKeyRotation": False,
|
||||
"Enabled": True,
|
||||
"KeyPolicy" : {
|
||||
"KeyPolicy": {
|
||||
"Version": "2012-10-17",
|
||||
"Id": "key-default-1",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "Enable IAM User Permissions",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": { "Fn::Join" : ["" , ["arn:aws:iam::", {"Ref" : "AWS::AccountId"} ,":root" ]] }
|
||||
},
|
||||
"Action": "kms:*",
|
||||
"Resource": "*"
|
||||
"Sid": "Enable IAM User Permissions",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:aws:iam::",
|
||||
{"Ref": "AWS::AccountId"},
|
||||
":root",
|
||||
],
|
||||
]
|
||||
}
|
||||
},
|
||||
"Action": "kms:*",
|
||||
"Resource": "*",
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs" : {
|
||||
"KeyArn" : {
|
||||
"Outputs": {
|
||||
"KeyArn": {
|
||||
"Description": "Generated Key Arn",
|
||||
"Value" : { "Fn::GetAtt" : [ "myKey", "Arn" ] }
|
||||
"Value": {"Fn::GetAtt": ["myKey", "Arn"]},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica: Sample template showing how to create a highly-available, RDS DBInstance with a read replica. **WARNING** This template creates an Amazon Relational Database Service database instance and Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Parameters": {
|
||||
"DBName": {
|
||||
"Default": "MyDatabase",
|
||||
|
|
@ -13,13 +11,9 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "64",
|
||||
"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBInstanceIdentifier": {
|
||||
"Type": "String"
|
||||
},
|
||||
|
||||
"DBInstanceIdentifier": {"Type": "String"},
|
||||
"DBUser": {
|
||||
"NoEcho": "true",
|
||||
"Description": "The database admin account username",
|
||||
|
|
@ -27,9 +21,8 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "16",
|
||||
"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBPassword": {
|
||||
"NoEcho": "true",
|
||||
"Description": "The database admin account password",
|
||||
|
|
@ -37,112 +30,121 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "41",
|
||||
"AllowedPattern": "[a-zA-Z0-9]+",
|
||||
"ConstraintDescription": "must contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBAllocatedStorage": {
|
||||
"Default": "5",
|
||||
"Description": "The size of the database (Gb)",
|
||||
"Type": "Number",
|
||||
"MinValue": "5",
|
||||
"MaxValue": "1024",
|
||||
"ConstraintDescription": "must be between 5 and 1024Gb."
|
||||
"ConstraintDescription": "must be between 5 and 1024Gb.",
|
||||
},
|
||||
|
||||
"DBInstanceClass": {
|
||||
"Description": "The database instance type",
|
||||
"Type": "String",
|
||||
"Default": "db.m1.small",
|
||||
"AllowedValues": ["db.t1.micro", "db.m1.small", "db.m1.medium", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.cr1.8xlarge"],
|
||||
"ConstraintDescription": "must select a valid database instance type."
|
||||
"AllowedValues": [
|
||||
"db.t1.micro",
|
||||
"db.m1.small",
|
||||
"db.m1.medium",
|
||||
"db.m1.large",
|
||||
"db.m1.xlarge",
|
||||
"db.m2.xlarge",
|
||||
"db.m2.2xlarge",
|
||||
"db.m2.4xlarge",
|
||||
"db.m3.medium",
|
||||
"db.m3.large",
|
||||
"db.m3.xlarge",
|
||||
"db.m3.2xlarge",
|
||||
"db.r3.large",
|
||||
"db.r3.xlarge",
|
||||
"db.r3.2xlarge",
|
||||
"db.r3.4xlarge",
|
||||
"db.r3.8xlarge",
|
||||
"db.m2.xlarge",
|
||||
"db.m2.2xlarge",
|
||||
"db.m2.4xlarge",
|
||||
"db.cr1.8xlarge",
|
||||
],
|
||||
"ConstraintDescription": "must select a valid database instance type.",
|
||||
},
|
||||
|
||||
"EC2SecurityGroup": {
|
||||
"Description": "The EC2 security group that contains instances that need access to the database",
|
||||
"Default": "default",
|
||||
"Type": "String",
|
||||
"AllowedPattern": "[a-zA-Z0-9\\-]+",
|
||||
"ConstraintDescription": "must be a valid security group name."
|
||||
"ConstraintDescription": "must be a valid security group name.",
|
||||
},
|
||||
|
||||
"MultiAZ": {
|
||||
"Description": "Multi-AZ master database",
|
||||
"Type": "String",
|
||||
"Default": "false",
|
||||
"AllowedValues": ["true", "false"],
|
||||
"ConstraintDescription": "must be true or false."
|
||||
}
|
||||
"ConstraintDescription": "must be true or false.",
|
||||
},
|
||||
},
|
||||
|
||||
"Conditions": {
|
||||
"Is-EC2-VPC": {"Fn::Or": [{"Fn::Equals": [{"Ref": "AWS::Region"}, "eu-central-1"]},
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "cn-north-1"]}]},
|
||||
"Is-EC2-Classic": {"Fn::Not": [{"Condition": "Is-EC2-VPC"}]}
|
||||
"Is-EC2-VPC": {
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "eu-central-1"]},
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "cn-north-1"]},
|
||||
]
|
||||
},
|
||||
"Is-EC2-Classic": {"Fn::Not": [{"Condition": "Is-EC2-VPC"}]},
|
||||
},
|
||||
|
||||
"Resources": {
|
||||
"DBParameterGroup": {
|
||||
"Type": "AWS::RDS::DBParameterGroup",
|
||||
"Properties": {
|
||||
"Description": "DB Parameter Goup",
|
||||
"Family": "MySQL5.1",
|
||||
"Parameters": {
|
||||
"BACKLOG_QUEUE_LIMIT": "2048"
|
||||
}
|
||||
}
|
||||
"Parameters": {"BACKLOG_QUEUE_LIMIT": "2048"},
|
||||
},
|
||||
},
|
||||
|
||||
"DBEC2SecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"GroupDescription": "Open database for access",
|
||||
"SecurityGroupIngress": [{
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "3306",
|
||||
"ToPort": "3306",
|
||||
"SourceSecurityGroupName": {"Ref": "EC2SecurityGroup"}
|
||||
}]
|
||||
}
|
||||
"SecurityGroupIngress": [
|
||||
{
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "3306",
|
||||
"ToPort": "3306",
|
||||
"SourceSecurityGroupName": {"Ref": "EC2SecurityGroup"},
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
"DBSecurityGroup": {
|
||||
"Type": "AWS::RDS::DBSecurityGroup",
|
||||
"Condition": "Is-EC2-Classic",
|
||||
"Properties": {
|
||||
"DBSecurityGroupIngress": [{
|
||||
"EC2SecurityGroupName": {"Ref": "EC2SecurityGroup"}
|
||||
}],
|
||||
"GroupDescription": "database access"
|
||||
}
|
||||
"DBSecurityGroupIngress": [
|
||||
{"EC2SecurityGroupName": {"Ref": "EC2SecurityGroup"}}
|
||||
],
|
||||
"GroupDescription": "database access",
|
||||
},
|
||||
},
|
||||
|
||||
"my_vpc": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16",
|
||||
}
|
||||
},
|
||||
|
||||
"my_vpc": {"Type": "AWS::EC2::VPC", "Properties": {"CidrBlock": "10.0.0.0/16"}},
|
||||
"EC2Subnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"AvailabilityZone": "eu-central-1a",
|
||||
"CidrBlock": "10.0.1.0/24",
|
||||
"VpcId": {"Ref": "my_vpc"}
|
||||
}
|
||||
"VpcId": {"Ref": "my_vpc"},
|
||||
},
|
||||
},
|
||||
|
||||
"DBSubnet": {
|
||||
"Type": "AWS::RDS::DBSubnetGroup",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"DBSubnetGroupDescription": "my db subnet group",
|
||||
"SubnetIds": [{"Ref": "EC2Subnet"}],
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
"MasterDB": {
|
||||
"Type": "AWS::RDS::DBInstance",
|
||||
"Properties": {
|
||||
|
|
@ -151,54 +153,79 @@ template = {
|
|||
"AllocatedStorage": {"Ref": "DBAllocatedStorage"},
|
||||
"DBInstanceClass": {"Ref": "DBInstanceClass"},
|
||||
"Engine": "MySQL",
|
||||
"DBSubnetGroupName": {"Fn::If": ["Is-EC2-VPC", {"Ref": "DBSubnet"}, {"Ref": "AWS::NoValue"}]},
|
||||
"DBSubnetGroupName": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-VPC",
|
||||
{"Ref": "DBSubnet"},
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
"MasterUsername": {"Ref": "DBUser"},
|
||||
"MasterUserPassword": {"Ref": "DBPassword"},
|
||||
"MultiAZ": {"Ref": "MultiAZ"},
|
||||
"Tags": [{"Key": "Name", "Value": "Master Database"}],
|
||||
"VPCSecurityGroups": {"Fn::If": ["Is-EC2-VPC", [{"Fn::GetAtt": ["DBEC2SecurityGroup", "GroupId"]}], {"Ref": "AWS::NoValue"}]},
|
||||
"DBSecurityGroups": {"Fn::If": ["Is-EC2-Classic", [{"Ref": "DBSecurityGroup"}], {"Ref": "AWS::NoValue"}]}
|
||||
"VPCSecurityGroups": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-VPC",
|
||||
[{"Fn::GetAtt": ["DBEC2SecurityGroup", "GroupId"]}],
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
"DBSecurityGroups": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-Classic",
|
||||
[{"Ref": "DBSecurityGroup"}],
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
},
|
||||
"DeletionPolicy": "Snapshot"
|
||||
"DeletionPolicy": "Snapshot",
|
||||
},
|
||||
|
||||
"ReplicaDB": {
|
||||
"Type": "AWS::RDS::DBInstance",
|
||||
"Properties": {
|
||||
"SourceDBInstanceIdentifier": {"Ref": "MasterDB"},
|
||||
"DBInstanceClass": {"Ref": "DBInstanceClass"},
|
||||
"Tags": [{"Key": "Name", "Value": "Read Replica Database"}]
|
||||
}
|
||||
}
|
||||
"Tags": [{"Key": "Name", "Value": "Read Replica Database"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"Outputs": {
|
||||
"EC2Platform": {
|
||||
"Description": "Platform in which this stack is deployed",
|
||||
"Value": {"Fn::If": ["Is-EC2-VPC", "EC2-VPC", "EC2-Classic"]}
|
||||
"Value": {"Fn::If": ["Is-EC2-VPC", "EC2-VPC", "EC2-Classic"]},
|
||||
},
|
||||
|
||||
"MasterJDBCConnectionString": {
|
||||
"Description": "JDBC connection string for the master database",
|
||||
"Value": {"Fn::Join": ["", ["jdbc:mysql://",
|
||||
{"Fn::GetAtt": [
|
||||
"MasterDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": [
|
||||
"MasterDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"}]]}
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"jdbc:mysql://",
|
||||
{"Fn::GetAtt": ["MasterDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": ["MasterDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"},
|
||||
],
|
||||
]
|
||||
},
|
||||
},
|
||||
"ReplicaJDBCConnectionString": {
|
||||
"Description": "JDBC connection string for the replica database",
|
||||
"Value": {"Fn::Join": ["", ["jdbc:mysql://",
|
||||
{"Fn::GetAtt": [
|
||||
"ReplicaDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": [
|
||||
"ReplicaDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"}]]}
|
||||
}
|
||||
}
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"jdbc:mysql://",
|
||||
{"Fn::GetAtt": ["ReplicaDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": ["ReplicaDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"},
|
||||
],
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica: Sample template showing how to create a highly-available, RDS DBInstance with a read replica. **WARNING** This template creates an Amazon Relational Database Service database instance and Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Parameters": {
|
||||
"DBName": {
|
||||
"Default": "MyDatabase",
|
||||
|
|
@ -13,13 +11,9 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "64",
|
||||
"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBInstanceIdentifier": {
|
||||
"Type": "String"
|
||||
},
|
||||
|
||||
"DBInstanceIdentifier": {"Type": "String"},
|
||||
"DBUser": {
|
||||
"NoEcho": "true",
|
||||
"Description": "The database admin account username",
|
||||
|
|
@ -27,9 +21,8 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "16",
|
||||
"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBPassword": {
|
||||
"NoEcho": "true",
|
||||
"Description": "The database admin account password",
|
||||
|
|
@ -37,101 +30,113 @@ template = {
|
|||
"MinLength": "1",
|
||||
"MaxLength": "41",
|
||||
"AllowedPattern": "[a-zA-Z0-9]+",
|
||||
"ConstraintDescription": "must contain only alphanumeric characters."
|
||||
"ConstraintDescription": "must contain only alphanumeric characters.",
|
||||
},
|
||||
|
||||
"DBAllocatedStorage": {
|
||||
"Default": "5",
|
||||
"Description": "The size of the database (Gb)",
|
||||
"Type": "Number",
|
||||
"MinValue": "5",
|
||||
"MaxValue": "1024",
|
||||
"ConstraintDescription": "must be between 5 and 1024Gb."
|
||||
"ConstraintDescription": "must be between 5 and 1024Gb.",
|
||||
},
|
||||
|
||||
"DBInstanceClass": {
|
||||
"Description": "The database instance type",
|
||||
"Type": "String",
|
||||
"Default": "db.m1.small",
|
||||
"AllowedValues": ["db.t1.micro", "db.m1.small", "db.m1.medium", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.cr1.8xlarge"],
|
||||
"ConstraintDescription": "must select a valid database instance type."
|
||||
"AllowedValues": [
|
||||
"db.t1.micro",
|
||||
"db.m1.small",
|
||||
"db.m1.medium",
|
||||
"db.m1.large",
|
||||
"db.m1.xlarge",
|
||||
"db.m2.xlarge",
|
||||
"db.m2.2xlarge",
|
||||
"db.m2.4xlarge",
|
||||
"db.m3.medium",
|
||||
"db.m3.large",
|
||||
"db.m3.xlarge",
|
||||
"db.m3.2xlarge",
|
||||
"db.r3.large",
|
||||
"db.r3.xlarge",
|
||||
"db.r3.2xlarge",
|
||||
"db.r3.4xlarge",
|
||||
"db.r3.8xlarge",
|
||||
"db.m2.xlarge",
|
||||
"db.m2.2xlarge",
|
||||
"db.m2.4xlarge",
|
||||
"db.cr1.8xlarge",
|
||||
],
|
||||
"ConstraintDescription": "must select a valid database instance type.",
|
||||
},
|
||||
|
||||
"EC2SecurityGroup": {
|
||||
"Description": "The EC2 security group that contains instances that need access to the database",
|
||||
"Default": "default",
|
||||
"Type": "String",
|
||||
"AllowedPattern": "[a-zA-Z0-9\\-]+",
|
||||
"ConstraintDescription": "must be a valid security group name."
|
||||
"ConstraintDescription": "must be a valid security group name.",
|
||||
},
|
||||
|
||||
"MultiAZ": {
|
||||
"Description": "Multi-AZ master database",
|
||||
"Type": "String",
|
||||
"Default": "false",
|
||||
"AllowedValues": ["true", "false"],
|
||||
"ConstraintDescription": "must be true or false."
|
||||
}
|
||||
"ConstraintDescription": "must be true or false.",
|
||||
},
|
||||
},
|
||||
|
||||
"Conditions": {
|
||||
"Is-EC2-VPC": {"Fn::Or": [{"Fn::Equals": [{"Ref": "AWS::Region"}, "eu-central-1"]},
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "cn-north-1"]}]},
|
||||
"Is-EC2-Classic": {"Fn::Not": [{"Condition": "Is-EC2-VPC"}]}
|
||||
"Is-EC2-VPC": {
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "eu-central-1"]},
|
||||
{"Fn::Equals": [{"Ref": "AWS::Region"}, "cn-north-1"]},
|
||||
]
|
||||
},
|
||||
"Is-EC2-Classic": {"Fn::Not": [{"Condition": "Is-EC2-VPC"}]},
|
||||
},
|
||||
|
||||
"Resources": {
|
||||
"DBEC2SecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"GroupDescription": "Open database for access",
|
||||
"SecurityGroupIngress": [{
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "3306",
|
||||
"ToPort": "3306",
|
||||
"SourceSecurityGroupName": {"Ref": "EC2SecurityGroup"}
|
||||
}]
|
||||
}
|
||||
"SecurityGroupIngress": [
|
||||
{
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "3306",
|
||||
"ToPort": "3306",
|
||||
"SourceSecurityGroupName": {"Ref": "EC2SecurityGroup"},
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
"DBSecurityGroup": {
|
||||
"Type": "AWS::RDS::DBSecurityGroup",
|
||||
"Condition": "Is-EC2-Classic",
|
||||
"Properties": {
|
||||
"DBSecurityGroupIngress": [{
|
||||
"EC2SecurityGroupName": {"Ref": "EC2SecurityGroup"}
|
||||
}],
|
||||
"GroupDescription": "database access"
|
||||
}
|
||||
"DBSecurityGroupIngress": [
|
||||
{"EC2SecurityGroupName": {"Ref": "EC2SecurityGroup"}}
|
||||
],
|
||||
"GroupDescription": "database access",
|
||||
},
|
||||
},
|
||||
|
||||
"my_vpc": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16",
|
||||
}
|
||||
},
|
||||
|
||||
"my_vpc": {"Type": "AWS::EC2::VPC", "Properties": {"CidrBlock": "10.0.0.0/16"}},
|
||||
"EC2Subnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"AvailabilityZone": "eu-central-1a",
|
||||
"CidrBlock": "10.0.1.0/24",
|
||||
"VpcId": {"Ref": "my_vpc"}
|
||||
}
|
||||
"VpcId": {"Ref": "my_vpc"},
|
||||
},
|
||||
},
|
||||
|
||||
"DBSubnet": {
|
||||
"Type": "AWS::RDS::DBSubnetGroup",
|
||||
"Condition": "Is-EC2-VPC",
|
||||
"Properties": {
|
||||
"DBSubnetGroupDescription": "my db subnet group",
|
||||
"SubnetIds": [{"Ref": "EC2Subnet"}],
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
"MasterDB": {
|
||||
"Type": "AWS::RDS::DBInstance",
|
||||
"Properties": {
|
||||
|
|
@ -140,54 +145,79 @@ template = {
|
|||
"AllocatedStorage": {"Ref": "DBAllocatedStorage"},
|
||||
"DBInstanceClass": {"Ref": "DBInstanceClass"},
|
||||
"Engine": "MySQL",
|
||||
"DBSubnetGroupName": {"Fn::If": ["Is-EC2-VPC", {"Ref": "DBSubnet"}, {"Ref": "AWS::NoValue"}]},
|
||||
"DBSubnetGroupName": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-VPC",
|
||||
{"Ref": "DBSubnet"},
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
"MasterUsername": {"Ref": "DBUser"},
|
||||
"MasterUserPassword": {"Ref": "DBPassword"},
|
||||
"MultiAZ": {"Ref": "MultiAZ"},
|
||||
"Tags": [{"Key": "Name", "Value": "Master Database"}],
|
||||
"VPCSecurityGroups": {"Fn::If": ["Is-EC2-VPC", [{"Fn::GetAtt": ["DBEC2SecurityGroup", "GroupId"]}], {"Ref": "AWS::NoValue"}]},
|
||||
"DBSecurityGroups": {"Fn::If": ["Is-EC2-Classic", [{"Ref": "DBSecurityGroup"}], {"Ref": "AWS::NoValue"}]}
|
||||
"VPCSecurityGroups": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-VPC",
|
||||
[{"Fn::GetAtt": ["DBEC2SecurityGroup", "GroupId"]}],
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
"DBSecurityGroups": {
|
||||
"Fn::If": [
|
||||
"Is-EC2-Classic",
|
||||
[{"Ref": "DBSecurityGroup"}],
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
},
|
||||
"DeletionPolicy": "Snapshot"
|
||||
"DeletionPolicy": "Snapshot",
|
||||
},
|
||||
|
||||
"ReplicaDB": {
|
||||
"Type": "AWS::RDS::DBInstance",
|
||||
"Properties": {
|
||||
"SourceDBInstanceIdentifier": {"Ref": "MasterDB"},
|
||||
"DBInstanceClass": {"Ref": "DBInstanceClass"},
|
||||
"Tags": [{"Key": "Name", "Value": "Read Replica Database"}]
|
||||
}
|
||||
}
|
||||
"Tags": [{"Key": "Name", "Value": "Read Replica Database"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"Outputs": {
|
||||
"EC2Platform": {
|
||||
"Description": "Platform in which this stack is deployed",
|
||||
"Value": {"Fn::If": ["Is-EC2-VPC", "EC2-VPC", "EC2-Classic"]}
|
||||
"Value": {"Fn::If": ["Is-EC2-VPC", "EC2-VPC", "EC2-Classic"]},
|
||||
},
|
||||
|
||||
"MasterJDBCConnectionString": {
|
||||
"Description": "JDBC connection string for the master database",
|
||||
"Value": {"Fn::Join": ["", ["jdbc:mysql://",
|
||||
{"Fn::GetAtt": [
|
||||
"MasterDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": [
|
||||
"MasterDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"}]]}
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"jdbc:mysql://",
|
||||
{"Fn::GetAtt": ["MasterDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": ["MasterDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"},
|
||||
],
|
||||
]
|
||||
},
|
||||
},
|
||||
"ReplicaJDBCConnectionString": {
|
||||
"Description": "JDBC connection string for the replica database",
|
||||
"Value": {"Fn::Join": ["", ["jdbc:mysql://",
|
||||
{"Fn::GetAtt": [
|
||||
"ReplicaDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": [
|
||||
"ReplicaDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"}]]}
|
||||
}
|
||||
}
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"jdbc:mysql://",
|
||||
{"Fn::GetAtt": ["ReplicaDB", "Endpoint.Address"]},
|
||||
":",
|
||||
{"Fn::GetAtt": ["ReplicaDB", "Endpoint.Port"]},
|
||||
"/",
|
||||
{"Ref": "DBName"},
|
||||
],
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,35 +7,35 @@ template = {
|
|||
"Description": "The name of the first database to be created when the cluster is created",
|
||||
"Type": "String",
|
||||
"Default": "dev",
|
||||
"AllowedPattern": "([a-z]|[0-9])+"
|
||||
"AllowedPattern": "([a-z]|[0-9])+",
|
||||
},
|
||||
"ClusterType": {
|
||||
"Description": "The type of cluster",
|
||||
"Type": "String",
|
||||
"Default": "single-node",
|
||||
"AllowedValues": ["single-node", "multi-node"]
|
||||
"AllowedValues": ["single-node", "multi-node"],
|
||||
},
|
||||
"NumberOfNodes": {
|
||||
"Description": "The number of compute nodes in the cluster. For multi-node clusters, the NumberOfNodes parameter must be greater than 1",
|
||||
"Type": "Number",
|
||||
"Default": "1"
|
||||
"Default": "1",
|
||||
},
|
||||
"NodeType": {
|
||||
"Description": "The type of node to be provisioned",
|
||||
"Type": "String",
|
||||
"Default": "dw1.xlarge",
|
||||
"AllowedValues": ["dw1.xlarge", "dw1.8xlarge", "dw2.large", "dw2.8xlarge"]
|
||||
"AllowedValues": ["dw1.xlarge", "dw1.8xlarge", "dw2.large", "dw2.8xlarge"],
|
||||
},
|
||||
"MasterUsername": {
|
||||
"Description": "The user name that is associated with the master user account for the cluster that is being created",
|
||||
"Type": "String",
|
||||
"Default": "defaultuser",
|
||||
"AllowedPattern": "([a-z])([a-z]|[0-9])*"
|
||||
"AllowedPattern": "([a-z])([a-z]|[0-9])*",
|
||||
},
|
||||
"MasterUserPassword": {
|
||||
"MasterUserPassword": {
|
||||
"Description": "The password that is associated with the master user account for the cluster that is being created.",
|
||||
"Type": "String",
|
||||
"NoEcho": "true"
|
||||
"NoEcho": "true",
|
||||
},
|
||||
"InboundTraffic": {
|
||||
"Description": "Allow inbound traffic to the cluster from this CIDR range.",
|
||||
|
|
@ -44,18 +44,16 @@ template = {
|
|||
"MaxLength": "18",
|
||||
"Default": "0.0.0.0/0",
|
||||
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||
"ConstraintDescription": "must be a valid CIDR range of the form x.x.x.x/x."
|
||||
"ConstraintDescription": "must be a valid CIDR range of the form x.x.x.x/x.",
|
||||
},
|
||||
"PortNumber": {
|
||||
"Description": "The port number on which the cluster accepts incoming connections.",
|
||||
"Type": "Number",
|
||||
"Default": "5439"
|
||||
}
|
||||
"Default": "5439",
|
||||
},
|
||||
},
|
||||
"Conditions": {
|
||||
"IsMultiNodeCluster": {
|
||||
"Fn::Equals": [{"Ref": "ClusterType"}, "multi-node"]
|
||||
}
|
||||
"IsMultiNodeCluster": {"Fn::Equals": [{"Ref": "ClusterType"}, "multi-node"]}
|
||||
},
|
||||
"Resources": {
|
||||
"RedshiftCluster": {
|
||||
|
|
@ -63,7 +61,13 @@ template = {
|
|||
"DependsOn": "AttachGateway",
|
||||
"Properties": {
|
||||
"ClusterType": {"Ref": "ClusterType"},
|
||||
"NumberOfNodes": {"Fn::If": ["IsMultiNodeCluster", {"Ref": "NumberOfNodes"}, {"Ref": "AWS::NoValue"}]},
|
||||
"NumberOfNodes": {
|
||||
"Fn::If": [
|
||||
"IsMultiNodeCluster",
|
||||
{"Ref": "NumberOfNodes"},
|
||||
{"Ref": "AWS::NoValue"},
|
||||
]
|
||||
},
|
||||
"NodeType": {"Ref": "NodeType"},
|
||||
"DBName": {"Ref": "DatabaseName"},
|
||||
"MasterUsername": {"Ref": "MasterUsername"},
|
||||
|
|
@ -72,116 +76,106 @@ template = {
|
|||
"VpcSecurityGroupIds": [{"Ref": "SecurityGroup"}],
|
||||
"ClusterSubnetGroupName": {"Ref": "RedshiftClusterSubnetGroup"},
|
||||
"PubliclyAccessible": "true",
|
||||
"Port": {"Ref": "PortNumber"}
|
||||
}
|
||||
"Port": {"Ref": "PortNumber"},
|
||||
},
|
||||
},
|
||||
"RedshiftClusterParameterGroup": {
|
||||
"Type": "AWS::Redshift::ClusterParameterGroup",
|
||||
"Properties": {
|
||||
"Description": "Cluster parameter group",
|
||||
"ParameterGroupFamily": "redshift-1.0",
|
||||
"Parameters": [{
|
||||
"ParameterName": "enable_user_activity_logging",
|
||||
"ParameterValue": "true"
|
||||
}]
|
||||
}
|
||||
"Parameters": [
|
||||
{
|
||||
"ParameterName": "enable_user_activity_logging",
|
||||
"ParameterValue": "true",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
"RedshiftClusterSubnetGroup": {
|
||||
"Type": "AWS::Redshift::ClusterSubnetGroup",
|
||||
"Properties": {
|
||||
"Description": "Cluster subnet group",
|
||||
"SubnetIds": [{"Ref": "PublicSubnet"}]
|
||||
}
|
||||
},
|
||||
"VPC": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16"
|
||||
}
|
||||
"SubnetIds": [{"Ref": "PublicSubnet"}],
|
||||
},
|
||||
},
|
||||
"VPC": {"Type": "AWS::EC2::VPC", "Properties": {"CidrBlock": "10.0.0.0/16"}},
|
||||
"PublicSubnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/24",
|
||||
"VpcId": {"Ref": "VPC"}
|
||||
}
|
||||
"Properties": {"CidrBlock": "10.0.0.0/24", "VpcId": {"Ref": "VPC"}},
|
||||
},
|
||||
"SecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Properties": {
|
||||
"GroupDescription": "Security group",
|
||||
"SecurityGroupIngress": [{
|
||||
"CidrIp": {"Ref": "InboundTraffic"},
|
||||
"FromPort": {"Ref": "PortNumber"},
|
||||
"ToPort": {"Ref": "PortNumber"},
|
||||
"IpProtocol": "tcp"
|
||||
}],
|
||||
"VpcId": {"Ref": "VPC"}
|
||||
}
|
||||
},
|
||||
"myInternetGateway": {
|
||||
"Type": "AWS::EC2::InternetGateway"
|
||||
"SecurityGroupIngress": [
|
||||
{
|
||||
"CidrIp": {"Ref": "InboundTraffic"},
|
||||
"FromPort": {"Ref": "PortNumber"},
|
||||
"ToPort": {"Ref": "PortNumber"},
|
||||
"IpProtocol": "tcp",
|
||||
}
|
||||
],
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
},
|
||||
},
|
||||
"myInternetGateway": {"Type": "AWS::EC2::InternetGateway"},
|
||||
"AttachGateway": {
|
||||
"Type": "AWS::EC2::VPCGatewayAttachment",
|
||||
"Properties": {
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"InternetGatewayId": {"Ref": "myInternetGateway"}
|
||||
}
|
||||
"InternetGatewayId": {"Ref": "myInternetGateway"},
|
||||
},
|
||||
},
|
||||
"PublicRouteTable": {
|
||||
"Type": "AWS::EC2::RouteTable",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
}
|
||||
}
|
||||
"Properties": {"VpcId": {"Ref": "VPC"}},
|
||||
},
|
||||
"PublicRoute": {
|
||||
"Type": "AWS::EC2::Route",
|
||||
"DependsOn": "AttachGateway",
|
||||
"Properties": {
|
||||
"RouteTableId": {
|
||||
"Ref": "PublicRouteTable"
|
||||
},
|
||||
"RouteTableId": {"Ref": "PublicRouteTable"},
|
||||
"DestinationCidrBlock": "0.0.0.0/0",
|
||||
"GatewayId": {
|
||||
"Ref": "myInternetGateway"
|
||||
}
|
||||
}
|
||||
"GatewayId": {"Ref": "myInternetGateway"},
|
||||
},
|
||||
},
|
||||
"PublicSubnetRouteTableAssociation": {
|
||||
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
||||
"Properties": {
|
||||
"SubnetId": {
|
||||
"Ref": "PublicSubnet"
|
||||
},
|
||||
"RouteTableId": {
|
||||
"Ref": "PublicRouteTable"
|
||||
}
|
||||
}
|
||||
}
|
||||
"SubnetId": {"Ref": "PublicSubnet"},
|
||||
"RouteTableId": {"Ref": "PublicRouteTable"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Outputs": {
|
||||
"ClusterEndpoint": {
|
||||
"Description": "Cluster endpoint",
|
||||
"Value": {"Fn::Join": [":", [{"Fn::GetAtt": ["RedshiftCluster", "Endpoint.Address"]}, {"Fn::GetAtt": ["RedshiftCluster", "Endpoint.Port"]}]]}
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
":",
|
||||
[
|
||||
{"Fn::GetAtt": ["RedshiftCluster", "Endpoint.Address"]},
|
||||
{"Fn::GetAtt": ["RedshiftCluster", "Endpoint.Port"]},
|
||||
],
|
||||
]
|
||||
},
|
||||
},
|
||||
"ClusterName": {
|
||||
"Description": "Name of cluster",
|
||||
"Value": {"Ref": "RedshiftCluster"}
|
||||
"Value": {"Ref": "RedshiftCluster"},
|
||||
},
|
||||
"ParameterGroupName": {
|
||||
"Description": "Name of parameter group",
|
||||
"Value": {"Ref": "RedshiftClusterParameterGroup"}
|
||||
"Value": {"Ref": "RedshiftClusterParameterGroup"},
|
||||
},
|
||||
"RedshiftClusterSubnetGroupName": {
|
||||
"Description": "Name of cluster subnet group",
|
||||
"Value": {"Ref": "RedshiftClusterSubnetGroup"}
|
||||
"Value": {"Ref": "RedshiftClusterSubnetGroup"},
|
||||
},
|
||||
"RedshiftClusterSecurityGroupName": {
|
||||
"Description": "Name of cluster security group",
|
||||
"Value": {"Ref": "SecurityGroup"}
|
||||
}
|
||||
}
|
||||
"Value": {"Ref": "SecurityGroup"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +1,38 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
template = {
|
||||
"Parameters": {
|
||||
"R53ZoneName": {
|
||||
"Type": "String",
|
||||
"Default": "my_zone"
|
||||
}
|
||||
},
|
||||
|
||||
"Parameters": {"R53ZoneName": {"Type": "String", "Default": "my_zone"}},
|
||||
"Resources": {
|
||||
"Ec2Instance": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "ami-1234abcd",
|
||||
"PrivateIpAddress": "10.0.0.25",
|
||||
}
|
||||
"Properties": {"ImageId": "ami-1234abcd", "PrivateIpAddress": "10.0.0.25"},
|
||||
},
|
||||
|
||||
"HostedZone": {
|
||||
"Type": "AWS::Route53::HostedZone",
|
||||
"Properties": {
|
||||
"Name": {"Ref": "R53ZoneName"}
|
||||
}
|
||||
"Properties": {"Name": {"Ref": "R53ZoneName"}},
|
||||
},
|
||||
|
||||
"myDNSRecord": {
|
||||
"Type": "AWS::Route53::RecordSet",
|
||||
"Properties": {
|
||||
"HostedZoneId": {"Ref": "HostedZone"},
|
||||
"Comment": "DNS name for my instance.",
|
||||
"Name": {
|
||||
"Fn::Join": ["", [
|
||||
{"Ref": "Ec2Instance"}, ".",
|
||||
{"Ref": "AWS::Region"}, ".",
|
||||
{"Ref": "R53ZoneName"}, "."
|
||||
]]
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
{"Ref": "Ec2Instance"},
|
||||
".",
|
||||
{"Ref": "AWS::Region"},
|
||||
".",
|
||||
{"Ref": "R53ZoneName"},
|
||||
".",
|
||||
],
|
||||
]
|
||||
},
|
||||
"Type": "A",
|
||||
"TTL": "900",
|
||||
"ResourceRecords": [
|
||||
{"Fn::GetAtt": ["Ec2Instance", "PrivateIp"]}
|
||||
]
|
||||
}
|
||||
}
|
||||
"ResourceRecords": [{"Fn::GetAtt": ["Ec2Instance", "PrivateIp"]}],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,8 @@ template = {
|
|||
"Resources": {
|
||||
"HostedZone": {
|
||||
"Type": "AWS::Route53::HostedZone",
|
||||
"Properties": {
|
||||
"Name": "my_zone"
|
||||
}
|
||||
"Properties": {"Name": "my_zone"},
|
||||
},
|
||||
|
||||
"my_health_check": {
|
||||
"Type": "AWS::Route53::HealthCheck",
|
||||
"Properties": {
|
||||
|
|
@ -20,9 +17,8 @@ template = {
|
|||
"ResourcePath": "/",
|
||||
"Type": "HTTP",
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
"myDNSRecord": {
|
||||
"Type": "AWS::Route53::RecordSet",
|
||||
"Properties": {
|
||||
|
|
@ -33,7 +29,7 @@ template = {
|
|||
"TTL": "900",
|
||||
"ResourceRecords": ["my.example.com"],
|
||||
"HealthCheckId": {"Ref": "my_health_check"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,53 +2,71 @@ from __future__ import unicode_literals
|
|||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "AWS CloudFormation Sample Template Route53_RoundRobin: Sample template showing how to use weighted round robin (WRR) DNS entried via Amazon Route 53. This contrived sample uses weighted CNAME records to illustrate that the weighting influences the return records. It assumes that you already have a Hosted Zone registered with Amazon Route 53. **WARNING** This template creates one or more AWS resources. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Parameters": {
|
||||
"R53ZoneName": {
|
||||
"Type": "String",
|
||||
"Default": "my_zone"
|
||||
}
|
||||
},
|
||||
|
||||
"Parameters": {"R53ZoneName": {"Type": "String", "Default": "my_zone"}},
|
||||
"Resources": {
|
||||
|
||||
"MyZone": {
|
||||
"Type": "AWS::Route53::HostedZone",
|
||||
"Properties": {
|
||||
"Name": {"Ref": "R53ZoneName"}
|
||||
}
|
||||
"Properties": {"Name": {"Ref": "R53ZoneName"}},
|
||||
},
|
||||
|
||||
"MyDNSRecord": {
|
||||
"Type": "AWS::Route53::RecordSetGroup",
|
||||
"Properties": {
|
||||
"HostedZoneId": {"Ref": "MyZone"},
|
||||
"Comment": "Contrived example to redirect to aws.amazon.com 75% of the time and www.amazon.com 25% of the time.",
|
||||
"RecordSets": [{
|
||||
"SetIdentifier": {"Fn::Join": [" ", [{"Ref": "AWS::StackName"}, "AWS"]]},
|
||||
"Name": {"Fn::Join": ["", [{"Ref": "AWS::StackName"}, ".", {"Ref": "AWS::Region"}, ".", {"Ref": "R53ZoneName"}, "."]]},
|
||||
"Type": "CNAME",
|
||||
"TTL": "900",
|
||||
"ResourceRecords": ["aws.amazon.com"],
|
||||
"Weight": "3"
|
||||
}, {
|
||||
"SetIdentifier": {"Fn::Join": [" ", [{"Ref": "AWS::StackName"}, "Amazon"]]},
|
||||
"Name": {"Fn::Join": ["", [{"Ref": "AWS::StackName"}, ".", {"Ref": "AWS::Region"}, ".", {"Ref": "R53ZoneName"}, "."]]},
|
||||
"Type": "CNAME",
|
||||
"TTL": "900",
|
||||
"ResourceRecords": ["www.amazon.com"],
|
||||
"Weight": "1"
|
||||
}]
|
||||
}
|
||||
}
|
||||
"RecordSets": [
|
||||
{
|
||||
"SetIdentifier": {
|
||||
"Fn::Join": [" ", [{"Ref": "AWS::StackName"}, "AWS"]]
|
||||
},
|
||||
"Name": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
{"Ref": "AWS::StackName"},
|
||||
".",
|
||||
{"Ref": "AWS::Region"},
|
||||
".",
|
||||
{"Ref": "R53ZoneName"},
|
||||
".",
|
||||
],
|
||||
]
|
||||
},
|
||||
"Type": "CNAME",
|
||||
"TTL": "900",
|
||||
"ResourceRecords": ["aws.amazon.com"],
|
||||
"Weight": "3",
|
||||
},
|
||||
{
|
||||
"SetIdentifier": {
|
||||
"Fn::Join": [" ", [{"Ref": "AWS::StackName"}, "Amazon"]]
|
||||
},
|
||||
"Name": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
{"Ref": "AWS::StackName"},
|
||||
".",
|
||||
{"Ref": "AWS::Region"},
|
||||
".",
|
||||
{"Ref": "R53ZoneName"},
|
||||
".",
|
||||
],
|
||||
]
|
||||
},
|
||||
"Type": "CNAME",
|
||||
"TTL": "900",
|
||||
"ResourceRecords": ["www.amazon.com"],
|
||||
"Weight": "1",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"Outputs": {
|
||||
"DomainName": {
|
||||
"Description": "Fully qualified domain name",
|
||||
"Value": {"Ref": "MyDNSRecord"}
|
||||
"Value": {"Ref": "MyDNSRecord"},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ template = {
|
|||
"MinLength": "9",
|
||||
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||
"MaxLength": "18",
|
||||
"Type": "String"
|
||||
"Type": "String",
|
||||
},
|
||||
"KeyName": {
|
||||
"Type": "String",
|
||||
|
|
@ -18,7 +18,7 @@ template = {
|
|||
"MinLength": "1",
|
||||
"AllowedPattern": "[\\x20-\\x7E]*",
|
||||
"MaxLength": "255",
|
||||
"ConstraintDescription": "can contain only ASCII characters."
|
||||
"ConstraintDescription": "can contain only ASCII characters.",
|
||||
},
|
||||
"InstanceType": {
|
||||
"Default": "m1.small",
|
||||
|
|
@ -40,8 +40,8 @@ template = {
|
|||
"c1.xlarge",
|
||||
"cc1.4xlarge",
|
||||
"cc2.8xlarge",
|
||||
"cg1.4xlarge"
|
||||
]
|
||||
"cg1.4xlarge",
|
||||
],
|
||||
},
|
||||
"VolumeSize": {
|
||||
"Description": "WebServer EC2 instance type",
|
||||
|
|
@ -49,8 +49,8 @@ template = {
|
|||
"Type": "Number",
|
||||
"MaxValue": "1024",
|
||||
"MinValue": "5",
|
||||
"ConstraintDescription": "must be between 5 and 1024 Gb."
|
||||
}
|
||||
"ConstraintDescription": "must be between 5 and 1024 Gb.",
|
||||
},
|
||||
},
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Outputs": {
|
||||
|
|
@ -59,17 +59,9 @@ template = {
|
|||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"http://",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"WebServer",
|
||||
"PublicDnsName"
|
||||
]
|
||||
}
|
||||
]
|
||||
["http://", {"Fn::GetAtt": ["WebServer", "PublicDnsName"]}],
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"Resources": {
|
||||
|
|
@ -81,19 +73,17 @@ template = {
|
|||
"ToPort": "80",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": "0.0.0.0/0",
|
||||
"FromPort": "80"
|
||||
"FromPort": "80",
|
||||
},
|
||||
{
|
||||
"ToPort": "22",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": {
|
||||
"Ref": "SSHLocation"
|
||||
},
|
||||
"FromPort": "22"
|
||||
}
|
||||
"CidrIp": {"Ref": "SSHLocation"},
|
||||
"FromPort": "22",
|
||||
},
|
||||
],
|
||||
"GroupDescription": "Enable SSH access and HTTP access on the inbound port"
|
||||
}
|
||||
"GroupDescription": "Enable SSH access and HTTP access on the inbound port",
|
||||
},
|
||||
},
|
||||
"WebServer": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
|
|
@ -108,23 +98,17 @@ template = {
|
|||
"# Helper function\n",
|
||||
"function error_exit\n",
|
||||
"{\n",
|
||||
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '",
|
||||
{
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
' /opt/aws/bin/cfn-signal -e 1 -r "$1" \'',
|
||||
{"Ref": "WaitHandle"},
|
||||
"'\n",
|
||||
" exit 1\n",
|
||||
"}\n",
|
||||
"# Install Rails packages\n",
|
||||
"/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
{"Ref": "AWS::StackId"},
|
||||
" -r WebServer ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
{"Ref": "AWS::Region"},
|
||||
" || error_exit 'Failed to run cfn-init'\n",
|
||||
"# Wait for the EBS volume to show up\n",
|
||||
"while [ ! -e /dev/sdh ]; do echo Waiting for EBS volume to attach; sleep 5; done\n",
|
||||
|
|
@ -137,56 +121,38 @@ template = {
|
|||
"git init\n",
|
||||
"gollum --port 80 --host 0.0.0.0 &\n",
|
||||
"# If all is well so signal success\n",
|
||||
"/opt/aws/bin/cfn-signal -e $? -r \"Rails application setup complete\" '",
|
||||
{
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
"'\n"
|
||||
]
|
||||
'/opt/aws/bin/cfn-signal -e $? -r "Rails application setup complete" \'',
|
||||
{"Ref": "WaitHandle"},
|
||||
"'\n",
|
||||
],
|
||||
]
|
||||
}
|
||||
},
|
||||
"KeyName": {
|
||||
"Ref": "KeyName"
|
||||
},
|
||||
"SecurityGroups": [
|
||||
{
|
||||
"Ref": "WebServerSecurityGroup"
|
||||
}
|
||||
],
|
||||
"InstanceType": {
|
||||
"Ref": "InstanceType"
|
||||
},
|
||||
"KeyName": {"Ref": "KeyName"},
|
||||
"SecurityGroups": [{"Ref": "WebServerSecurityGroup"}],
|
||||
"InstanceType": {"Ref": "InstanceType"},
|
||||
"ImageId": {
|
||||
"Fn::FindInMap": [
|
||||
"AWSRegionArch2AMI",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
{"Ref": "AWS::Region"},
|
||||
{
|
||||
"Fn::FindInMap": [
|
||||
"AWSInstanceType2Arch",
|
||||
{
|
||||
"Ref": "InstanceType"
|
||||
},
|
||||
"Arch"
|
||||
{"Ref": "InstanceType"},
|
||||
"Arch",
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
"Metadata": {
|
||||
"AWS::CloudFormation::Init": {
|
||||
"config": {
|
||||
"packages": {
|
||||
"rubygems": {
|
||||
"nokogiri": [
|
||||
"1.5.10"
|
||||
],
|
||||
"nokogiri": ["1.5.10"],
|
||||
"rdiscount": [],
|
||||
"gollum": [
|
||||
"1.1.1"
|
||||
]
|
||||
"gollum": ["1.1.1"],
|
||||
},
|
||||
"yum": {
|
||||
"libxslt-devel": [],
|
||||
|
|
@ -196,150 +162,99 @@ template = {
|
|||
"ruby-devel": [],
|
||||
"ruby-rdoc": [],
|
||||
"make": [],
|
||||
"libxml2-devel": []
|
||||
}
|
||||
"libxml2-devel": [],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"DataVolume": {
|
||||
"Type": "AWS::EC2::Volume",
|
||||
"Properties": {
|
||||
"Tags": [
|
||||
{
|
||||
"Value": "Gollum Data Volume",
|
||||
"Key": "Usage"
|
||||
}
|
||||
],
|
||||
"AvailabilityZone": {
|
||||
"Fn::GetAtt": [
|
||||
"WebServer",
|
||||
"AvailabilityZone"
|
||||
]
|
||||
},
|
||||
"Tags": [{"Value": "Gollum Data Volume", "Key": "Usage"}],
|
||||
"AvailabilityZone": {"Fn::GetAtt": ["WebServer", "AvailabilityZone"]},
|
||||
"Size": "100",
|
||||
}
|
||||
},
|
||||
},
|
||||
"MountPoint": {
|
||||
"Type": "AWS::EC2::VolumeAttachment",
|
||||
"Properties": {
|
||||
"InstanceId": {
|
||||
"Ref": "WebServer"
|
||||
},
|
||||
"InstanceId": {"Ref": "WebServer"},
|
||||
"Device": "/dev/sdh",
|
||||
"VolumeId": {
|
||||
"Ref": "DataVolume"
|
||||
}
|
||||
}
|
||||
"VolumeId": {"Ref": "DataVolume"},
|
||||
},
|
||||
},
|
||||
"WaitCondition": {
|
||||
"DependsOn": "MountPoint",
|
||||
"Type": "AWS::CloudFormation::WaitCondition",
|
||||
"Properties": {
|
||||
"Handle": {
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
"Timeout": "300"
|
||||
},
|
||||
"Properties": {"Handle": {"Ref": "WaitHandle"}, "Timeout": "300"},
|
||||
"Metadata": {
|
||||
"Comment1": "Note that the WaitCondition is dependent on the volume mount point allowing the volume to be created and attached to the EC2 instance",
|
||||
"Comment2": "The instance bootstrap script waits for the volume to be attached to the instance prior to installing Gollum and signalling completion"
|
||||
}
|
||||
"Comment2": "The instance bootstrap script waits for the volume to be attached to the instance prior to installing Gollum and signalling completion",
|
||||
},
|
||||
},
|
||||
"WaitHandle": {
|
||||
"Type": "AWS::CloudFormation::WaitConditionHandle"
|
||||
}
|
||||
"WaitHandle": {"Type": "AWS::CloudFormation::WaitConditionHandle"},
|
||||
},
|
||||
"Mappings": {
|
||||
"AWSInstanceType2Arch": {
|
||||
"m3.2xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m2.2xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m1.small": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"c1.medium": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cg1.4xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m2.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"t1.micro": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cc1.4xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m1.medium": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cc2.8xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m1.large": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m1.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m2.4xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"c1.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m3.xlarge": {
|
||||
"Arch": "64"
|
||||
}
|
||||
"m3.2xlarge": {"Arch": "64"},
|
||||
"m2.2xlarge": {"Arch": "64"},
|
||||
"m1.small": {"Arch": "64"},
|
||||
"c1.medium": {"Arch": "64"},
|
||||
"cg1.4xlarge": {"Arch": "64HVM"},
|
||||
"m2.xlarge": {"Arch": "64"},
|
||||
"t1.micro": {"Arch": "64"},
|
||||
"cc1.4xlarge": {"Arch": "64HVM"},
|
||||
"m1.medium": {"Arch": "64"},
|
||||
"cc2.8xlarge": {"Arch": "64HVM"},
|
||||
"m1.large": {"Arch": "64"},
|
||||
"m1.xlarge": {"Arch": "64"},
|
||||
"m2.4xlarge": {"Arch": "64"},
|
||||
"c1.xlarge": {"Arch": "64"},
|
||||
"m3.xlarge": {"Arch": "64"},
|
||||
},
|
||||
"AWSRegionArch2AMI": {
|
||||
"ap-southeast-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-b4b0cae6",
|
||||
"64": "ami-beb0caec"
|
||||
"64": "ami-beb0caec",
|
||||
},
|
||||
"ap-southeast-2": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-b3990e89",
|
||||
"64": "ami-bd990e87"
|
||||
"64": "ami-bd990e87",
|
||||
},
|
||||
"us-west-2": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-38fe7308",
|
||||
"64": "ami-30fe7300"
|
||||
"64": "ami-30fe7300",
|
||||
},
|
||||
"us-east-1": {
|
||||
"64HVM": "ami-0da96764",
|
||||
"32": "ami-31814f58",
|
||||
"64": "ami-1b814f72"
|
||||
"64": "ami-1b814f72",
|
||||
},
|
||||
"ap-northeast-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-0644f007",
|
||||
"64": "ami-0a44f00b"
|
||||
"64": "ami-0a44f00b",
|
||||
},
|
||||
"us-west-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-11d68a54",
|
||||
"64": "ami-1bd68a5e"
|
||||
"64": "ami-1bd68a5e",
|
||||
},
|
||||
"eu-west-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-973b06e3",
|
||||
"64": "ami-953b06e1"
|
||||
"64": "ami-953b06e1",
|
||||
},
|
||||
"sa-east-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-3e3be423",
|
||||
"64": "ami-3c3be421"
|
||||
}
|
||||
}
|
||||
}
|
||||
"64": "ami-3c3be421",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
template = {
|
||||
"Resources": {
|
||||
"VPCEIP": {
|
||||
"Type": "AWS::EC2::EIP",
|
||||
"Properties": {
|
||||
"Domain": "vpc"
|
||||
}
|
||||
}
|
||||
}
|
||||
"Resources": {"VPCEIP": {"Type": "AWS::EC2::EIP", "Properties": {"Domain": "vpc"}}}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,33 +6,26 @@ template = {
|
|||
"Resources": {
|
||||
"ENI": {
|
||||
"Type": "AWS::EC2::NetworkInterface",
|
||||
"Properties": {
|
||||
"SubnetId": {"Ref": "Subnet"}
|
||||
}
|
||||
"Properties": {"SubnetId": {"Ref": "Subnet"}},
|
||||
},
|
||||
"Subnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Properties": {
|
||||
"AvailabilityZone": "us-east-1a",
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"CidrBlock": "10.0.0.0/24"
|
||||
}
|
||||
"CidrBlock": "10.0.0.0/24",
|
||||
},
|
||||
},
|
||||
"VPC": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16"
|
||||
}
|
||||
}
|
||||
"VPC": {"Type": "AWS::EC2::VPC", "Properties": {"CidrBlock": "10.0.0.0/16"}},
|
||||
},
|
||||
"Outputs": {
|
||||
"NinjaENI": {
|
||||
"Description": "Elastic IP mapping to Auto-Scaling Group",
|
||||
"Value": {"Ref": "ENI"}
|
||||
"Value": {"Ref": "ENI"},
|
||||
},
|
||||
"ENIIpAddress": {
|
||||
"Description": "ENI's Private IP address",
|
||||
"Value": {"Fn::GetAtt": ["ENI", "PrimaryPrivateIpAddress"]}
|
||||
}
|
||||
}
|
||||
"Value": {"Fn::GetAtt": ["ENI", "PrimaryPrivateIpAddress"]},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ template = {
|
|||
"MinLength": "9",
|
||||
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||
"MaxLength": "18",
|
||||
"Type": "String"
|
||||
"Type": "String",
|
||||
},
|
||||
"KeyName": {
|
||||
"Type": "String",
|
||||
|
|
@ -18,7 +18,7 @@ template = {
|
|||
"MinLength": "1",
|
||||
"AllowedPattern": "[\\x20-\\x7E]*",
|
||||
"MaxLength": "255",
|
||||
"ConstraintDescription": "can contain only ASCII characters."
|
||||
"ConstraintDescription": "can contain only ASCII characters.",
|
||||
},
|
||||
"InstanceType": {
|
||||
"Default": "m1.small",
|
||||
|
|
@ -40,9 +40,9 @@ template = {
|
|||
"c1.xlarge",
|
||||
"cc1.4xlarge",
|
||||
"cc2.8xlarge",
|
||||
"cg1.4xlarge"
|
||||
]
|
||||
}
|
||||
"cg1.4xlarge",
|
||||
],
|
||||
},
|
||||
},
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Outputs": {
|
||||
|
|
@ -51,116 +51,61 @@ template = {
|
|||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"http://",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"WebServerInstance",
|
||||
"PublicIp"
|
||||
]
|
||||
}
|
||||
]
|
||||
["http://", {"Fn::GetAtt": ["WebServerInstance", "PublicIp"]}],
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"Resources": {
|
||||
"Subnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"CidrBlock": "10.0.0.0/24",
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"WebServerWaitHandle": {
|
||||
"Type": "AWS::CloudFormation::WaitConditionHandle"
|
||||
"Tags": [{"Value": {"Ref": "AWS::StackId"}, "Key": "Application"}],
|
||||
},
|
||||
},
|
||||
"WebServerWaitHandle": {"Type": "AWS::CloudFormation::WaitConditionHandle"},
|
||||
"Route": {
|
||||
"Type": "AWS::EC2::Route",
|
||||
"Properties": {
|
||||
"GatewayId": {
|
||||
"Ref": "InternetGateway"
|
||||
},
|
||||
"GatewayId": {"Ref": "InternetGateway"},
|
||||
"DestinationCidrBlock": "0.0.0.0/0",
|
||||
"RouteTableId": {
|
||||
"Ref": "RouteTable"
|
||||
}
|
||||
"RouteTableId": {"Ref": "RouteTable"},
|
||||
},
|
||||
"DependsOn": "AttachGateway"
|
||||
"DependsOn": "AttachGateway",
|
||||
},
|
||||
"SubnetRouteTableAssociation": {
|
||||
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
||||
"Properties": {
|
||||
"SubnetId": {
|
||||
"Ref": "Subnet"
|
||||
},
|
||||
"RouteTableId": {
|
||||
"Ref": "RouteTable"
|
||||
}
|
||||
}
|
||||
"SubnetId": {"Ref": "Subnet"},
|
||||
"RouteTableId": {"Ref": "RouteTable"},
|
||||
},
|
||||
},
|
||||
"InternetGateway": {
|
||||
"Type": "AWS::EC2::InternetGateway",
|
||||
"Properties": {
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
"Tags": [{"Value": {"Ref": "AWS::StackId"}, "Key": "Application"}]
|
||||
},
|
||||
},
|
||||
"RouteTable": {
|
||||
"Type": "AWS::EC2::RouteTable",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"Tags": [{"Value": {"Ref": "AWS::StackId"}, "Key": "Application"}],
|
||||
},
|
||||
},
|
||||
"WebServerWaitCondition": {
|
||||
"Type": "AWS::CloudFormation::WaitCondition",
|
||||
"Properties": {
|
||||
"Handle": {
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
"Timeout": "300"
|
||||
},
|
||||
"DependsOn": "WebServerInstance"
|
||||
"Properties": {"Handle": {"Ref": "WebServerWaitHandle"}, "Timeout": "300"},
|
||||
"DependsOn": "WebServerInstance",
|
||||
},
|
||||
"VPC": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16",
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
"Tags": [{"Value": {"Ref": "AWS::StackId"}, "Key": "Application"}],
|
||||
},
|
||||
},
|
||||
"InstanceSecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
|
|
@ -169,23 +114,19 @@ template = {
|
|||
{
|
||||
"ToPort": "22",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": {
|
||||
"Ref": "SSHLocation"
|
||||
},
|
||||
"FromPort": "22"
|
||||
"CidrIp": {"Ref": "SSHLocation"},
|
||||
"FromPort": "22",
|
||||
},
|
||||
{
|
||||
"ToPort": "80",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": "0.0.0.0/0",
|
||||
"FromPort": "80"
|
||||
}
|
||||
"FromPort": "80",
|
||||
},
|
||||
],
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"GroupDescription": "Enable SSH access via port 22"
|
||||
}
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"GroupDescription": "Enable SSH access via port 22",
|
||||
},
|
||||
},
|
||||
"WebServerInstance": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
|
|
@ -200,71 +141,39 @@ template = {
|
|||
"# Helper function\n",
|
||||
"function error_exit\n",
|
||||
"{\n",
|
||||
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '",
|
||||
{
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
' /opt/aws/bin/cfn-signal -e 1 -r "$1" \'',
|
||||
{"Ref": "WebServerWaitHandle"},
|
||||
"'\n",
|
||||
" exit 1\n",
|
||||
"}\n",
|
||||
"# Install the simple web page\n",
|
||||
"/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
{"Ref": "AWS::StackId"},
|
||||
" -r WebServerInstance ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
{"Ref": "AWS::Region"},
|
||||
" || error_exit 'Failed to run cfn-init'\n",
|
||||
"# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",
|
||||
"/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",
|
||||
"# All done so signal success\n",
|
||||
"/opt/aws/bin/cfn-signal -e 0 -r \"WebServer setup complete\" '",
|
||||
{
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
"'\n"
|
||||
]
|
||||
'/opt/aws/bin/cfn-signal -e 0 -r "WebServer setup complete" \'',
|
||||
{"Ref": "WebServerWaitHandle"},
|
||||
"'\n",
|
||||
],
|
||||
]
|
||||
}
|
||||
},
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
},
|
||||
{
|
||||
"Value": "Bar",
|
||||
"Key": "Foo"
|
||||
}
|
||||
{"Value": {"Ref": "AWS::StackId"}, "Key": "Application"},
|
||||
{"Value": "Bar", "Key": "Foo"},
|
||||
],
|
||||
"SecurityGroupIds": [
|
||||
{
|
||||
"Ref": "InstanceSecurityGroup"
|
||||
}
|
||||
],
|
||||
"KeyName": {
|
||||
"Ref": "KeyName"
|
||||
},
|
||||
"SubnetId": {
|
||||
"Ref": "Subnet"
|
||||
},
|
||||
"SecurityGroupIds": [{"Ref": "InstanceSecurityGroup"}],
|
||||
"KeyName": {"Ref": "KeyName"},
|
||||
"SubnetId": {"Ref": "Subnet"},
|
||||
"ImageId": {
|
||||
"Fn::FindInMap": [
|
||||
"RegionMap",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"AMI"
|
||||
]
|
||||
"Fn::FindInMap": ["RegionMap", {"Ref": "AWS::Region"}, "AMI"]
|
||||
},
|
||||
"InstanceType": {
|
||||
"Ref": "InstanceType"
|
||||
}
|
||||
"InstanceType": {"Ref": "InstanceType"},
|
||||
},
|
||||
"Metadata": {
|
||||
"Comment": "Install a simple PHP application",
|
||||
|
|
@ -278,21 +187,17 @@ template = {
|
|||
[
|
||||
"[main]\n",
|
||||
"stack=",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
{"Ref": "AWS::StackId"},
|
||||
"\n",
|
||||
"region=",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"\n"
|
||||
]
|
||||
{"Ref": "AWS::Region"},
|
||||
"\n",
|
||||
],
|
||||
]
|
||||
},
|
||||
"owner": "root",
|
||||
"group": "root",
|
||||
"mode": "000400"
|
||||
"mode": "000400",
|
||||
},
|
||||
"/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
|
||||
"content": {
|
||||
|
|
@ -303,17 +208,13 @@ template = {
|
|||
"triggers=post.update\n",
|
||||
"path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n",
|
||||
"action=/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
{"Ref": "AWS::StackId"},
|
||||
" -r WebServerInstance ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
{"Ref": "AWS::Region"},
|
||||
"\n",
|
||||
"runas=root\n"
|
||||
]
|
||||
"runas=root\n",
|
||||
],
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -324,85 +225,52 @@ template = {
|
|||
[
|
||||
"<?php\n",
|
||||
"echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",
|
||||
"?>\n"
|
||||
]
|
||||
"?>\n",
|
||||
],
|
||||
]
|
||||
},
|
||||
"owner": "apache",
|
||||
"group": "apache",
|
||||
"mode": "000644"
|
||||
}
|
||||
"mode": "000644",
|
||||
},
|
||||
},
|
||||
"services": {
|
||||
"sysvinit": {
|
||||
"httpd": {
|
||||
"ensureRunning": "true",
|
||||
"enabled": "true"
|
||||
},
|
||||
"httpd": {"ensureRunning": "true", "enabled": "true"},
|
||||
"sendmail": {
|
||||
"ensureRunning": "false",
|
||||
"enabled": "false"
|
||||
}
|
||||
"enabled": "false",
|
||||
},
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"yum": {
|
||||
"httpd": [],
|
||||
"php": []
|
||||
}
|
||||
}
|
||||
"packages": {"yum": {"httpd": [], "php": []}},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"IPAddress": {
|
||||
"Type": "AWS::EC2::EIP",
|
||||
"Properties": {
|
||||
"InstanceId": {
|
||||
"Ref": "WebServerInstance"
|
||||
},
|
||||
"Domain": "vpc"
|
||||
},
|
||||
"DependsOn": "AttachGateway"
|
||||
"Properties": {"InstanceId": {"Ref": "WebServerInstance"}, "Domain": "vpc"},
|
||||
"DependsOn": "AttachGateway",
|
||||
},
|
||||
"AttachGateway": {
|
||||
"Type": "AWS::EC2::VPCGatewayAttachment",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"InternetGatewayId": {
|
||||
"Ref": "InternetGateway"
|
||||
}
|
||||
}
|
||||
}
|
||||
"VpcId": {"Ref": "VPC"},
|
||||
"InternetGatewayId": {"Ref": "InternetGateway"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Mappings": {
|
||||
"RegionMap": {
|
||||
"ap-southeast-1": {
|
||||
"AMI": "ami-74dda626"
|
||||
},
|
||||
"ap-southeast-2": {
|
||||
"AMI": "ami-b3990e89"
|
||||
},
|
||||
"us-west-2": {
|
||||
"AMI": "ami-16fd7026"
|
||||
},
|
||||
"us-east-1": {
|
||||
"AMI": "ami-7f418316"
|
||||
},
|
||||
"ap-northeast-1": {
|
||||
"AMI": "ami-dcfa4edd"
|
||||
},
|
||||
"us-west-1": {
|
||||
"AMI": "ami-951945d0"
|
||||
},
|
||||
"eu-west-1": {
|
||||
"AMI": "ami-24506250"
|
||||
},
|
||||
"sa-east-1": {
|
||||
"AMI": "ami-3e3be423"
|
||||
}
|
||||
"ap-southeast-1": {"AMI": "ami-74dda626"},
|
||||
"ap-southeast-2": {"AMI": "ami-b3990e89"},
|
||||
"us-west-2": {"AMI": "ami-16fd7026"},
|
||||
"us-east-1": {"AMI": "ami-7f418316"},
|
||||
"ap-northeast-1": {"AMI": "ami-dcfa4edd"},
|
||||
"us-west-1": {"AMI": "ami-951945d0"},
|
||||
"eu-west-1": {"AMI": "ami-24506250"},
|
||||
"sa-east-1": {"AMI": "ami-3e3be423"},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,24 @@ import os
|
|||
import json
|
||||
|
||||
import boto
|
||||
import boto.iam
|
||||
import boto.s3
|
||||
import boto.s3.key
|
||||
import boto.cloudformation
|
||||
from boto.exception import BotoServerError
|
||||
import sure # noqa
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises # noqa
|
||||
from nose.tools import assert_raises
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
from moto import mock_cloudformation_deprecated, mock_s3_deprecated, mock_route53_deprecated
|
||||
from moto import (
|
||||
mock_cloudformation_deprecated,
|
||||
mock_s3_deprecated,
|
||||
mock_route53_deprecated,
|
||||
mock_iam_deprecated,
|
||||
)
|
||||
from moto.cloudformation import cloudformation_backends
|
||||
|
||||
dummy_template = {
|
||||
|
|
@ -33,12 +41,7 @@ dummy_template3 = {
|
|||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 3",
|
||||
"Resources": {
|
||||
"VPC": {
|
||||
"Properties": {
|
||||
"CidrBlock": "192.168.0.0/16",
|
||||
},
|
||||
"Type": "AWS::EC2::VPC"
|
||||
}
|
||||
"VPC": {"Properties": {"CidrBlock": "192.168.0.0/16"}, "Type": "AWS::EC2::VPC"}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -50,24 +53,22 @@ dummy_template_json3 = json.dumps(dummy_template3)
|
|||
@mock_cloudformation_deprecated
|
||||
def test_create_stack():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack.stack_name.should.equal('test_stack')
|
||||
stack.get_template().should.equal({
|
||||
'GetTemplateResponse': {
|
||||
'GetTemplateResult': {
|
||||
'TemplateBody': dummy_template_json,
|
||||
'ResponseMetadata': {
|
||||
'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
|
||||
stack.stack_name.should.equal("test_stack")
|
||||
stack.get_template().should.equal(
|
||||
{
|
||||
"GetTemplateResponse": {
|
||||
"GetTemplateResult": {
|
||||
"TemplateBody": dummy_template_json,
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
|
|
@ -77,44 +78,34 @@ def test_create_stack_hosted_zone_by_id():
|
|||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 1",
|
||||
"Parameters": {
|
||||
},
|
||||
"Parameters": {},
|
||||
"Resources": {
|
||||
"Bar": {
|
||||
"Type" : "AWS::Route53::HostedZone",
|
||||
"Properties" : {
|
||||
"Name" : "foo.bar.baz",
|
||||
}
|
||||
},
|
||||
"Type": "AWS::Route53::HostedZone",
|
||||
"Properties": {"Name": "foo.bar.baz"},
|
||||
}
|
||||
},
|
||||
}
|
||||
dummy_template2 = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 2",
|
||||
"Parameters": {
|
||||
"ZoneId": { "Type": "String" }
|
||||
},
|
||||
"Parameters": {"ZoneId": {"Type": "String"}},
|
||||
"Resources": {
|
||||
"Foo": {
|
||||
"Properties": {
|
||||
"HostedZoneId": {"Ref": "ZoneId"},
|
||||
"RecordSets": []
|
||||
},
|
||||
"Type": "AWS::Route53::RecordSetGroup"
|
||||
"Properties": {"HostedZoneId": {"Ref": "ZoneId"}, "RecordSets": []},
|
||||
"Type": "AWS::Route53::RecordSetGroup",
|
||||
}
|
||||
},
|
||||
}
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=json.dumps(dummy_template),
|
||||
parameters={}.items()
|
||||
"test_stack", template_body=json.dumps(dummy_template), parameters={}.items()
|
||||
)
|
||||
r53_conn = boto.connect_route53()
|
||||
zone_id = r53_conn.get_zones()[0].id
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=json.dumps(dummy_template2),
|
||||
parameters={"ZoneId": zone_id}.items()
|
||||
parameters={"ZoneId": zone_id}.items(),
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
|
|
@ -139,62 +130,57 @@ def test_create_stack_with_notification_arn():
|
|||
conn.create_stack(
|
||||
"test_stack_with_notifications",
|
||||
template_body=dummy_template_json,
|
||||
notification_arns='arn:aws:sns:us-east-1:123456789012:fake-queue'
|
||||
notification_arns="arn:aws:sns:us-east-1:{}:fake-queue".format(ACCOUNT_ID),
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
[n.value for n in stack.notification_arns].should.contain(
|
||||
'arn:aws:sns:us-east-1:123456789012:fake-queue')
|
||||
"arn:aws:sns:us-east-1:{}:fake-queue".format(ACCOUNT_ID)
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
@mock_s3_deprecated
|
||||
def test_create_stack_from_s3_url():
|
||||
s3_conn = boto.s3.connect_to_region('us-west-1')
|
||||
s3_conn = boto.s3.connect_to_region("us-west-1")
|
||||
bucket = s3_conn.create_bucket("foobar")
|
||||
key = boto.s3.key.Key(bucket)
|
||||
key.key = "template-key"
|
||||
key.set_contents_from_string(dummy_template_json)
|
||||
key_url = key.generate_url(expires_in=0, query_auth=False)
|
||||
|
||||
conn = boto.cloudformation.connect_to_region('us-west-1')
|
||||
conn.create_stack('new-stack', template_url=key_url)
|
||||
conn = boto.cloudformation.connect_to_region("us-west-1")
|
||||
conn.create_stack("new-stack", template_url=key_url)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack.stack_name.should.equal('new-stack')
|
||||
stack.stack_name.should.equal("new-stack")
|
||||
stack.get_template().should.equal(
|
||||
{
|
||||
'GetTemplateResponse': {
|
||||
'GetTemplateResult': {
|
||||
'TemplateBody': dummy_template_json,
|
||||
'ResponseMetadata': {
|
||||
'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
|
||||
}
|
||||
"GetTemplateResponse": {
|
||||
"GetTemplateResult": {
|
||||
"TemplateBody": dummy_template_json,
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
def test_describe_stack_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
stack = conn.describe_stacks("test_stack")[0]
|
||||
stack.stack_name.should.equal('test_stack')
|
||||
stack.stack_name.should.equal("test_stack")
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
def test_describe_stack_by_stack_id():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
stack = conn.describe_stacks("test_stack")[0]
|
||||
stack_by_id = conn.describe_stacks(stack.stack_id)[0]
|
||||
|
|
@ -205,10 +191,7 @@ def test_describe_stack_by_stack_id():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_describe_deleted_stack():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
stack = conn.describe_stacks("test_stack")[0]
|
||||
stack_id = stack.stack_id
|
||||
|
|
@ -222,36 +205,28 @@ def test_describe_deleted_stack():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_get_template_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
template = conn.get_template("test_stack")
|
||||
template.should.equal({
|
||||
'GetTemplateResponse': {
|
||||
'GetTemplateResult': {
|
||||
'TemplateBody': dummy_template_json,
|
||||
'ResponseMetadata': {
|
||||
'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
|
||||
template.should.equal(
|
||||
{
|
||||
"GetTemplateResponse": {
|
||||
"GetTemplateResult": {
|
||||
"TemplateBody": dummy_template_json,
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
def test_list_stacks():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack(
|
||||
"test_stack2",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
conn.create_stack("test_stack2", template_body=dummy_template_json)
|
||||
|
||||
stacks = conn.list_stacks()
|
||||
stacks.should.have.length_of(2)
|
||||
|
|
@ -261,10 +236,7 @@ def test_list_stacks():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_delete_stack_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
conn.describe_stacks().should.have.length_of(1)
|
||||
conn.delete_stack("test_stack")
|
||||
|
|
@ -274,10 +246,7 @@ def test_delete_stack_by_name():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_delete_stack_by_id():
|
||||
conn = boto.connect_cloudformation()
|
||||
stack_id = conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
conn.describe_stacks().should.have.length_of(1)
|
||||
conn.delete_stack(stack_id)
|
||||
|
|
@ -291,10 +260,7 @@ def test_delete_stack_by_id():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_delete_stack_with_resource_missing_delete_attr():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json3,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json3)
|
||||
|
||||
conn.describe_stacks().should.have.length_of(1)
|
||||
conn.delete_stack("test_stack")
|
||||
|
|
@ -318,19 +284,22 @@ def test_cloudformation_params():
|
|||
"APPNAME": {
|
||||
"Default": "app-name",
|
||||
"Description": "The name of the app",
|
||||
"Type": "String"
|
||||
"Type": "String",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
cfn = boto.connect_cloudformation()
|
||||
cfn.create_stack('test_stack1', template_body=dummy_template_json, parameters=[
|
||||
('APPNAME', 'testing123')])
|
||||
stack = cfn.describe_stacks('test_stack1')[0]
|
||||
cfn.create_stack(
|
||||
"test_stack1",
|
||||
template_body=dummy_template_json,
|
||||
parameters=[("APPNAME", "testing123")],
|
||||
)
|
||||
stack = cfn.describe_stacks("test_stack1")[0]
|
||||
stack.parameters.should.have.length_of(1)
|
||||
param = stack.parameters[0]
|
||||
param.key.should.equal('APPNAME')
|
||||
param.value.should.equal('testing123')
|
||||
param.key.should.equal("APPNAME")
|
||||
param.value.should.equal("testing123")
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
|
|
@ -339,52 +308,34 @@ def test_cloudformation_params_conditions_and_resources_are_distinct():
|
|||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 1",
|
||||
"Conditions": {
|
||||
"FooEnabled": {
|
||||
"Fn::Equals": [
|
||||
{
|
||||
"Ref": "FooEnabled"
|
||||
},
|
||||
"true"
|
||||
]
|
||||
},
|
||||
"FooEnabled": {"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]},
|
||||
"FooDisabled": {
|
||||
"Fn::Not": [
|
||||
{
|
||||
"Fn::Equals": [
|
||||
{
|
||||
"Ref": "FooEnabled"
|
||||
},
|
||||
"true"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
"Fn::Not": [{"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]}]
|
||||
},
|
||||
},
|
||||
"Parameters": {
|
||||
"FooEnabled": {
|
||||
"Type": "String",
|
||||
"AllowedValues": [
|
||||
"true",
|
||||
"false"
|
||||
]
|
||||
}
|
||||
"FooEnabled": {"Type": "String", "AllowedValues": ["true", "false"]}
|
||||
},
|
||||
"Resources": {
|
||||
"Bar": {
|
||||
"Properties": {
|
||||
"CidrBlock": "192.168.0.0/16",
|
||||
},
|
||||
"Properties": {"CidrBlock": "192.168.0.0/16"},
|
||||
"Condition": "FooDisabled",
|
||||
"Type": "AWS::EC2::VPC"
|
||||
"Type": "AWS::EC2::VPC",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
cfn = boto.connect_cloudformation()
|
||||
cfn.create_stack('test_stack1', template_body=dummy_template_json, parameters=[('FooEnabled', 'true')])
|
||||
stack = cfn.describe_stacks('test_stack1')[0]
|
||||
cfn.create_stack(
|
||||
"test_stack1",
|
||||
template_body=dummy_template_json,
|
||||
parameters=[("FooEnabled", "true")],
|
||||
)
|
||||
stack = cfn.describe_stacks("test_stack1")[0]
|
||||
resources = stack.list_resources()
|
||||
assert not [resource for resource in resources if resource.logical_resource_id == 'Bar']
|
||||
assert not [
|
||||
resource for resource in resources if resource.logical_resource_id == "Bar"
|
||||
]
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
|
|
@ -403,48 +354,46 @@ def test_stack_tags():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_update_stack():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
conn.update_stack("test_stack", dummy_template_json2)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack.stack_status.should.equal("UPDATE_COMPLETE")
|
||||
stack.get_template().should.equal({
|
||||
'GetTemplateResponse': {
|
||||
'GetTemplateResult': {
|
||||
'TemplateBody': dummy_template_json2,
|
||||
'ResponseMetadata': {
|
||||
'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
|
||||
stack.get_template().should.equal(
|
||||
{
|
||||
"GetTemplateResponse": {
|
||||
"GetTemplateResult": {
|
||||
"TemplateBody": dummy_template_json2,
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
def test_update_stack_with_previous_template():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
conn.update_stack("test_stack", use_previous_template=True)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack.stack_status.should.equal("UPDATE_COMPLETE")
|
||||
stack.get_template().should.equal({
|
||||
'GetTemplateResponse': {
|
||||
'GetTemplateResult': {
|
||||
'TemplateBody': dummy_template_json,
|
||||
'ResponseMetadata': {
|
||||
'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
|
||||
stack.get_template().should.equal(
|
||||
{
|
||||
"GetTemplateResponse": {
|
||||
"GetTemplateResult": {
|
||||
"TemplateBody": dummy_template_json,
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
|
|
@ -454,29 +403,23 @@ def test_update_stack_with_parameters():
|
|||
"Description": "Stack",
|
||||
"Resources": {
|
||||
"VPC": {
|
||||
"Properties": {
|
||||
"CidrBlock": {"Ref": "Bar"}
|
||||
},
|
||||
"Type": "AWS::EC2::VPC"
|
||||
"Properties": {"CidrBlock": {"Ref": "Bar"}},
|
||||
"Type": "AWS::EC2::VPC",
|
||||
}
|
||||
},
|
||||
"Parameters": {
|
||||
"Bar": {
|
||||
"Type": "String"
|
||||
}
|
||||
}
|
||||
"Parameters": {"Bar": {"Type": "String"}},
|
||||
}
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
parameters=[("Bar", "192.168.0.0/16")]
|
||||
parameters=[("Bar", "192.168.0.0/16")],
|
||||
)
|
||||
conn.update_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
parameters=[("Bar", "192.168.0.1/16")]
|
||||
parameters=[("Bar", "192.168.0.1/16")],
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
|
|
@ -487,14 +430,10 @@ def test_update_stack_with_parameters():
|
|||
def test_update_stack_replace_tags():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
tags={"foo": "bar"},
|
||||
"test_stack", template_body=dummy_template_json, tags={"foo": "bar"}
|
||||
)
|
||||
conn.update_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
tags={"foo": "baz"},
|
||||
"test_stack", template_body=dummy_template_json, tags={"foo": "baz"}
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
|
|
@ -506,28 +445,26 @@ def test_update_stack_replace_tags():
|
|||
@mock_cloudformation_deprecated
|
||||
def test_update_stack_when_rolled_back():
|
||||
conn = boto.connect_cloudformation()
|
||||
stack_id = conn.create_stack(
|
||||
"test_stack", template_body=dummy_template_json)
|
||||
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
|
||||
cloudformation_backends[conn.region.name].stacks[
|
||||
stack_id].status = 'ROLLBACK_COMPLETE'
|
||||
stack_id
|
||||
].status = "ROLLBACK_COMPLETE"
|
||||
|
||||
with assert_raises(BotoServerError) as err:
|
||||
conn.update_stack("test_stack", dummy_template_json)
|
||||
|
||||
ex = err.exception
|
||||
ex.body.should.match(
|
||||
r'is in ROLLBACK_COMPLETE state and can not be updated')
|
||||
ex.error_code.should.equal('ValidationError')
|
||||
ex.reason.should.equal('Bad Request')
|
||||
ex.body.should.match(r"is in ROLLBACK_COMPLETE state and can not be updated")
|
||||
ex.error_code.should.equal("ValidationError")
|
||||
ex.reason.should.equal("Bad Request")
|
||||
ex.status.should.equal(400)
|
||||
|
||||
|
||||
@mock_cloudformation_deprecated
|
||||
def test_describe_stack_events_shows_create_update_and_delete():
|
||||
conn = boto.connect_cloudformation()
|
||||
stack_id = conn.create_stack(
|
||||
"test_stack", template_body=dummy_template_json)
|
||||
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
|
||||
conn.update_stack(stack_id, template_body=dummy_template_json2)
|
||||
conn.delete_stack(stack_id)
|
||||
|
||||
|
|
@ -538,14 +475,16 @@ def test_describe_stack_events_shows_create_update_and_delete():
|
|||
|
||||
# testing ordering of stack events without assuming resource events will not exist
|
||||
# the AWS API returns events in reverse chronological order
|
||||
stack_events_to_look_for = iter([
|
||||
("DELETE_COMPLETE", None),
|
||||
("DELETE_IN_PROGRESS", "User Initiated"),
|
||||
("UPDATE_COMPLETE", None),
|
||||
("UPDATE_IN_PROGRESS", "User Initiated"),
|
||||
("CREATE_COMPLETE", None),
|
||||
("CREATE_IN_PROGRESS", "User Initiated"),
|
||||
])
|
||||
stack_events_to_look_for = iter(
|
||||
[
|
||||
("DELETE_COMPLETE", None),
|
||||
("DELETE_IN_PROGRESS", "User Initiated"),
|
||||
("UPDATE_COMPLETE", None),
|
||||
("UPDATE_IN_PROGRESS", "User Initiated"),
|
||||
("CREATE_COMPLETE", None),
|
||||
("CREATE_IN_PROGRESS", "User Initiated"),
|
||||
]
|
||||
)
|
||||
try:
|
||||
for event in events:
|
||||
event.stack_id.should.equal(stack_id)
|
||||
|
|
@ -556,12 +495,10 @@ def test_describe_stack_events_shows_create_update_and_delete():
|
|||
event.logical_resource_id.should.equal("test_stack")
|
||||
event.physical_resource_id.should.equal(stack_id)
|
||||
|
||||
status_to_look_for, reason_to_look_for = next(
|
||||
stack_events_to_look_for)
|
||||
status_to_look_for, reason_to_look_for = next(stack_events_to_look_for)
|
||||
event.resource_status.should.equal(status_to_look_for)
|
||||
if reason_to_look_for is not None:
|
||||
event.resource_status_reason.should.equal(
|
||||
reason_to_look_for)
|
||||
event.resource_status_reason.should.equal(reason_to_look_for)
|
||||
except StopIteration:
|
||||
assert False, "Too many stack events"
|
||||
|
||||
|
|
@ -574,74 +511,60 @@ def test_create_stack_lambda_and_dynamodb():
|
|||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack Lambda Test 1",
|
||||
"Parameters": {
|
||||
},
|
||||
"Parameters": {},
|
||||
"Resources": {
|
||||
"func1": {
|
||||
"Type" : "AWS::Lambda::Function",
|
||||
"Properties" : {
|
||||
"Code": {
|
||||
"S3Bucket": "bucket_123",
|
||||
"S3Key": "key_123"
|
||||
},
|
||||
"Type": "AWS::Lambda::Function",
|
||||
"Properties": {
|
||||
"Code": {"S3Bucket": "bucket_123", "S3Key": "key_123"},
|
||||
"FunctionName": "func1",
|
||||
"Handler": "handler.handler",
|
||||
"Role": "role1",
|
||||
"Role": get_role_name(),
|
||||
"Runtime": "python2.7",
|
||||
"Description": "descr",
|
||||
"MemorySize": 12345,
|
||||
}
|
||||
},
|
||||
},
|
||||
"func1version": {
|
||||
"Type": "AWS::Lambda::Version",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Ref": "func1"
|
||||
}
|
||||
}
|
||||
"Properties": {"FunctionName": {"Ref": "func1"}},
|
||||
},
|
||||
"tab1": {
|
||||
"Type" : "AWS::DynamoDB::Table",
|
||||
"Properties" : {
|
||||
"Type": "AWS::DynamoDB::Table",
|
||||
"Properties": {
|
||||
"TableName": "tab1",
|
||||
"KeySchema": [{
|
||||
"AttributeName": "attr1",
|
||||
"KeyType": "HASH"
|
||||
}],
|
||||
"AttributeDefinitions": [{
|
||||
"AttributeName": "attr1",
|
||||
"AttributeType": "string"
|
||||
}],
|
||||
"KeySchema": [{"AttributeName": "attr1", "KeyType": "HASH"}],
|
||||
"AttributeDefinitions": [
|
||||
{"AttributeName": "attr1", "AttributeType": "string"}
|
||||
],
|
||||
"ProvisionedThroughput": {
|
||||
"ReadCapacityUnits": 10,
|
||||
"WriteCapacityUnits": 10
|
||||
}
|
||||
}
|
||||
"WriteCapacityUnits": 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
"func1mapping": {
|
||||
"Type": "AWS::Lambda::EventSourceMapping",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Ref": "func1"
|
||||
},
|
||||
"FunctionName": {"Ref": "func1"},
|
||||
"EventSourceArn": "arn:aws:dynamodb:region:XXXXXX:table/tab1/stream/2000T00:00:00.000",
|
||||
"StartingPosition": "0",
|
||||
"BatchSize": 100,
|
||||
"Enabled": True
|
||||
}
|
||||
}
|
||||
"Enabled": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
validate_s3_before = os.environ.get('VALIDATE_LAMBDA_S3', '')
|
||||
validate_s3_before = os.environ.get("VALIDATE_LAMBDA_S3", "")
|
||||
try:
|
||||
os.environ['VALIDATE_LAMBDA_S3'] = 'false'
|
||||
os.environ["VALIDATE_LAMBDA_S3"] = "false"
|
||||
conn.create_stack(
|
||||
"test_stack_lambda_1",
|
||||
template_body=json.dumps(dummy_template),
|
||||
parameters={}.items()
|
||||
parameters={}.items(),
|
||||
)
|
||||
finally:
|
||||
os.environ['VALIDATE_LAMBDA_S3'] = validate_s3_before
|
||||
os.environ["VALIDATE_LAMBDA_S3"] = validate_s3_before
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.list_resources()
|
||||
|
|
@ -657,20 +580,26 @@ def test_create_stack_kinesis():
|
|||
"Parameters": {},
|
||||
"Resources": {
|
||||
"stream1": {
|
||||
"Type" : "AWS::Kinesis::Stream",
|
||||
"Properties" : {
|
||||
"Name": "stream1",
|
||||
"ShardCount": 2
|
||||
}
|
||||
"Type": "AWS::Kinesis::Stream",
|
||||
"Properties": {"Name": "stream1", "ShardCount": 2},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
conn.create_stack(
|
||||
"test_stack_kinesis_1",
|
||||
template_body=json.dumps(dummy_template),
|
||||
parameters={}.items()
|
||||
parameters={}.items(),
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.list_resources()
|
||||
assert len(resources) == 1
|
||||
|
||||
|
||||
def get_role_name():
|
||||
with mock_iam_deprecated():
|
||||
iam = boto.connect_iam()
|
||||
role = iam.create_role("my-role")["create_role_response"]["create_role_result"][
|
||||
"role"
|
||||
]["arn"]
|
||||
return role
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,87 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
# Standard library modules
|
||||
import unittest
|
||||
|
||||
# Third-party modules
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
# Package modules
|
||||
from moto import mock_cloudformation
|
||||
|
||||
AWS_REGION = 'us-west-1'
|
||||
|
||||
SG_STACK_NAME = 'simple-sg-stack'
|
||||
SG_TEMPLATE = """
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Simple test CF template for moto_cloudformation
|
||||
|
||||
|
||||
Resources:
|
||||
SimpleSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Description: "A simple security group"
|
||||
Properties:
|
||||
GroupName: simple-security-group
|
||||
GroupDescription: "A simple security group"
|
||||
SecurityGroupEgress:
|
||||
-
|
||||
Description: "Egress to remote HTTPS servers"
|
||||
CidrIp: 0.0.0.0/0
|
||||
IpProtocol: tcp
|
||||
FromPort: 443
|
||||
ToPort: 443
|
||||
|
||||
Outputs:
|
||||
SimpleSecurityGroupName:
|
||||
Value: !GetAtt SimpleSecurityGroup.GroupId
|
||||
Export:
|
||||
Name: "SimpleSecurityGroup"
|
||||
|
||||
"""
|
||||
|
||||
EC2_STACK_NAME = 'simple-ec2-stack'
|
||||
EC2_TEMPLATE = """
|
||||
---
|
||||
# The latest template format version is "2010-09-09" and as of 2018-04-09
|
||||
# is currently the only valid value.
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Simple test CF template for moto_cloudformation
|
||||
|
||||
|
||||
Resources:
|
||||
SimpleInstance:
|
||||
Type: AWS::EC2::Instance
|
||||
Properties:
|
||||
ImageId: ami-03cf127a
|
||||
InstanceType: t2.micro
|
||||
SecurityGroups: !Split [',', !ImportValue SimpleSecurityGroup]
|
||||
"""
|
||||
|
||||
|
||||
class TestSimpleInstance(unittest.TestCase):
|
||||
def test_simple_instance(self):
|
||||
"""Test that we can create a simple CloudFormation stack that imports values from an existing CloudFormation stack"""
|
||||
with mock_cloudformation():
|
||||
client = boto3.client('cloudformation', region_name=AWS_REGION)
|
||||
client.create_stack(StackName=SG_STACK_NAME, TemplateBody=SG_TEMPLATE)
|
||||
response = client.create_stack(StackName=EC2_STACK_NAME, TemplateBody=EC2_TEMPLATE)
|
||||
self.assertIn('StackId', response)
|
||||
response = client.describe_stacks(StackName=response['StackId'])
|
||||
self.assertIn('Stacks', response)
|
||||
stack_info = response['Stacks']
|
||||
self.assertEqual(1, len(stack_info))
|
||||
self.assertIn('StackName', stack_info[0])
|
||||
self.assertEqual(EC2_STACK_NAME, stack_info[0]['StackName'])
|
||||
|
||||
def test_simple_instance_missing_export(self):
|
||||
"""Test that we get an exception if a CloudFormation stack tries to imports a non-existent export value"""
|
||||
with mock_cloudformation():
|
||||
client = boto3.client('cloudformation', region_name=AWS_REGION)
|
||||
with self.assertRaises(ClientError) as e:
|
||||
client.create_stack(StackName=EC2_STACK_NAME, TemplateBody=EC2_TEMPLATE)
|
||||
self.assertIn('Error', e.exception.response)
|
||||
self.assertIn('Code', e.exception.response['Error'])
|
||||
self.assertEqual('ExportNotFound', e.exception.response['Error']['Code'])
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
# Standard library modules
|
||||
import unittest
|
||||
|
||||
# Third-party modules
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
# Package modules
|
||||
from moto import mock_cloudformation
|
||||
|
||||
AWS_REGION = "us-west-1"
|
||||
|
||||
SG_STACK_NAME = "simple-sg-stack"
|
||||
SG_TEMPLATE = """
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Simple test CF template for moto_cloudformation
|
||||
|
||||
|
||||
Resources:
|
||||
SimpleSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Description: "A simple security group"
|
||||
Properties:
|
||||
GroupName: simple-security-group
|
||||
GroupDescription: "A simple security group"
|
||||
SecurityGroupEgress:
|
||||
-
|
||||
Description: "Egress to remote HTTPS servers"
|
||||
CidrIp: 0.0.0.0/0
|
||||
IpProtocol: tcp
|
||||
FromPort: 443
|
||||
ToPort: 443
|
||||
|
||||
Outputs:
|
||||
SimpleSecurityGroupName:
|
||||
Value: !GetAtt SimpleSecurityGroup.GroupId
|
||||
Export:
|
||||
Name: "SimpleSecurityGroup"
|
||||
|
||||
"""
|
||||
|
||||
EC2_STACK_NAME = "simple-ec2-stack"
|
||||
EC2_TEMPLATE = """
|
||||
---
|
||||
# The latest template format version is "2010-09-09" and as of 2018-04-09
|
||||
# is currently the only valid value.
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Simple test CF template for moto_cloudformation
|
||||
|
||||
|
||||
Resources:
|
||||
SimpleInstance:
|
||||
Type: AWS::EC2::Instance
|
||||
Properties:
|
||||
ImageId: ami-03cf127a
|
||||
InstanceType: t2.micro
|
||||
SecurityGroups: !Split [',', !ImportValue SimpleSecurityGroup]
|
||||
"""
|
||||
|
||||
|
||||
class TestSimpleInstance(unittest.TestCase):
|
||||
def test_simple_instance(self):
|
||||
"""Test that we can create a simple CloudFormation stack that imports values from an existing CloudFormation stack"""
|
||||
with mock_cloudformation():
|
||||
client = boto3.client("cloudformation", region_name=AWS_REGION)
|
||||
client.create_stack(StackName=SG_STACK_NAME, TemplateBody=SG_TEMPLATE)
|
||||
response = client.create_stack(
|
||||
StackName=EC2_STACK_NAME, TemplateBody=EC2_TEMPLATE
|
||||
)
|
||||
self.assertIn("StackId", response)
|
||||
response = client.describe_stacks(StackName=response["StackId"])
|
||||
self.assertIn("Stacks", response)
|
||||
stack_info = response["Stacks"]
|
||||
self.assertEqual(1, len(stack_info))
|
||||
self.assertIn("StackName", stack_info[0])
|
||||
self.assertEqual(EC2_STACK_NAME, stack_info[0]["StackName"])
|
||||
|
||||
def test_simple_instance_missing_export(self):
|
||||
"""Test that we get an exception if a CloudFormation stack tries to imports a non-existent export value"""
|
||||
with mock_cloudformation():
|
||||
client = boto3.client("cloudformation", region_name=AWS_REGION)
|
||||
with self.assertRaises(ClientError) as e:
|
||||
client.create_stack(StackName=EC2_STACK_NAME, TemplateBody=EC2_TEMPLATE)
|
||||
self.assertIn("Error", e.exception.response)
|
||||
self.assertIn("Code", e.exception.response["Error"])
|
||||
self.assertEqual("ExportNotFound", e.exception.response["Error"]["Code"])
|
||||
|
|
|
|||
|
|
@ -1,33 +1,36 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
from six.moves.urllib.parse import urlencode
|
||||
import re
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
def test_cloudformation_server_get():
|
||||
backend = server.create_backend_app("cloudformation")
|
||||
stack_name = 'test stack'
|
||||
test_client = backend.test_client()
|
||||
template_body = {
|
||||
"Resources": {},
|
||||
}
|
||||
create_stack_resp = test_client.action_data("CreateStack", StackName=stack_name,
|
||||
TemplateBody=json.dumps(template_body))
|
||||
create_stack_resp.should.match(
|
||||
r"<CreateStackResponse>.*<CreateStackResult>.*<StackId>.*</StackId>.*</CreateStackResult>.*</CreateStackResponse>", re.DOTALL)
|
||||
stack_id_from_create_response = re.search(
|
||||
"<StackId>(.*)</StackId>", create_stack_resp).groups()[0]
|
||||
|
||||
list_stacks_resp = test_client.action_data("ListStacks")
|
||||
stack_id_from_list_response = re.search(
|
||||
"<StackId>(.*)</StackId>", list_stacks_resp).groups()[0]
|
||||
|
||||
stack_id_from_create_response.should.equal(stack_id_from_list_response)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
from six.moves.urllib.parse import urlencode
|
||||
import re
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
def test_cloudformation_server_get():
|
||||
backend = server.create_backend_app("cloudformation")
|
||||
stack_name = "test stack"
|
||||
test_client = backend.test_client()
|
||||
template_body = {"Resources": {}}
|
||||
create_stack_resp = test_client.action_data(
|
||||
"CreateStack", StackName=stack_name, TemplateBody=json.dumps(template_body)
|
||||
)
|
||||
create_stack_resp.should.match(
|
||||
r"<CreateStackResponse>.*<CreateStackResult>.*<StackId>.*</StackId>.*</CreateStackResult>.*</CreateStackResponse>",
|
||||
re.DOTALL,
|
||||
)
|
||||
stack_id_from_create_response = re.search(
|
||||
"<StackId>(.*)</StackId>", create_stack_resp
|
||||
).groups()[0]
|
||||
|
||||
list_stacks_resp = test_client.action_data("ListStacks")
|
||||
stack_id_from_list_response = re.search(
|
||||
"<StackId>(.*)</StackId>", list_stacks_resp
|
||||
).groups()[0]
|
||||
|
||||
stack_id_from_create_response.should.equal(stack_id_from_list_response)
|
||||
|
|
|
|||
|
|
@ -7,91 +7,57 @@ import sure # noqa
|
|||
|
||||
from moto.cloudformation.exceptions import ValidationError
|
||||
from moto.cloudformation.models import FakeStack
|
||||
from moto.cloudformation.parsing import resource_class_from_type, parse_condition, Export
|
||||
from moto.cloudformation.parsing import (
|
||||
resource_class_from_type,
|
||||
parse_condition,
|
||||
Export,
|
||||
)
|
||||
from moto.sqs.models import Queue
|
||||
from moto.s3.models import FakeBucket
|
||||
from moto.cloudformation.utils import yaml_tag_constructor
|
||||
from boto.cloudformation.stack import Output
|
||||
|
||||
|
||||
|
||||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "Create a multi-az, load balanced, Auto Scaled sample web site. The Auto Scaling trigger is based on the CPU utilization of the web servers. The AMI is chosen based on the region in which the stack is run. This example creates a web service running across all availability zones in a region. The instances are load balanced with a simple health check. The web site is available on port 80, however, the instances can be configured to listen on any port (8888 by default). **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Resources": {
|
||||
"Queue": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": "my-queue",
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
"S3Bucket": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"DeletionPolicy": "Retain"
|
||||
"Properties": {"QueueName": "my-queue", "VisibilityTimeout": 60},
|
||||
},
|
||||
"S3Bucket": {"Type": "AWS::S3::Bucket", "DeletionPolicy": "Retain"},
|
||||
},
|
||||
}
|
||||
|
||||
name_type_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "Create a multi-az, load balanced, Auto Scaled sample web site. The Auto Scaling trigger is based on the CPU utilization of the web servers. The AMI is chosen based on the region in which the stack is run. This example creates a web service running across all availability zones in a region. The instances are load balanced with a simple health check. The web site is available on port 80, however, the instances can be configured to listen on any port (8888 by default). **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Resources": {
|
||||
"Queue": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
"Queue": {"Type": "AWS::SQS::Queue", "Properties": {"VisibilityTimeout": 60}}
|
||||
},
|
||||
}
|
||||
|
||||
output_dict = {
|
||||
"Outputs": {
|
||||
"Output1": {
|
||||
"Value": {"Ref": "Queue"},
|
||||
"Description": "This is a description."
|
||||
}
|
||||
"Output1": {"Value": {"Ref": "Queue"}, "Description": "This is a description."}
|
||||
}
|
||||
}
|
||||
|
||||
bad_output = {
|
||||
"Outputs": {
|
||||
"Output1": {
|
||||
"Value": {"Fn::GetAtt": ["Queue", "InvalidAttribute"]}
|
||||
}
|
||||
}
|
||||
"Outputs": {"Output1": {"Value": {"Fn::GetAtt": ["Queue", "InvalidAttribute"]}}}
|
||||
}
|
||||
|
||||
get_attribute_output = {
|
||||
"Outputs": {
|
||||
"Output1": {
|
||||
"Value": {"Fn::GetAtt": ["Queue", "QueueName"]}
|
||||
}
|
||||
}
|
||||
"Outputs": {"Output1": {"Value": {"Fn::GetAtt": ["Queue", "QueueName"]}}}
|
||||
}
|
||||
|
||||
get_availability_zones_output = {
|
||||
"Outputs": {
|
||||
"Output1": {
|
||||
"Value": {"Fn::GetAZs": ""}
|
||||
}
|
||||
}
|
||||
}
|
||||
get_availability_zones_output = {"Outputs": {"Output1": {"Value": {"Fn::GetAZs": ""}}}}
|
||||
|
||||
parameters = {
|
||||
"Parameters": {
|
||||
"Param": {
|
||||
"Type": "String",
|
||||
},
|
||||
"NoEchoParam": {
|
||||
"Type": "String",
|
||||
"NoEcho": True
|
||||
}
|
||||
"Param": {"Type": "String"},
|
||||
"NoEchoParam": {"Type": "String", "NoEcho": True},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,11 +67,11 @@ split_select_template = {
|
|||
"Queue": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": {"Fn::Select": [ "1", {"Fn::Split": [ "-", "123-myqueue" ] } ] },
|
||||
"QueueName": {"Fn::Select": ["1", {"Fn::Split": ["-", "123-myqueue"]}]},
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
sub_template = {
|
||||
|
|
@ -114,18 +80,18 @@ sub_template = {
|
|||
"Queue1": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": {"Fn::Sub": '${AWS::StackName}-queue-${!Literal}'},
|
||||
"QueueName": {"Fn::Sub": "${AWS::StackName}-queue-${!Literal}"},
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
},
|
||||
"Queue2": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": {"Fn::Sub": '${Queue1.QueueName}'},
|
||||
"QueueName": {"Fn::Sub": "${Queue1.QueueName}"},
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export_value_template = {
|
||||
|
|
@ -134,17 +100,12 @@ export_value_template = {
|
|||
"Queue": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": {"Fn::Sub": '${AWS::StackName}-queue'},
|
||||
"QueueName": {"Fn::Sub": "${AWS::StackName}-queue"},
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs": {
|
||||
"Output1": {
|
||||
"Value": "value",
|
||||
"Export": {"Name": 'queue-us-west-1'}
|
||||
}
|
||||
}
|
||||
"Outputs": {"Output1": {"Value": "value", "Export": {"Name": "queue-us-west-1"}}},
|
||||
}
|
||||
|
||||
import_value_template = {
|
||||
|
|
@ -153,33 +114,30 @@ import_value_template = {
|
|||
"Queue": {
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": {"Fn::ImportValue": 'queue-us-west-1'},
|
||||
"QueueName": {"Fn::ImportValue": "queue-us-west-1"},
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
outputs_template = dict(list(dummy_template.items()) +
|
||||
list(output_dict.items()))
|
||||
bad_outputs_template = dict(
|
||||
list(dummy_template.items()) + list(bad_output.items()))
|
||||
outputs_template = dict(list(dummy_template.items()) + list(output_dict.items()))
|
||||
bad_outputs_template = dict(list(dummy_template.items()) + list(bad_output.items()))
|
||||
get_attribute_outputs_template = dict(
|
||||
list(dummy_template.items()) + list(get_attribute_output.items()))
|
||||
list(dummy_template.items()) + list(get_attribute_output.items())
|
||||
)
|
||||
get_availability_zones_template = dict(
|
||||
list(dummy_template.items()) + list(get_availability_zones_output.items()))
|
||||
list(dummy_template.items()) + list(get_availability_zones_output.items())
|
||||
)
|
||||
|
||||
parameters_template = dict(
|
||||
list(dummy_template.items()) + list(parameters.items()))
|
||||
parameters_template = dict(list(dummy_template.items()) + list(parameters.items()))
|
||||
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
name_type_template_json = json.dumps(name_type_template)
|
||||
output_type_template_json = json.dumps(outputs_template)
|
||||
bad_output_template_json = json.dumps(bad_outputs_template)
|
||||
get_attribute_outputs_template_json = json.dumps(
|
||||
get_attribute_outputs_template)
|
||||
get_availability_zones_template_json = json.dumps(
|
||||
get_availability_zones_template)
|
||||
get_attribute_outputs_template_json = json.dumps(get_attribute_outputs_template)
|
||||
get_availability_zones_template_json = json.dumps(get_availability_zones_template)
|
||||
parameters_template_json = json.dumps(parameters_template)
|
||||
split_select_template_json = json.dumps(split_select_template)
|
||||
sub_template_json = json.dumps(sub_template)
|
||||
|
|
@ -193,15 +151,16 @@ def test_parse_stack_resources():
|
|||
name="test_stack",
|
||||
template=dummy_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(2)
|
||||
|
||||
queue = stack.resource_map['Queue']
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.should.be.a(Queue)
|
||||
queue.name.should.equal("my-queue")
|
||||
|
||||
bucket = stack.resource_map['S3Bucket']
|
||||
bucket = stack.resource_map["S3Bucket"]
|
||||
bucket.should.be.a(FakeBucket)
|
||||
bucket.physical_resource_id.should.equal(bucket.name)
|
||||
|
||||
|
|
@ -209,8 +168,7 @@ def test_parse_stack_resources():
|
|||
@patch("moto.cloudformation.parsing.logger")
|
||||
def test_missing_resource_logs(logger):
|
||||
resource_class_from_type("foobar")
|
||||
logger.warning.assert_called_with(
|
||||
'No Moto CloudFormation support for %s', 'foobar')
|
||||
logger.warning.assert_called_with("No Moto CloudFormation support for %s", "foobar")
|
||||
|
||||
|
||||
def test_parse_stack_with_name_type_resource():
|
||||
|
|
@ -219,10 +177,11 @@ def test_parse_stack_with_name_type_resource():
|
|||
name="test_stack",
|
||||
template=name_type_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
list(stack.resource_map.keys())[0].should.equal('Queue')
|
||||
list(stack.resource_map.keys())[0].should.equal("Queue")
|
||||
queue = list(stack.resource_map.values())[0]
|
||||
queue.should.be.a(Queue)
|
||||
|
||||
|
|
@ -233,10 +192,11 @@ def test_parse_stack_with_yaml_template():
|
|||
name="test_stack",
|
||||
template=yaml.dump(name_type_template),
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
list(stack.resource_map.keys())[0].should.equal('Queue')
|
||||
list(stack.resource_map.keys())[0].should.equal("Queue")
|
||||
queue = list(stack.resource_map.values())[0]
|
||||
queue.should.be.a(Queue)
|
||||
|
||||
|
|
@ -247,10 +207,11 @@ def test_parse_stack_with_outputs():
|
|||
name="test_stack",
|
||||
template=output_type_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal('Output1')
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.description.should.equal("This is a description.")
|
||||
|
|
@ -262,14 +223,16 @@ def test_parse_stack_with_get_attribute_outputs():
|
|||
name="test_stack",
|
||||
template=get_attribute_outputs_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal('Output1')
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.value.should.equal("my-queue")
|
||||
|
||||
|
||||
def test_parse_stack_with_get_attribute_kms():
|
||||
from .fixtures.kms_key import template
|
||||
|
||||
|
|
@ -279,31 +242,35 @@ def test_parse_stack_with_get_attribute_kms():
|
|||
name="test_stack",
|
||||
template=template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal('KeyArn')
|
||||
list(stack.output_map.keys())[0].should.equal("KeyArn")
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
|
||||
|
||||
def test_parse_stack_with_get_availability_zones():
|
||||
stack = FakeStack(
|
||||
stack_id="test_id",
|
||||
name="test_stack",
|
||||
template=get_availability_zones_template_json,
|
||||
parameters={},
|
||||
region_name='us-east-1')
|
||||
region_name="us-east-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal('Output1')
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.value.should.equal([ "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d" ])
|
||||
output.value.should.equal(["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"])
|
||||
|
||||
|
||||
def test_parse_stack_with_bad_get_attribute_outputs():
|
||||
FakeStack.when.called_with(
|
||||
"test_id", "test_stack", bad_output_template_json, {}, "us-west-1").should.throw(ValidationError)
|
||||
"test_id", "test_stack", bad_output_template_json, {}, "us-west-1"
|
||||
).should.throw(ValidationError)
|
||||
|
||||
|
||||
def test_parse_stack_with_parameters():
|
||||
|
|
@ -312,7 +279,8 @@ def test_parse_stack_with_parameters():
|
|||
name="test_stack",
|
||||
template=parameters_template_json,
|
||||
parameters={"Param": "visible value", "NoEchoParam": "hidden value"},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.no_echo_parameter_keys.should.have("NoEchoParam")
|
||||
stack.resource_map.no_echo_parameter_keys.should_not.have("Param")
|
||||
|
|
@ -334,21 +302,13 @@ def test_parse_equals_condition():
|
|||
|
||||
def test_parse_not_condition():
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Not": [{
|
||||
"Fn::Equals": [{"Ref": "EnvType"}, "prod"]
|
||||
}]
|
||||
},
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(False)
|
||||
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Not": [{
|
||||
"Fn::Equals": [{"Ref": "EnvType"}, "prod"]
|
||||
}]
|
||||
},
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "staging"},
|
||||
condition_map={},
|
||||
).should.equal(True)
|
||||
|
|
@ -416,10 +376,11 @@ def test_parse_split_and_select():
|
|||
name="test_stack",
|
||||
template=split_select_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
queue = stack.resource_map['Queue']
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("myqueue")
|
||||
|
||||
|
||||
|
|
@ -429,10 +390,11 @@ def test_sub():
|
|||
name="test_stack",
|
||||
template=sub_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
queue1 = stack.resource_map['Queue1']
|
||||
queue2 = stack.resource_map['Queue2']
|
||||
queue1 = stack.resource_map["Queue1"]
|
||||
queue2 = stack.resource_map["Queue2"]
|
||||
queue2.name.should.equal(queue1.name)
|
||||
|
||||
|
||||
|
|
@ -442,20 +404,21 @@ def test_import():
|
|||
name="test_stack",
|
||||
template=export_value_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1')
|
||||
region_name="us-west-1",
|
||||
)
|
||||
import_stack = FakeStack(
|
||||
stack_id="test_id",
|
||||
name="test_stack",
|
||||
template=import_value_template_json,
|
||||
parameters={},
|
||||
region_name='us-west-1',
|
||||
cross_stack_resources={export_stack.exports[0].value: export_stack.exports[0]})
|
||||
region_name="us-west-1",
|
||||
cross_stack_resources={export_stack.exports[0].value: export_stack.exports[0]},
|
||||
)
|
||||
|
||||
queue = import_stack.resource_map['Queue']
|
||||
queue = import_stack.resource_map["Queue"]
|
||||
queue.name.should.equal("value")
|
||||
|
||||
|
||||
|
||||
def test_short_form_func_in_yaml_teamplate():
|
||||
template = """---
|
||||
KeyB64: !Base64 valueToEncode
|
||||
|
|
@ -476,24 +439,24 @@ def test_short_form_func_in_yaml_teamplate():
|
|||
KeySplit: !Split [A, B]
|
||||
KeySub: !Sub A
|
||||
"""
|
||||
yaml.add_multi_constructor('', yaml_tag_constructor, Loader=yaml.Loader)
|
||||
yaml.add_multi_constructor("", yaml_tag_constructor, Loader=yaml.Loader)
|
||||
template_dict = yaml.load(template, Loader=yaml.Loader)
|
||||
key_and_expects = [
|
||||
['KeyRef', {'Ref': 'foo'}],
|
||||
['KeyB64', {'Fn::Base64': 'valueToEncode'}],
|
||||
['KeyAnd', {'Fn::And': ['A', 'B']}],
|
||||
['KeyEquals', {'Fn::Equals': ['A', 'B']}],
|
||||
['KeyIf', {'Fn::If': ['A', 'B', 'C']}],
|
||||
['KeyNot', {'Fn::Not': ['A']}],
|
||||
['KeyOr', {'Fn::Or': ['A', 'B']}],
|
||||
['KeyFindInMap', {'Fn::FindInMap': ['A', 'B', 'C']}],
|
||||
['KeyGetAtt', {'Fn::GetAtt': ['A', 'B']}],
|
||||
['KeyGetAZs', {'Fn::GetAZs': 'A'}],
|
||||
['KeyImportValue', {'Fn::ImportValue': 'A'}],
|
||||
['KeyJoin', {'Fn::Join': [ ":", [ 'A', 'B', 'C' ] ]}],
|
||||
['KeySelect', {'Fn::Select': ['A', 'B']}],
|
||||
['KeySplit', {'Fn::Split': ['A', 'B']}],
|
||||
['KeySub', {'Fn::Sub': 'A'}],
|
||||
["KeyRef", {"Ref": "foo"}],
|
||||
["KeyB64", {"Fn::Base64": "valueToEncode"}],
|
||||
["KeyAnd", {"Fn::And": ["A", "B"]}],
|
||||
["KeyEquals", {"Fn::Equals": ["A", "B"]}],
|
||||
["KeyIf", {"Fn::If": ["A", "B", "C"]}],
|
||||
["KeyNot", {"Fn::Not": ["A"]}],
|
||||
["KeyOr", {"Fn::Or": ["A", "B"]}],
|
||||
["KeyFindInMap", {"Fn::FindInMap": ["A", "B", "C"]}],
|
||||
["KeyGetAtt", {"Fn::GetAtt": ["A", "B"]}],
|
||||
["KeyGetAZs", {"Fn::GetAZs": "A"}],
|
||||
["KeyImportValue", {"Fn::ImportValue": "A"}],
|
||||
["KeyJoin", {"Fn::Join": [":", ["A", "B", "C"]]}],
|
||||
["KeySelect", {"Fn::Select": ["A", "B"]}],
|
||||
["KeySplit", {"Fn::Split": ["A", "B"]}],
|
||||
["KeySub", {"Fn::Sub": "A"}],
|
||||
]
|
||||
for k, v in key_and_expects:
|
||||
template_dict.should.have.key(k).which.should.be.equal(v)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ import botocore
|
|||
|
||||
from moto.cloudformation.exceptions import ValidationError
|
||||
from moto.cloudformation.models import FakeStack
|
||||
from moto.cloudformation.parsing import resource_class_from_type, parse_condition, Export
|
||||
from moto.cloudformation.parsing import (
|
||||
resource_class_from_type,
|
||||
parse_condition,
|
||||
Export,
|
||||
)
|
||||
from moto.sqs.models import Queue
|
||||
from moto.s3.models import FakeBucket
|
||||
from moto.cloudformation.utils import yaml_tag_constructor
|
||||
|
|
@ -27,25 +31,16 @@ json_template = {
|
|||
"KeyName": "dummy",
|
||||
"InstanceType": "t2.micro",
|
||||
"Tags": [
|
||||
{
|
||||
"Key": "Description",
|
||||
"Value": "Test tag"
|
||||
},
|
||||
{
|
||||
"Key": "Name",
|
||||
"Value": "Name tag for tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
{"Key": "Description", "Value": "Test tag"},
|
||||
{"Key": "Name", "Value": "Name tag for tests"},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
# One resource is required
|
||||
json_bad_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 1"
|
||||
}
|
||||
json_bad_template = {"AWSTemplateFormatVersion": "2010-09-09", "Description": "Stack 1"}
|
||||
|
||||
dummy_template_json = json.dumps(json_template)
|
||||
dummy_bad_template_json = json.dumps(json_bad_template)
|
||||
|
|
@ -53,25 +48,25 @@ dummy_bad_template_json = json.dumps(json_bad_template)
|
|||
|
||||
@mock_cloudformation
|
||||
def test_boto3_json_validate_successful():
|
||||
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||
response = cf_conn.validate_template(
|
||||
TemplateBody=dummy_template_json,
|
||||
)
|
||||
assert response['Description'] == "Stack 1"
|
||||
assert response['Parameters'] == []
|
||||
assert response['ResponseMetadata']['HTTPStatusCode'] == 200
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
response = cf_conn.validate_template(TemplateBody=dummy_template_json)
|
||||
assert response["Description"] == "Stack 1"
|
||||
assert response["Parameters"] == []
|
||||
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_boto3_json_invalid_missing_resource():
|
||||
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
try:
|
||||
cf_conn.validate_template(
|
||||
TemplateBody=dummy_bad_template_json,
|
||||
)
|
||||
cf_conn.validate_template(TemplateBody=dummy_bad_template_json)
|
||||
assert False
|
||||
except botocore.exceptions.ClientError as e:
|
||||
assert str(e) == 'An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack' \
|
||||
' with id Missing top level item Resources to file module does not exist'
|
||||
assert (
|
||||
str(e)
|
||||
== "An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack"
|
||||
" with id Missing top level item Resources to file module does not exist"
|
||||
)
|
||||
assert True
|
||||
|
||||
|
||||
|
|
@ -91,25 +86,26 @@ yaml_bad_template = """
|
|||
Description: Simple CloudFormation Test Template
|
||||
"""
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_boto3_yaml_validate_successful():
|
||||
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||
response = cf_conn.validate_template(
|
||||
TemplateBody=yaml_template,
|
||||
)
|
||||
assert response['Description'] == "Simple CloudFormation Test Template"
|
||||
assert response['Parameters'] == []
|
||||
assert response['ResponseMetadata']['HTTPStatusCode'] == 200
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
response = cf_conn.validate_template(TemplateBody=yaml_template)
|
||||
assert response["Description"] == "Simple CloudFormation Test Template"
|
||||
assert response["Parameters"] == []
|
||||
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_boto3_yaml_invalid_missing_resource():
|
||||
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
try:
|
||||
cf_conn.validate_template(
|
||||
TemplateBody=yaml_bad_template,
|
||||
)
|
||||
cf_conn.validate_template(TemplateBody=yaml_bad_template)
|
||||
assert False
|
||||
except botocore.exceptions.ClientError as e:
|
||||
assert str(e) == 'An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack' \
|
||||
' with id Missing top level item Resources to file module does not exist'
|
||||
assert (
|
||||
str(e)
|
||||
== "An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack"
|
||||
" with id Missing top level item Resources to file module does not exist"
|
||||
)
|
||||
assert True
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
import boto
|
||||
from boto.ec2.cloudwatch.alarm import MetricAlarm
|
||||
import boto3
|
||||
from datetime import datetime, timedelta
|
||||
import pytz
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_cloudwatch_deprecated
|
||||
|
||||
|
||||
def alarm_fixture(name="tester", action=None):
|
||||
action = action or ['arn:alarm']
|
||||
action = action or ["arn:alarm"]
|
||||
return MetricAlarm(
|
||||
name=name,
|
||||
namespace="{0}_namespace".format(name),
|
||||
metric="{0}_metric".format(name),
|
||||
comparison='>=',
|
||||
comparison=">=",
|
||||
threshold=2.0,
|
||||
period=60,
|
||||
evaluation_periods=5,
|
||||
statistic='Average',
|
||||
description='A test',
|
||||
dimensions={'InstanceId': ['i-0123456,i-0123457']},
|
||||
statistic="Average",
|
||||
description="A test",
|
||||
dimensions={"InstanceId": ["i-0123456,i-0123457"]},
|
||||
alarm_actions=action,
|
||||
ok_actions=['arn:ok'],
|
||||
insufficient_data_actions=['arn:insufficient'],
|
||||
unit='Seconds',
|
||||
ok_actions=["arn:ok"],
|
||||
insufficient_data_actions=["arn:insufficient"],
|
||||
unit="Seconds",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -38,21 +35,20 @@ def test_create_alarm():
|
|||
alarms = conn.describe_alarms()
|
||||
alarms.should.have.length_of(1)
|
||||
alarm = alarms[0]
|
||||
alarm.name.should.equal('tester')
|
||||
alarm.namespace.should.equal('tester_namespace')
|
||||
alarm.metric.should.equal('tester_metric')
|
||||
alarm.comparison.should.equal('>=')
|
||||
alarm.name.should.equal("tester")
|
||||
alarm.namespace.should.equal("tester_namespace")
|
||||
alarm.metric.should.equal("tester_metric")
|
||||
alarm.comparison.should.equal(">=")
|
||||
alarm.threshold.should.equal(2.0)
|
||||
alarm.period.should.equal(60)
|
||||
alarm.evaluation_periods.should.equal(5)
|
||||
alarm.statistic.should.equal('Average')
|
||||
alarm.description.should.equal('A test')
|
||||
dict(alarm.dimensions).should.equal(
|
||||
{'InstanceId': ['i-0123456,i-0123457']})
|
||||
list(alarm.alarm_actions).should.equal(['arn:alarm'])
|
||||
list(alarm.ok_actions).should.equal(['arn:ok'])
|
||||
list(alarm.insufficient_data_actions).should.equal(['arn:insufficient'])
|
||||
alarm.unit.should.equal('Seconds')
|
||||
alarm.statistic.should.equal("Average")
|
||||
alarm.description.should.equal("A test")
|
||||
dict(alarm.dimensions).should.equal({"InstanceId": ["i-0123456,i-0123457"]})
|
||||
list(alarm.alarm_actions).should.equal(["arn:alarm"])
|
||||
list(alarm.ok_actions).should.equal(["arn:ok"])
|
||||
list(alarm.insufficient_data_actions).should.equal(["arn:insufficient"])
|
||||
alarm.unit.should.equal("Seconds")
|
||||
|
||||
|
||||
@mock_cloudwatch_deprecated
|
||||
|
|
@ -79,19 +75,18 @@ def test_put_metric_data():
|
|||
conn = boto.connect_cloudwatch()
|
||||
|
||||
conn.put_metric_data(
|
||||
namespace='tester',
|
||||
name='metric',
|
||||
namespace="tester",
|
||||
name="metric",
|
||||
value=1.5,
|
||||
dimensions={'InstanceId': ['i-0123456,i-0123457']},
|
||||
dimensions={"InstanceId": ["i-0123456,i-0123457"]},
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric.namespace.should.equal('tester')
|
||||
metric.name.should.equal('metric')
|
||||
dict(metric.dimensions).should.equal(
|
||||
{'InstanceId': ['i-0123456,i-0123457']})
|
||||
metric.namespace.should.equal("tester")
|
||||
metric.name.should.equal("metric")
|
||||
dict(metric.dimensions).should.equal({"InstanceId": ["i-0123456,i-0123457"]})
|
||||
|
||||
|
||||
@mock_cloudwatch_deprecated
|
||||
|
|
@ -110,8 +105,7 @@ def test_describe_alarms():
|
|||
alarms.should.have.length_of(4)
|
||||
alarms = conn.describe_alarms(alarm_name_prefix="nfoo")
|
||||
alarms.should.have.length_of(2)
|
||||
alarms = conn.describe_alarms(
|
||||
alarm_names=["nfoobar", "nbarfoo", "nbazfoo"])
|
||||
alarms = conn.describe_alarms(alarm_names=["nfoobar", "nbarfoo", "nbazfoo"])
|
||||
alarms.should.have.length_of(3)
|
||||
alarms = conn.describe_alarms(action_prefix="afoo")
|
||||
alarms.should.have.length_of(2)
|
||||
|
|
|
|||
515
tests/test_cloudwatch/test_cloudwatch_boto3.py
Executable file → Normal file
515
tests/test_cloudwatch/test_cloudwatch_boto3.py
Executable file → Normal file
|
|
@ -1,224 +1,291 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from datetime import datetime, timedelta
|
||||
import pytz
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_cloudwatch
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_list_dashboard():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName='test1', DashboardBody=widget)
|
||||
resp = client.list_dashboards()
|
||||
|
||||
len(resp['DashboardEntries']).should.equal(1)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_list_prefix_nomatch_dashboard():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName='test1', DashboardBody=widget)
|
||||
resp = client.list_dashboards(DashboardNamePrefix='nomatch')
|
||||
|
||||
len(resp['DashboardEntries']).should.equal(0)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_delete_dashboard():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName='test1', DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName='test2', DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName='test3', DashboardBody=widget)
|
||||
client.delete_dashboards(DashboardNames=['test2', 'test1'])
|
||||
|
||||
resp = client.list_dashboards(DashboardNamePrefix='test3')
|
||||
len(resp['DashboardEntries']).should.equal(1)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_delete_dashboard_fail():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName='test1', DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName='test2', DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName='test3', DashboardBody=widget)
|
||||
# Doesnt delete anything if all dashboards to be deleted do not exist
|
||||
try:
|
||||
client.delete_dashboards(DashboardNames=['test2', 'test1', 'test_no_match'])
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFound')
|
||||
else:
|
||||
raise RuntimeError('Should of raised error')
|
||||
|
||||
resp = client.list_dashboards()
|
||||
len(resp['DashboardEntries']).should.equal(3)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_dashboard():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
client.put_dashboard(DashboardName='test1', DashboardBody=widget)
|
||||
|
||||
resp = client.get_dashboard(DashboardName='test1')
|
||||
resp.should.contain('DashboardArn')
|
||||
resp.should.contain('DashboardBody')
|
||||
resp['DashboardName'].should.equal('test1')
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_dashboard_fail():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
|
||||
try:
|
||||
client.get_dashboard(DashboardName='test1')
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ResourceNotFound')
|
||||
else:
|
||||
raise RuntimeError('Should of raised error')
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_alarm_state():
|
||||
client = boto3.client('cloudwatch', region_name='eu-central-1')
|
||||
|
||||
client.put_metric_alarm(
|
||||
AlarmName='testalarm1',
|
||||
MetricName='cpu',
|
||||
Namespace='blah',
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic='Average',
|
||||
Threshold=2,
|
||||
ComparisonOperator='GreaterThanThreshold',
|
||||
)
|
||||
client.put_metric_alarm(
|
||||
AlarmName='testalarm2',
|
||||
MetricName='cpu',
|
||||
Namespace='blah',
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic='Average',
|
||||
Threshold=2,
|
||||
ComparisonOperator='GreaterThanThreshold',
|
||||
)
|
||||
|
||||
# This is tested implicitly as if it doesnt work the rest will die
|
||||
client.set_alarm_state(
|
||||
AlarmName='testalarm1',
|
||||
StateValue='ALARM',
|
||||
StateReason='testreason',
|
||||
StateReasonData='{"some": "json_data"}'
|
||||
)
|
||||
|
||||
resp = client.describe_alarms(
|
||||
StateValue='ALARM'
|
||||
)
|
||||
len(resp['MetricAlarms']).should.equal(1)
|
||||
resp['MetricAlarms'][0]['AlarmName'].should.equal('testalarm1')
|
||||
resp['MetricAlarms'][0]['StateValue'].should.equal('ALARM')
|
||||
|
||||
resp = client.describe_alarms(
|
||||
StateValue='OK'
|
||||
)
|
||||
len(resp['MetricAlarms']).should.equal(1)
|
||||
resp['MetricAlarms'][0]['AlarmName'].should.equal('testalarm2')
|
||||
resp['MetricAlarms'][0]['StateValue'].should.equal('OK')
|
||||
|
||||
# Just for sanity
|
||||
resp = client.describe_alarms()
|
||||
len(resp['MetricAlarms']).should.equal(2)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_metric_data_no_dimensions():
|
||||
conn = boto3.client('cloudwatch', region_name='us-east-1')
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace='tester',
|
||||
MetricData=[
|
||||
dict(
|
||||
MetricName='metric',
|
||||
Value=1.5,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()['Metrics']
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric['Namespace'].should.equal('tester')
|
||||
metric['MetricName'].should.equal('metric')
|
||||
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_metric_data_with_statistics():
|
||||
conn = boto3.client('cloudwatch', region_name='us-east-1')
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace='tester',
|
||||
MetricData=[
|
||||
dict(
|
||||
MetricName='statmetric',
|
||||
Timestamp=datetime(2015, 1, 1),
|
||||
# no Value to test https://github.com/spulec/moto/issues/1615
|
||||
StatisticValues=dict(
|
||||
SampleCount=123.0,
|
||||
Sum=123.0,
|
||||
Minimum=123.0,
|
||||
Maximum=123.0
|
||||
),
|
||||
Unit='Milliseconds',
|
||||
StorageResolution=123
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()['Metrics']
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric['Namespace'].should.equal('tester')
|
||||
metric['MetricName'].should.equal('statmetric')
|
||||
# TODO: test statistics - https://github.com/spulec/moto/issues/1615
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_metric_statistics():
|
||||
conn = boto3.client('cloudwatch', region_name='us-east-1')
|
||||
utc_now = datetime.now(tz=pytz.utc)
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace='tester',
|
||||
MetricData=[
|
||||
dict(
|
||||
MetricName='metric',
|
||||
Value=1.5,
|
||||
Timestamp=utc_now
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
stats = conn.get_metric_statistics(
|
||||
Namespace='tester',
|
||||
MetricName='metric',
|
||||
StartTime=utc_now - timedelta(seconds=60),
|
||||
EndTime=utc_now + timedelta(seconds=60),
|
||||
Period=60,
|
||||
Statistics=['SampleCount', 'Sum']
|
||||
)
|
||||
|
||||
stats['Datapoints'].should.have.length_of(1)
|
||||
datapoint = stats['Datapoints'][0]
|
||||
datapoint['SampleCount'].should.equal(1.0)
|
||||
datapoint['Sum'].should.equal(1.5)
|
||||
# from __future__ import unicode_literals
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from datetime import datetime, timedelta
|
||||
from nose.tools import assert_raises
|
||||
from uuid import uuid4
|
||||
import pytz
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_cloudwatch
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_list_dashboard():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName="test1", DashboardBody=widget)
|
||||
resp = client.list_dashboards()
|
||||
|
||||
len(resp["DashboardEntries"]).should.equal(1)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_list_prefix_nomatch_dashboard():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName="test1", DashboardBody=widget)
|
||||
resp = client.list_dashboards(DashboardNamePrefix="nomatch")
|
||||
|
||||
len(resp["DashboardEntries"]).should.equal(0)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_delete_dashboard():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName="test1", DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName="test2", DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName="test3", DashboardBody=widget)
|
||||
client.delete_dashboards(DashboardNames=["test2", "test1"])
|
||||
|
||||
resp = client.list_dashboards(DashboardNamePrefix="test3")
|
||||
len(resp["DashboardEntries"]).should.equal(1)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_delete_dashboard_fail():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
|
||||
client.put_dashboard(DashboardName="test1", DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName="test2", DashboardBody=widget)
|
||||
client.put_dashboard(DashboardName="test3", DashboardBody=widget)
|
||||
# Doesnt delete anything if all dashboards to be deleted do not exist
|
||||
try:
|
||||
client.delete_dashboards(DashboardNames=["test2", "test1", "test_no_match"])
|
||||
except ClientError as err:
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFound")
|
||||
else:
|
||||
raise RuntimeError("Should of raised error")
|
||||
|
||||
resp = client.list_dashboards()
|
||||
len(resp["DashboardEntries"]).should.equal(3)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_dashboard():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
widget = '{"widgets": [{"type": "text", "x": 0, "y": 7, "width": 3, "height": 3, "properties": {"markdown": "Hello world"}}]}'
|
||||
client.put_dashboard(DashboardName="test1", DashboardBody=widget)
|
||||
|
||||
resp = client.get_dashboard(DashboardName="test1")
|
||||
resp.should.contain("DashboardArn")
|
||||
resp.should.contain("DashboardBody")
|
||||
resp["DashboardName"].should.equal("test1")
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_dashboard_fail():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
|
||||
try:
|
||||
client.get_dashboard(DashboardName="test1")
|
||||
except ClientError as err:
|
||||
err.response["Error"]["Code"].should.equal("ResourceNotFound")
|
||||
else:
|
||||
raise RuntimeError("Should of raised error")
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_alarm_state():
|
||||
client = boto3.client("cloudwatch", region_name="eu-central-1")
|
||||
|
||||
client.put_metric_alarm(
|
||||
AlarmName="testalarm1",
|
||||
MetricName="cpu",
|
||||
Namespace="blah",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
)
|
||||
client.put_metric_alarm(
|
||||
AlarmName="testalarm2",
|
||||
MetricName="cpu",
|
||||
Namespace="blah",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
)
|
||||
|
||||
# This is tested implicitly as if it doesnt work the rest will die
|
||||
client.set_alarm_state(
|
||||
AlarmName="testalarm1",
|
||||
StateValue="ALARM",
|
||||
StateReason="testreason",
|
||||
StateReasonData='{"some": "json_data"}',
|
||||
)
|
||||
|
||||
resp = client.describe_alarms(StateValue="ALARM")
|
||||
len(resp["MetricAlarms"]).should.equal(1)
|
||||
resp["MetricAlarms"][0]["AlarmName"].should.equal("testalarm1")
|
||||
resp["MetricAlarms"][0]["StateValue"].should.equal("ALARM")
|
||||
|
||||
resp = client.describe_alarms(StateValue="OK")
|
||||
len(resp["MetricAlarms"]).should.equal(1)
|
||||
resp["MetricAlarms"][0]["AlarmName"].should.equal("testalarm2")
|
||||
resp["MetricAlarms"][0]["StateValue"].should.equal("OK")
|
||||
|
||||
# Just for sanity
|
||||
resp = client.describe_alarms()
|
||||
len(resp["MetricAlarms"]).should.equal(2)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_metric_data_no_dimensions():
|
||||
conn = boto3.client("cloudwatch", region_name="us-east-1")
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace="tester", MetricData=[dict(MetricName="metric", Value=1.5)]
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()["Metrics"]
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric["Namespace"].should.equal("tester")
|
||||
metric["MetricName"].should.equal("metric")
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_put_metric_data_with_statistics():
|
||||
conn = boto3.client("cloudwatch", region_name="us-east-1")
|
||||
utc_now = datetime.now(tz=pytz.utc)
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace="tester",
|
||||
MetricData=[
|
||||
dict(
|
||||
MetricName="statmetric",
|
||||
Timestamp=utc_now,
|
||||
# no Value to test https://github.com/spulec/moto/issues/1615
|
||||
StatisticValues=dict(
|
||||
SampleCount=123.0, Sum=123.0, Minimum=123.0, Maximum=123.0
|
||||
),
|
||||
Unit="Milliseconds",
|
||||
StorageResolution=123,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()["Metrics"]
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric["Namespace"].should.equal("tester")
|
||||
metric["MetricName"].should.equal("statmetric")
|
||||
# TODO: test statistics - https://github.com/spulec/moto/issues/1615
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_get_metric_statistics():
|
||||
conn = boto3.client("cloudwatch", region_name="us-east-1")
|
||||
utc_now = datetime.now(tz=pytz.utc)
|
||||
|
||||
conn.put_metric_data(
|
||||
Namespace="tester",
|
||||
MetricData=[dict(MetricName="metric", Value=1.5, Timestamp=utc_now)],
|
||||
)
|
||||
|
||||
stats = conn.get_metric_statistics(
|
||||
Namespace="tester",
|
||||
MetricName="metric",
|
||||
StartTime=utc_now - timedelta(seconds=60),
|
||||
EndTime=utc_now + timedelta(seconds=60),
|
||||
Period=60,
|
||||
Statistics=["SampleCount", "Sum"],
|
||||
)
|
||||
|
||||
stats["Datapoints"].should.have.length_of(1)
|
||||
datapoint = stats["Datapoints"][0]
|
||||
datapoint["SampleCount"].should.equal(1.0)
|
||||
datapoint["Sum"].should.equal(1.5)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_list_metrics():
|
||||
cloudwatch = boto3.client("cloudwatch", "eu-west-1")
|
||||
# Verify namespace has to exist
|
||||
res = cloudwatch.list_metrics(Namespace="unknown/")["Metrics"]
|
||||
res.should.be.empty
|
||||
# Create some metrics to filter on
|
||||
create_metrics(cloudwatch, namespace="list_test_1/", metrics=4, data_points=2)
|
||||
create_metrics(cloudwatch, namespace="list_test_2/", metrics=4, data_points=2)
|
||||
# Verify we can retrieve everything
|
||||
res = cloudwatch.list_metrics()["Metrics"]
|
||||
len(res).should.equal(16) # 2 namespaces * 4 metrics * 2 data points
|
||||
# Verify we can filter by namespace/metric name
|
||||
res = cloudwatch.list_metrics(Namespace="list_test_1/")["Metrics"]
|
||||
len(res).should.equal(8) # 1 namespace * 4 metrics * 2 data points
|
||||
res = cloudwatch.list_metrics(Namespace="list_test_1/", MetricName="metric1")[
|
||||
"Metrics"
|
||||
]
|
||||
len(res).should.equal(2) # 1 namespace * 1 metrics * 2 data points
|
||||
# Verify format
|
||||
res.should.equal(
|
||||
[
|
||||
{u"Namespace": "list_test_1/", u"Dimensions": [], u"MetricName": "metric1"},
|
||||
{u"Namespace": "list_test_1/", u"Dimensions": [], u"MetricName": "metric1"},
|
||||
]
|
||||
)
|
||||
# Verify unknown namespace still has no results
|
||||
res = cloudwatch.list_metrics(Namespace="unknown/")["Metrics"]
|
||||
res.should.be.empty
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
def test_list_metrics_paginated():
|
||||
cloudwatch = boto3.client("cloudwatch", "eu-west-1")
|
||||
# Verify that only a single page of metrics is returned
|
||||
cloudwatch.list_metrics()["Metrics"].should.be.empty
|
||||
# Verify we can't pass a random NextToken
|
||||
with assert_raises(ClientError) as e:
|
||||
cloudwatch.list_metrics(NextToken=str(uuid4()))
|
||||
e.exception.response["Error"]["Message"].should.equal(
|
||||
"Request parameter NextToken is invalid"
|
||||
)
|
||||
# Add a boatload of metrics
|
||||
create_metrics(cloudwatch, namespace="test", metrics=100, data_points=1)
|
||||
# Verify that a single page is returned until we've reached 500
|
||||
first_page = cloudwatch.list_metrics()
|
||||
first_page["Metrics"].shouldnt.be.empty
|
||||
len(first_page["Metrics"]).should.equal(100)
|
||||
create_metrics(cloudwatch, namespace="test", metrics=200, data_points=2)
|
||||
first_page = cloudwatch.list_metrics()
|
||||
len(first_page["Metrics"]).should.equal(500)
|
||||
first_page.shouldnt.contain("NextToken")
|
||||
# Verify that adding more data points results in pagination
|
||||
create_metrics(cloudwatch, namespace="test", metrics=60, data_points=10)
|
||||
first_page = cloudwatch.list_metrics()
|
||||
len(first_page["Metrics"]).should.equal(500)
|
||||
first_page["NextToken"].shouldnt.be.empty
|
||||
# Retrieve second page - and verify there's more where that came from
|
||||
second_page = cloudwatch.list_metrics(NextToken=first_page["NextToken"])
|
||||
len(second_page["Metrics"]).should.equal(500)
|
||||
second_page.should.contain("NextToken")
|
||||
# Last page should only have the last 100 results, and no NextToken (indicating that pagination is finished)
|
||||
third_page = cloudwatch.list_metrics(NextToken=second_page["NextToken"])
|
||||
len(third_page["Metrics"]).should.equal(100)
|
||||
third_page.shouldnt.contain("NextToken")
|
||||
# Verify that we can't reuse an existing token
|
||||
with assert_raises(ClientError) as e:
|
||||
cloudwatch.list_metrics(NextToken=first_page["NextToken"])
|
||||
e.exception.response["Error"]["Message"].should.equal(
|
||||
"Request parameter NextToken is invalid"
|
||||
)
|
||||
|
||||
|
||||
def create_metrics(cloudwatch, namespace, metrics=5, data_points=5):
|
||||
for i in range(0, metrics):
|
||||
metric_name = "metric" + str(i)
|
||||
for j in range(0, data_points):
|
||||
cloudwatch.put_metric_data(
|
||||
Namespace=namespace,
|
||||
MetricData=[{"MetricName": metric_name, "Value": j, "Unit": "Seconds"}],
|
||||
)
|
||||
|
|
|
|||
877
tests/test_codepipeline/test_codepipeline.py
Normal file
877
tests/test_codepipeline/test_codepipeline.py
Normal file
|
|
@ -0,0 +1,877 @@
|
|||
import json
|
||||
from datetime import datetime
|
||||
|
||||
import boto3
|
||||
import sure # noqa
|
||||
from botocore.exceptions import ClientError
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_codepipeline, mock_iam
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_create_pipeline():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
|
||||
response = client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
tags=[{"key": "key", "value": "value"}],
|
||||
)
|
||||
|
||||
response["pipeline"].should.equal(
|
||||
{
|
||||
"name": "test-pipeline",
|
||||
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"}],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {},
|
||||
"outputArtifacts": [],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"version": 1,
|
||||
}
|
||||
)
|
||||
response["tags"].should.equal([{"key": "key", "value": "value"}])
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
@mock_iam
|
||||
def test_create_pipeline_errors():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
client_iam = boto3.client("iam", region_name="us-east-1")
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("CreatePipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("InvalidStructureException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"A pipeline with the name 'test-pipeline' already exists in account '123456789012'"
|
||||
)
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "invalid-pipeline",
|
||||
"roleArn": "arn:aws:iam::123456789012:role/not-existing",
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("CreatePipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("InvalidStructureException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/not-existing"
|
||||
)
|
||||
|
||||
wrong_role_arn = client_iam.create_role(
|
||||
RoleName="wrong-role",
|
||||
AssumeRolePolicyDocument=json.dumps(
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {"Service": "s3.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole",
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
)["Role"]["Arn"]
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "invalid-pipeline",
|
||||
"roleArn": wrong_role_arn,
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("CreatePipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("InvalidStructureException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/wrong-role"
|
||||
)
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "invalid-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("CreatePipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("InvalidStructureException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline"
|
||||
)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_get_pipeline():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
tags=[{"key": "key", "value": "value"}],
|
||||
)
|
||||
|
||||
response = client.get_pipeline(name="test-pipeline")
|
||||
|
||||
response["pipeline"].should.equal(
|
||||
{
|
||||
"name": "test-pipeline",
|
||||
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"}],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {},
|
||||
"outputArtifacts": [],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"version": 1,
|
||||
}
|
||||
)
|
||||
response["metadata"]["pipelineArn"].should.equal(
|
||||
"arn:aws:codepipeline:us-east-1:123456789012:test-pipeline"
|
||||
)
|
||||
response["metadata"]["created"].should.be.a(datetime)
|
||||
response["metadata"]["updated"].should.be.a(datetime)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_get_pipeline_errors():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.get_pipeline(name="not-existing")
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("GetPipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("PipelineNotFoundException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"Account '123456789012' does not have a pipeline with name 'not-existing'"
|
||||
)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_update_pipeline():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
role_arn = get_role_arn()
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": role_arn,
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
tags=[{"key": "key", "value": "value"}],
|
||||
)
|
||||
|
||||
response = client.get_pipeline(name="test-pipeline")
|
||||
created_time = response["metadata"]["created"]
|
||||
updated_time = response["metadata"]["updated"]
|
||||
|
||||
response = client.update_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": role_arn,
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "different-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
response["pipeline"].should.equal(
|
||||
{
|
||||
"name": "test-pipeline",
|
||||
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {
|
||||
"S3Bucket": "different-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"}],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
"runOrder": 1,
|
||||
"configuration": {},
|
||||
"outputArtifacts": [],
|
||||
"inputArtifacts": [],
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"version": 2,
|
||||
}
|
||||
)
|
||||
|
||||
metadata = client.get_pipeline(name="test-pipeline")["metadata"]
|
||||
metadata["created"].should.equal(created_time)
|
||||
metadata["updated"].should.be.greater_than(updated_time)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_update_pipeline_errors():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.update_pipeline(
|
||||
pipeline={
|
||||
"name": "not-existing",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
ex = e.exception
|
||||
ex.operation_name.should.equal("UpdatePipeline")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("ResourceNotFoundException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
"The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
||||
)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_list_pipelines():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline-1",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline-2",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
response = client.list_pipelines()
|
||||
|
||||
response["pipelines"].should.have.length_of(2)
|
||||
response["pipelines"][0]["name"].should.equal("test-pipeline-1")
|
||||
response["pipelines"][0]["version"].should.equal(1)
|
||||
response["pipelines"][0]["created"].should.be.a(datetime)
|
||||
response["pipelines"][0]["updated"].should.be.a(datetime)
|
||||
response["pipelines"][1]["name"].should.equal("test-pipeline-2")
|
||||
response["pipelines"][1]["version"].should.equal(1)
|
||||
response["pipelines"][1]["created"].should.be.a(datetime)
|
||||
response["pipelines"][1]["updated"].should.be.a(datetime)
|
||||
|
||||
|
||||
@mock_codepipeline
|
||||
def test_delete_pipeline():
|
||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||
client.create_pipeline(
|
||||
pipeline={
|
||||
"name": "test-pipeline",
|
||||
"roleArn": get_role_arn(),
|
||||
"artifactStore": {
|
||||
"type": "S3",
|
||||
"location": "codepipeline-us-east-1-123456789012",
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "Stage-1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Source",
|
||||
"owner": "AWS",
|
||||
"provider": "S3",
|
||||
"version": "1",
|
||||
},
|
||||
"configuration": {
|
||||
"S3Bucket": "test-bucket",
|
||||
"S3ObjectKey": "test-object",
|
||||
},
|
||||
"outputArtifacts": [{"name": "artifact"},],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Stage-2",
|
||||
"actions": [
|
||||
{
|
||||
"name": "Action-1",
|
||||
"actionTypeId": {
|
||||
"category": "Approval",
|
||||
"owner": "AWS",
|
||||
"provider": "Manual",
|
||||
"version": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
client.list_pipelines()["pipelines"].should.have.length_of(1)
|
||||
|
||||
client.delete_pipeline(name="test-pipeline")
|
||||
|
||||
client.list_pipelines()["pipelines"].should.have.length_of(0)
|
||||
|
||||
# deleting a not existing pipeline, should raise no exception
|
||||
client.delete_pipeline(name="test-pipeline")
|
||||
|
||||
|
||||
@mock_iam
|
||||
def get_role_arn():
|
||||
iam = boto3.client("iam", region_name="us-east-1")
|
||||
try:
|
||||
return iam.get_role(RoleName="test-role")["Role"]["Arn"]
|
||||
except ClientError:
|
||||
return iam.create_role(
|
||||
RoleName="test-role",
|
||||
AssumeRolePolicyDocument=json.dumps(
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {"Service": "codepipeline.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole",
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
)["Role"]["Arn"]
|
||||
|
|
@ -1,97 +1,150 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_cognitoidentity
|
||||
import sure # noqa
|
||||
|
||||
from moto.cognitoidentity.utils import get_random_identity_id
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_create_identity_pool():
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
|
||||
result = conn.create_identity_pool(IdentityPoolName='TestPool',
|
||||
result = conn.create_identity_pool(
|
||||
IdentityPoolName="TestPool",
|
||||
AllowUnauthenticatedIdentities=False,
|
||||
SupportedLoginProviders={'graph.facebook.com': '123456789012345'},
|
||||
DeveloperProviderName='devname',
|
||||
OpenIdConnectProviderARNs=['arn:aws:rds:eu-west-2:123456789012:db:mysql-db'],
|
||||
SupportedLoginProviders={"graph.facebook.com": "123456789012345"},
|
||||
DeveloperProviderName="devname",
|
||||
OpenIdConnectProviderARNs=[
|
||||
"arn:aws:rds:eu-west-2:{}:db:mysql-db".format(ACCOUNT_ID)
|
||||
],
|
||||
CognitoIdentityProviders=[
|
||||
{
|
||||
'ProviderName': 'testprovider',
|
||||
'ClientId': 'CLIENT12345',
|
||||
'ServerSideTokenCheck': True
|
||||
},
|
||||
"ProviderName": "testprovider",
|
||||
"ClientId": "CLIENT12345",
|
||||
"ServerSideTokenCheck": True,
|
||||
}
|
||||
],
|
||||
SamlProviderARNs=['arn:aws:rds:eu-west-2:123456789012:db:mysql-db'])
|
||||
assert result['IdentityPoolId'] != ''
|
||||
SamlProviderARNs=["arn:aws:rds:eu-west-2:{}:db:mysql-db".format(ACCOUNT_ID)],
|
||||
)
|
||||
assert result["IdentityPoolId"] != ""
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_describe_identity_pool():
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
|
||||
res = conn.create_identity_pool(
|
||||
IdentityPoolName="TestPool",
|
||||
AllowUnauthenticatedIdentities=False,
|
||||
SupportedLoginProviders={"graph.facebook.com": "123456789012345"},
|
||||
DeveloperProviderName="devname",
|
||||
OpenIdConnectProviderARNs=[
|
||||
"arn:aws:rds:eu-west-2:{}:db:mysql-db".format(ACCOUNT_ID)
|
||||
],
|
||||
CognitoIdentityProviders=[
|
||||
{
|
||||
"ProviderName": "testprovider",
|
||||
"ClientId": "CLIENT12345",
|
||||
"ServerSideTokenCheck": True,
|
||||
}
|
||||
],
|
||||
SamlProviderARNs=["arn:aws:rds:eu-west-2:{}:db:mysql-db".format(ACCOUNT_ID)],
|
||||
)
|
||||
|
||||
result = conn.describe_identity_pool(IdentityPoolId=res["IdentityPoolId"])
|
||||
|
||||
assert result["IdentityPoolId"] == res["IdentityPoolId"]
|
||||
assert (
|
||||
result["AllowUnauthenticatedIdentities"]
|
||||
== res["AllowUnauthenticatedIdentities"]
|
||||
)
|
||||
assert result["SupportedLoginProviders"] == res["SupportedLoginProviders"]
|
||||
assert result["DeveloperProviderName"] == res["DeveloperProviderName"]
|
||||
assert result["OpenIdConnectProviderARNs"] == res["OpenIdConnectProviderARNs"]
|
||||
assert result["CognitoIdentityProviders"] == res["CognitoIdentityProviders"]
|
||||
assert result["SamlProviderARNs"] == res["SamlProviderARNs"]
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_describe_identity_pool_with_invalid_id_raises_error():
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
|
||||
with assert_raises(ClientError) as cm:
|
||||
conn.describe_identity_pool(IdentityPoolId="us-west-2_non-existent")
|
||||
|
||||
cm.exception.operation_name.should.equal("DescribeIdentityPool")
|
||||
cm.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
|
||||
# testing a helper function
|
||||
def test_get_random_identity_id():
|
||||
assert len(get_random_identity_id('us-west-2')) > 0
|
||||
assert len(get_random_identity_id('us-west-2').split(':')[1]) == 19
|
||||
assert len(get_random_identity_id("us-west-2")) > 0
|
||||
assert len(get_random_identity_id("us-west-2").split(":")[1]) == 19
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_id():
|
||||
# These two do NOT work in server mode. They just don't return the data from the model.
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
result = conn.get_id(AccountId='someaccount',
|
||||
IdentityPoolId='us-west-2:12345',
|
||||
Logins={
|
||||
'someurl': '12345'
|
||||
})
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
result = conn.get_id(
|
||||
AccountId="someaccount",
|
||||
IdentityPoolId="us-west-2:12345",
|
||||
Logins={"someurl": "12345"},
|
||||
)
|
||||
print(result)
|
||||
assert result.get('IdentityId', "").startswith('us-west-2') or result.get('ResponseMetadata').get('HTTPStatusCode') == 200
|
||||
assert (
|
||||
result.get("IdentityId", "").startswith("us-west-2")
|
||||
or result.get("ResponseMetadata").get("HTTPStatusCode") == 200
|
||||
)
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_credentials_for_identity():
|
||||
# These two do NOT work in server mode. They just don't return the data from the model.
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
result = conn.get_credentials_for_identity(IdentityId='12345')
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
result = conn.get_credentials_for_identity(IdentityId="12345")
|
||||
|
||||
assert result.get('Expiration', 0) > 0 or result.get('ResponseMetadata').get('HTTPStatusCode') == 200
|
||||
assert result.get('IdentityId') == '12345' or result.get('ResponseMetadata').get('HTTPStatusCode') == 200
|
||||
assert (
|
||||
result.get("Expiration", 0) > 0
|
||||
or result.get("ResponseMetadata").get("HTTPStatusCode") == 200
|
||||
)
|
||||
assert (
|
||||
result.get("IdentityId") == "12345"
|
||||
or result.get("ResponseMetadata").get("HTTPStatusCode") == 200
|
||||
)
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_open_id_token_for_developer_identity():
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
result = conn.get_open_id_token_for_developer_identity(
|
||||
IdentityPoolId='us-west-2:12345',
|
||||
IdentityId='12345',
|
||||
Logins={
|
||||
'someurl': '12345'
|
||||
},
|
||||
TokenDuration=123
|
||||
IdentityPoolId="us-west-2:12345",
|
||||
IdentityId="12345",
|
||||
Logins={"someurl": "12345"},
|
||||
TokenDuration=123,
|
||||
)
|
||||
assert len(result['Token']) > 0
|
||||
assert result['IdentityId'] == '12345'
|
||||
assert len(result["Token"]) > 0
|
||||
assert result["IdentityId"] == "12345"
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_open_id_token_for_developer_identity_when_no_explicit_identity_id():
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
result = conn.get_open_id_token_for_developer_identity(
|
||||
IdentityPoolId='us-west-2:12345',
|
||||
Logins={
|
||||
'someurl': '12345'
|
||||
},
|
||||
TokenDuration=123
|
||||
IdentityPoolId="us-west-2:12345", Logins={"someurl": "12345"}, TokenDuration=123
|
||||
)
|
||||
assert len(result['Token']) > 0
|
||||
assert len(result['IdentityId']) > 0
|
||||
assert len(result["Token"]) > 0
|
||||
assert len(result["IdentityId"]) > 0
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_open_id_token():
|
||||
conn = boto3.client('cognito-identity', 'us-west-2')
|
||||
result = conn.get_open_id_token(
|
||||
IdentityId='12345',
|
||||
Logins={
|
||||
'someurl': '12345'
|
||||
}
|
||||
)
|
||||
assert len(result['Token']) > 0
|
||||
assert result['IdentityId'] == '12345'
|
||||
conn = boto3.client("cognito-identity", "us-west-2")
|
||||
result = conn.get_open_id_token(IdentityId="12345", Logins={"someurl": "12345"})
|
||||
assert len(result["Token"]) > 0
|
||||
assert result["IdentityId"] == "12345"
|
||||
|
|
|
|||
|
|
@ -1,45 +1,53 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
from moto import mock_cognitoidentity
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_create_identity_pool():
|
||||
|
||||
backend = server.create_backend_app("cognito-identity")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post('/',
|
||||
data={"IdentityPoolName": "test", "AllowUnauthenticatedIdentities": True},
|
||||
headers={
|
||||
"X-Amz-Target": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.CreateIdentityPool"},
|
||||
)
|
||||
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
assert json_data['IdentityPoolName'] == "test"
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_id():
|
||||
backend = server.create_backend_app("cognito-identity")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post('/',
|
||||
data=json.dumps({'AccountId': 'someaccount',
|
||||
'IdentityPoolId': 'us-west-2:12345',
|
||||
'Logins': {'someurl': '12345'}}),
|
||||
headers={
|
||||
"X-Amz-Target": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetId"},
|
||||
)
|
||||
|
||||
print(res.data)
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
assert ':' in json_data['IdentityId']
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
from moto import mock_cognitoidentity
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_create_identity_pool():
|
||||
|
||||
backend = server.create_backend_app("cognito-identity")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post(
|
||||
"/",
|
||||
data={"IdentityPoolName": "test", "AllowUnauthenticatedIdentities": True},
|
||||
headers={
|
||||
"X-Amz-Target": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.CreateIdentityPool"
|
||||
},
|
||||
)
|
||||
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
assert json_data["IdentityPoolName"] == "test"
|
||||
|
||||
|
||||
@mock_cognitoidentity
|
||||
def test_get_id():
|
||||
backend = server.create_backend_app("cognito-identity")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post(
|
||||
"/",
|
||||
data=json.dumps(
|
||||
{
|
||||
"AccountId": "someaccount",
|
||||
"IdentityPoolId": "us-west-2:12345",
|
||||
"Logins": {"someurl": "12345"},
|
||||
}
|
||||
),
|
||||
headers={
|
||||
"X-Amz-Target": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetId"
|
||||
},
|
||||
)
|
||||
|
||||
print(res.data)
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
assert ":" in json_data["IdentityId"]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import random
|
|||
import uuid
|
||||
|
||||
import boto3
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
import sure # noqa
|
||||
from botocore.exceptions import ClientError
|
||||
|
|
@ -13,6 +14,7 @@ from jose import jws
|
|||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_cognitoidp
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -21,15 +23,10 @@ def test_create_user_pool():
|
|||
|
||||
name = str(uuid.uuid4())
|
||||
value = str(uuid.uuid4())
|
||||
result = conn.create_user_pool(
|
||||
PoolName=name,
|
||||
LambdaConfig={
|
||||
"PreSignUp": value
|
||||
}
|
||||
)
|
||||
result = conn.create_user_pool(PoolName=name, LambdaConfig={"PreSignUp": value})
|
||||
|
||||
result["UserPool"]["Id"].should_not.be.none
|
||||
result["UserPool"]["Id"].should.match(r'[\w-]+_[0-9a-zA-Z]+')
|
||||
result["UserPool"]["Id"].should.match(r"[\w-]+_[0-9a-zA-Z]+")
|
||||
result["UserPool"]["Name"].should.equal(name)
|
||||
result["UserPool"]["LambdaConfig"]["PreSignUp"].should.equal(value)
|
||||
|
||||
|
|
@ -102,10 +99,7 @@ def test_describe_user_pool():
|
|||
name = str(uuid.uuid4())
|
||||
value = str(uuid.uuid4())
|
||||
user_pool_details = conn.create_user_pool(
|
||||
PoolName=name,
|
||||
LambdaConfig={
|
||||
"PreSignUp": value
|
||||
}
|
||||
PoolName=name, LambdaConfig={"PreSignUp": value}
|
||||
)
|
||||
|
||||
result = conn.describe_user_pool(UserPoolId=user_pool_details["UserPool"]["Id"])
|
||||
|
|
@ -139,7 +133,9 @@ def test_create_user_pool_domain_custom_domain_config():
|
|||
|
||||
domain = str(uuid.uuid4())
|
||||
custom_domain_config = {
|
||||
"CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/123456789012",
|
||||
"CertificateArn": "arn:aws:acm:us-east-1:{}:certificate/123456789012".format(
|
||||
ACCOUNT_ID
|
||||
)
|
||||
}
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
result = conn.create_user_pool_domain(
|
||||
|
|
@ -184,7 +180,9 @@ def test_update_user_pool_domain():
|
|||
|
||||
domain = str(uuid.uuid4())
|
||||
custom_domain_config = {
|
||||
"CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/123456789012",
|
||||
"CertificateArn": "arn:aws:acm:us-east-1:{}:certificate/123456789012".format(
|
||||
ACCOUNT_ID
|
||||
)
|
||||
}
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
conn.create_user_pool_domain(UserPoolId=user_pool_id, Domain=domain)
|
||||
|
|
@ -203,9 +201,7 @@ def test_create_user_pool_client():
|
|||
value = str(uuid.uuid4())
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
result = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=client_name,
|
||||
CallbackURLs=[value],
|
||||
UserPoolId=user_pool_id, ClientName=client_name, CallbackURLs=[value]
|
||||
)
|
||||
|
||||
result["UserPoolClient"]["UserPoolId"].should.equal(user_pool_id)
|
||||
|
|
@ -236,11 +232,11 @@ def test_list_user_pool_clients_returns_max_items():
|
|||
client_count = 10
|
||||
for i in range(client_count):
|
||||
client_name = str(uuid.uuid4())
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id,
|
||||
ClientName=client_name)
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id, ClientName=client_name)
|
||||
max_results = 5
|
||||
result = conn.list_user_pool_clients(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results)
|
||||
result = conn.list_user_pool_clients(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["UserPoolClients"].should.have.length_of(max_results)
|
||||
result.should.have.key("NextToken")
|
||||
|
||||
|
|
@ -254,18 +250,18 @@ def test_list_user_pool_clients_returns_next_tokens():
|
|||
client_count = 10
|
||||
for i in range(client_count):
|
||||
client_name = str(uuid.uuid4())
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id,
|
||||
ClientName=client_name)
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id, ClientName=client_name)
|
||||
max_results = 5
|
||||
result = conn.list_user_pool_clients(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results)
|
||||
result = conn.list_user_pool_clients(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["UserPoolClients"].should.have.length_of(max_results)
|
||||
result.should.have.key("NextToken")
|
||||
|
||||
next_token = result["NextToken"]
|
||||
result_2 = conn.list_user_pool_clients(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results,
|
||||
NextToken=next_token)
|
||||
result_2 = conn.list_user_pool_clients(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results, NextToken=next_token
|
||||
)
|
||||
result_2["UserPoolClients"].should.have.length_of(max_results)
|
||||
result_2.shouldnt.have.key("NextToken")
|
||||
|
||||
|
|
@ -279,11 +275,11 @@ def test_list_user_pool_clients_when_max_items_more_than_total_items():
|
|||
client_count = 10
|
||||
for i in range(client_count):
|
||||
client_name = str(uuid.uuid4())
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id,
|
||||
ClientName=client_name)
|
||||
conn.create_user_pool_client(UserPoolId=user_pool_id, ClientName=client_name)
|
||||
max_results = client_count + 5
|
||||
result = conn.list_user_pool_clients(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results)
|
||||
result = conn.list_user_pool_clients(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["UserPoolClients"].should.have.length_of(client_count)
|
||||
result.shouldnt.have.key("NextToken")
|
||||
|
||||
|
|
@ -296,14 +292,11 @@ def test_describe_user_pool_client():
|
|||
value = str(uuid.uuid4())
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
client_details = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=client_name,
|
||||
CallbackURLs=[value],
|
||||
UserPoolId=user_pool_id, ClientName=client_name, CallbackURLs=[value]
|
||||
)
|
||||
|
||||
result = conn.describe_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientId=client_details["UserPoolClient"]["ClientId"],
|
||||
UserPoolId=user_pool_id, ClientId=client_details["UserPoolClient"]["ClientId"]
|
||||
)
|
||||
|
||||
result["UserPoolClient"]["ClientName"].should.equal(client_name)
|
||||
|
|
@ -321,9 +314,7 @@ def test_update_user_pool_client():
|
|||
new_value = str(uuid.uuid4())
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
client_details = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=old_client_name,
|
||||
CallbackURLs=[old_value],
|
||||
UserPoolId=user_pool_id, ClientName=old_client_name, CallbackURLs=[old_value]
|
||||
)
|
||||
|
||||
result = conn.update_user_pool_client(
|
||||
|
|
@ -344,13 +335,11 @@ def test_delete_user_pool_client():
|
|||
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
client_details = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=str(uuid.uuid4()),
|
||||
UserPoolId=user_pool_id, ClientName=str(uuid.uuid4())
|
||||
)
|
||||
|
||||
conn.delete_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientId=client_details["UserPoolClient"]["ClientId"],
|
||||
UserPoolId=user_pool_id, ClientId=client_details["UserPoolClient"]["ClientId"]
|
||||
)
|
||||
|
||||
caught = False
|
||||
|
|
@ -377,9 +366,7 @@ def test_create_identity_provider():
|
|||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
ProviderType=provider_type,
|
||||
ProviderDetails={
|
||||
"thing": value
|
||||
},
|
||||
ProviderDetails={"thing": value},
|
||||
)
|
||||
|
||||
result["IdentityProvider"]["UserPoolId"].should.equal(user_pool_id)
|
||||
|
|
@ -402,10 +389,7 @@ def test_list_identity_providers():
|
|||
ProviderDetails={},
|
||||
)
|
||||
|
||||
result = conn.list_identity_providers(
|
||||
UserPoolId=user_pool_id,
|
||||
MaxResults=10,
|
||||
)
|
||||
result = conn.list_identity_providers(UserPoolId=user_pool_id, MaxResults=10)
|
||||
|
||||
result["Providers"].should.have.length_of(1)
|
||||
result["Providers"][0]["ProviderName"].should.equal(provider_name)
|
||||
|
|
@ -430,8 +414,9 @@ def test_list_identity_providers_returns_max_items():
|
|||
)
|
||||
|
||||
max_results = 5
|
||||
result = conn.list_identity_providers(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results)
|
||||
result = conn.list_identity_providers(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["Providers"].should.have.length_of(max_results)
|
||||
result.should.have.key("NextToken")
|
||||
|
||||
|
|
@ -454,14 +439,16 @@ def test_list_identity_providers_returns_next_tokens():
|
|||
)
|
||||
|
||||
max_results = 5
|
||||
result = conn.list_identity_providers(UserPoolId=user_pool_id, MaxResults=max_results)
|
||||
result = conn.list_identity_providers(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["Providers"].should.have.length_of(max_results)
|
||||
result.should.have.key("NextToken")
|
||||
|
||||
next_token = result["NextToken"]
|
||||
result_2 = conn.list_identity_providers(UserPoolId=user_pool_id,
|
||||
MaxResults=max_results,
|
||||
NextToken=next_token)
|
||||
result_2 = conn.list_identity_providers(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results, NextToken=next_token
|
||||
)
|
||||
result_2["Providers"].should.have.length_of(max_results)
|
||||
result_2.shouldnt.have.key("NextToken")
|
||||
|
||||
|
|
@ -484,7 +471,9 @@ def test_list_identity_providers_when_max_items_more_than_total_items():
|
|||
)
|
||||
|
||||
max_results = identity_provider_count + 5
|
||||
result = conn.list_identity_providers(UserPoolId=user_pool_id, MaxResults=max_results)
|
||||
result = conn.list_identity_providers(
|
||||
UserPoolId=user_pool_id, MaxResults=max_results
|
||||
)
|
||||
result["Providers"].should.have.length_of(identity_provider_count)
|
||||
result.shouldnt.have.key("NextToken")
|
||||
|
||||
|
|
@ -501,14 +490,11 @@ def test_describe_identity_providers():
|
|||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
ProviderType=provider_type,
|
||||
ProviderDetails={
|
||||
"thing": value
|
||||
},
|
||||
ProviderDetails={"thing": value},
|
||||
)
|
||||
|
||||
result = conn.describe_identity_provider(
|
||||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
UserPoolId=user_pool_id, ProviderName=provider_name
|
||||
)
|
||||
|
||||
result["IdentityProvider"]["UserPoolId"].should.equal(user_pool_id)
|
||||
|
|
@ -530,17 +516,13 @@ def test_update_identity_provider():
|
|||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
ProviderType=provider_type,
|
||||
ProviderDetails={
|
||||
"thing": value
|
||||
},
|
||||
ProviderDetails={"thing": value},
|
||||
)
|
||||
|
||||
result = conn.update_identity_provider(
|
||||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
ProviderDetails={
|
||||
"thing": new_value
|
||||
},
|
||||
ProviderDetails={"thing": new_value},
|
||||
)
|
||||
|
||||
result["IdentityProvider"]["UserPoolId"].should.equal(user_pool_id)
|
||||
|
|
@ -557,16 +539,12 @@ def test_update_identity_provider_no_user_pool():
|
|||
|
||||
with assert_raises(conn.exceptions.ResourceNotFoundException) as cm:
|
||||
conn.update_identity_provider(
|
||||
UserPoolId="foo",
|
||||
ProviderName="bar",
|
||||
ProviderDetails={
|
||||
"thing": new_value
|
||||
},
|
||||
UserPoolId="foo", ProviderName="bar", ProviderDetails={"thing": new_value}
|
||||
)
|
||||
|
||||
cm.exception.operation_name.should.equal('UpdateIdentityProvider')
|
||||
cm.exception.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
cm.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
|
||||
cm.exception.operation_name.should.equal("UpdateIdentityProvider")
|
||||
cm.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -583,14 +561,12 @@ def test_update_identity_provider_no_identity_provider():
|
|||
conn.update_identity_provider(
|
||||
UserPoolId=user_pool_id,
|
||||
ProviderName="foo",
|
||||
ProviderDetails={
|
||||
"thing": new_value
|
||||
},
|
||||
ProviderDetails={"thing": new_value},
|
||||
)
|
||||
|
||||
cm.exception.operation_name.should.equal('UpdateIdentityProvider')
|
||||
cm.exception.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
cm.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
|
||||
cm.exception.operation_name.should.equal("UpdateIdentityProvider")
|
||||
cm.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -605,9 +581,7 @@ def test_delete_identity_providers():
|
|||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
ProviderType=provider_type,
|
||||
ProviderDetails={
|
||||
"thing": value
|
||||
},
|
||||
ProviderDetails={"thing": value},
|
||||
)
|
||||
|
||||
conn.delete_identity_provider(UserPoolId=user_pool_id, ProviderName=provider_name)
|
||||
|
|
@ -615,8 +589,7 @@ def test_delete_identity_providers():
|
|||
caught = False
|
||||
try:
|
||||
conn.describe_identity_provider(
|
||||
UserPoolId=user_pool_id,
|
||||
ProviderName=provider_name,
|
||||
UserPoolId=user_pool_id, ProviderName=provider_name
|
||||
)
|
||||
except conn.exceptions.ResourceNotFoundException:
|
||||
caught = True
|
||||
|
|
@ -662,9 +635,9 @@ def test_create_group_with_duplicate_name_raises_error():
|
|||
|
||||
with assert_raises(ClientError) as cm:
|
||||
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||
cm.exception.operation_name.should.equal('CreateGroup')
|
||||
cm.exception.response['Error']['Code'].should.equal('GroupExistsException')
|
||||
cm.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
|
||||
cm.exception.operation_name.should.equal("CreateGroup")
|
||||
cm.exception.response["Error"]["Code"].should.equal("GroupExistsException")
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -710,7 +683,7 @@ def test_delete_group():
|
|||
|
||||
with assert_raises(ClientError) as cm:
|
||||
conn.get_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||
cm.exception.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||
cm.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -724,7 +697,9 @@ def test_admin_add_user_to_group():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
result = conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
result = conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||
|
||||
|
||||
|
|
@ -739,8 +714,12 @@ def test_admin_add_user_to_group_again_is_noop():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -754,7 +733,9 @@ def test_list_users_in_group():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
|
||||
result = conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name)
|
||||
|
||||
|
|
@ -775,8 +756,12 @@ def test_list_users_in_group_ignores_deleted_user():
|
|||
username2 = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username2)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username2, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username2, GroupName=group_name
|
||||
)
|
||||
conn.admin_delete_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
result = conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name)
|
||||
|
|
@ -796,7 +781,9 @@ def test_admin_list_groups_for_user():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
|
||||
result = conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id)
|
||||
|
||||
|
|
@ -817,8 +804,12 @@ def test_admin_list_groups_for_user_ignores_deleted_group():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name2)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name2
|
||||
)
|
||||
conn.delete_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||
|
||||
result = conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id)
|
||||
|
|
@ -838,14 +829,20 @@ def test_admin_remove_user_from_group():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
|
||||
result = conn.admin_remove_user_from_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
result = conn.admin_remove_user_from_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||
conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name) \
|
||||
["Users"].should.have.length_of(0)
|
||||
conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id) \
|
||||
["Groups"].should.have.length_of(0)
|
||||
conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name)[
|
||||
"Users"
|
||||
].should.have.length_of(0)
|
||||
conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id)[
|
||||
"Groups"
|
||||
].should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -859,8 +856,12 @@ def test_admin_remove_user_from_group_again_is_noop():
|
|||
username = str(uuid.uuid4())
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
conn.admin_add_user_to_group(
|
||||
UserPoolId=user_pool_id, Username=username, GroupName=group_name
|
||||
)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -873,9 +874,7 @@ def test_admin_create_user():
|
|||
result = conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[
|
||||
{"Name": "thing", "Value": value}
|
||||
],
|
||||
UserAttributes=[{"Name": "thing", "Value": value}],
|
||||
)
|
||||
|
||||
result["User"]["Username"].should.equal(username)
|
||||
|
|
@ -886,6 +885,32 @@ def test_admin_create_user():
|
|||
result["User"]["Enabled"].should.equal(True)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
def test_admin_create_existing_user():
|
||||
conn = boto3.client("cognito-idp", "us-west-2")
|
||||
|
||||
username = str(uuid.uuid4())
|
||||
value = str(uuid.uuid4())
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[{"Name": "thing", "Value": value}],
|
||||
)
|
||||
|
||||
caught = False
|
||||
try:
|
||||
conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[{"Name": "thing", "Value": value}],
|
||||
)
|
||||
except conn.exceptions.UsernameExistsException:
|
||||
caught = True
|
||||
|
||||
caught.should.be.true
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
def test_admin_get_user():
|
||||
conn = boto3.client("cognito-idp", "us-west-2")
|
||||
|
|
@ -896,9 +921,7 @@ def test_admin_get_user():
|
|||
conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[
|
||||
{"Name": "thing", "Value": value}
|
||||
],
|
||||
UserAttributes=[{"Name": "thing", "Value": value}],
|
||||
)
|
||||
|
||||
result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username)
|
||||
|
|
@ -944,8 +967,7 @@ def test_list_users_returns_limit_items():
|
|||
# Given 10 users
|
||||
user_count = 10
|
||||
for i in range(user_count):
|
||||
conn.admin_create_user(UserPoolId=user_pool_id,
|
||||
Username=str(uuid.uuid4()))
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=str(uuid.uuid4()))
|
||||
max_results = 5
|
||||
result = conn.list_users(UserPoolId=user_pool_id, Limit=max_results)
|
||||
result["Users"].should.have.length_of(max_results)
|
||||
|
|
@ -960,8 +982,7 @@ def test_list_users_returns_pagination_tokens():
|
|||
# Given 10 users
|
||||
user_count = 10
|
||||
for i in range(user_count):
|
||||
conn.admin_create_user(UserPoolId=user_pool_id,
|
||||
Username=str(uuid.uuid4()))
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=str(uuid.uuid4()))
|
||||
|
||||
max_results = 5
|
||||
result = conn.list_users(UserPoolId=user_pool_id, Limit=max_results)
|
||||
|
|
@ -969,8 +990,9 @@ def test_list_users_returns_pagination_tokens():
|
|||
result.should.have.key("PaginationToken")
|
||||
|
||||
next_token = result["PaginationToken"]
|
||||
result_2 = conn.list_users(UserPoolId=user_pool_id,
|
||||
Limit=max_results, PaginationToken=next_token)
|
||||
result_2 = conn.list_users(
|
||||
UserPoolId=user_pool_id, Limit=max_results, PaginationToken=next_token
|
||||
)
|
||||
result_2["Users"].should.have.length_of(max_results)
|
||||
result_2.shouldnt.have.key("PaginationToken")
|
||||
|
||||
|
|
@ -983,8 +1005,7 @@ def test_list_users_when_limit_more_than_total_items():
|
|||
# Given 10 users
|
||||
user_count = 10
|
||||
for i in range(user_count):
|
||||
conn.admin_create_user(UserPoolId=user_pool_id,
|
||||
Username=str(uuid.uuid4()))
|
||||
conn.admin_create_user(UserPoolId=user_pool_id, Username=str(uuid.uuid4()))
|
||||
|
||||
max_results = user_count + 5
|
||||
result = conn.list_users(UserPoolId=user_pool_id, Limit=max_results)
|
||||
|
|
@ -1003,8 +1024,9 @@ def test_admin_disable_user():
|
|||
result = conn.admin_disable_user(UserPoolId=user_pool_id, Username=username)
|
||||
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||
|
||||
conn.admin_get_user(UserPoolId=user_pool_id, Username=username) \
|
||||
["Enabled"].should.equal(False)
|
||||
conn.admin_get_user(UserPoolId=user_pool_id, Username=username)[
|
||||
"Enabled"
|
||||
].should.equal(False)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -1019,8 +1041,9 @@ def test_admin_enable_user():
|
|||
result = conn.admin_enable_user(UserPoolId=user_pool_id, Username=username)
|
||||
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||
|
||||
conn.admin_get_user(UserPoolId=user_pool_id, Username=username) \
|
||||
["Enabled"].should.equal(True)
|
||||
conn.admin_get_user(UserPoolId=user_pool_id, Username=username)[
|
||||
"Enabled"
|
||||
].should.equal(True)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
|
|
@ -1050,27 +1073,21 @@ def authentication_flow(conn):
|
|||
client_id = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=str(uuid.uuid4()),
|
||||
ReadAttributes=[user_attribute_name]
|
||||
ReadAttributes=[user_attribute_name],
|
||||
)["UserPoolClient"]["ClientId"]
|
||||
|
||||
conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
TemporaryPassword=temporary_password,
|
||||
UserAttributes=[{
|
||||
'Name': user_attribute_name,
|
||||
'Value': user_attribute_value
|
||||
}]
|
||||
UserAttributes=[{"Name": user_attribute_name, "Value": user_attribute_value}],
|
||||
)
|
||||
|
||||
result = conn.admin_initiate_auth(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientId=client_id,
|
||||
AuthFlow="ADMIN_NO_SRP_AUTH",
|
||||
AuthParameters={
|
||||
"USERNAME": username,
|
||||
"PASSWORD": temporary_password
|
||||
},
|
||||
AuthParameters={"USERNAME": username, "PASSWORD": temporary_password},
|
||||
)
|
||||
|
||||
# A newly created user is forced to set a new password
|
||||
|
|
@ -1083,10 +1100,7 @@ def authentication_flow(conn):
|
|||
Session=result["Session"],
|
||||
ClientId=client_id,
|
||||
ChallengeName="NEW_PASSWORD_REQUIRED",
|
||||
ChallengeResponses={
|
||||
"USERNAME": username,
|
||||
"NEW_PASSWORD": new_password
|
||||
}
|
||||
ChallengeResponses={"USERNAME": username, "NEW_PASSWORD": new_password},
|
||||
)
|
||||
|
||||
result["AuthenticationResult"]["IdToken"].should_not.be.none
|
||||
|
|
@ -1099,9 +1113,7 @@ def authentication_flow(conn):
|
|||
"access_token": result["AuthenticationResult"]["AccessToken"],
|
||||
"username": username,
|
||||
"password": new_password,
|
||||
"additional_fields": {
|
||||
user_attribute_name: user_attribute_value
|
||||
}
|
||||
"additional_fields": {user_attribute_name: user_attribute_value},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1124,7 +1136,9 @@ def test_token_legitimacy():
|
|||
id_token = outputs["id_token"]
|
||||
access_token = outputs["access_token"]
|
||||
client_id = outputs["client_id"]
|
||||
issuer = "https://cognito-idp.us-west-2.amazonaws.com/{}".format(outputs["user_pool_id"])
|
||||
issuer = "https://cognito-idp.us-west-2.amazonaws.com/{}".format(
|
||||
outputs["user_pool_id"]
|
||||
)
|
||||
id_claims = json.loads(jws.verify(id_token, json_web_key, "RS256"))
|
||||
id_claims["iss"].should.equal(issuer)
|
||||
id_claims["aud"].should.equal(client_id)
|
||||
|
|
@ -1155,10 +1169,7 @@ def test_change_password():
|
|||
UserPoolId=outputs["user_pool_id"],
|
||||
ClientId=outputs["client_id"],
|
||||
AuthFlow="ADMIN_NO_SRP_AUTH",
|
||||
AuthParameters={
|
||||
"USERNAME": outputs["username"],
|
||||
"PASSWORD": newer_password,
|
||||
},
|
||||
AuthParameters={"USERNAME": outputs["username"], "PASSWORD": newer_password},
|
||||
)
|
||||
|
||||
result["AuthenticationResult"].should_not.be.none
|
||||
|
|
@ -1168,7 +1179,9 @@ def test_change_password():
|
|||
def test_forgot_password():
|
||||
conn = boto3.client("cognito-idp", "us-west-2")
|
||||
|
||||
result = conn.forgot_password(ClientId=str(uuid.uuid4()), Username=str(uuid.uuid4()))
|
||||
result = conn.forgot_password(
|
||||
ClientId=str(uuid.uuid4()), Username=str(uuid.uuid4())
|
||||
)
|
||||
result["CodeDeliveryDetails"].should_not.be.none
|
||||
|
||||
|
||||
|
|
@ -1179,14 +1192,11 @@ def test_confirm_forgot_password():
|
|||
username = str(uuid.uuid4())
|
||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||
client_id = conn.create_user_pool_client(
|
||||
UserPoolId=user_pool_id,
|
||||
ClientName=str(uuid.uuid4()),
|
||||
UserPoolId=user_pool_id, ClientName=str(uuid.uuid4())
|
||||
)["UserPoolClient"]["ClientId"]
|
||||
|
||||
conn.admin_create_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
TemporaryPassword=str(uuid.uuid4()),
|
||||
UserPoolId=user_pool_id, Username=username, TemporaryPassword=str(uuid.uuid4())
|
||||
)
|
||||
|
||||
conn.confirm_forgot_password(
|
||||
|
|
@ -1196,6 +1206,7 @@ def test_confirm_forgot_password():
|
|||
Password=str(uuid.uuid4()),
|
||||
)
|
||||
|
||||
|
||||
@mock_cognitoidp
|
||||
def test_admin_update_user_attributes():
|
||||
conn = boto3.client("cognito-idp", "us-west-2")
|
||||
|
|
@ -1207,41 +1218,26 @@ def test_admin_update_user_attributes():
|
|||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[
|
||||
{
|
||||
'Name': 'family_name',
|
||||
'Value': 'Doe',
|
||||
},
|
||||
{
|
||||
'Name': 'given_name',
|
||||
'Value': 'John',
|
||||
}
|
||||
]
|
||||
{"Name": "family_name", "Value": "Doe"},
|
||||
{"Name": "given_name", "Value": "John"},
|
||||
],
|
||||
)
|
||||
|
||||
conn.admin_update_user_attributes(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username,
|
||||
UserAttributes=[
|
||||
{
|
||||
'Name': 'family_name',
|
||||
'Value': 'Doe',
|
||||
},
|
||||
{
|
||||
'Name': 'given_name',
|
||||
'Value': 'Jane',
|
||||
}
|
||||
]
|
||||
{"Name": "family_name", "Value": "Doe"},
|
||||
{"Name": "given_name", "Value": "Jane"},
|
||||
],
|
||||
)
|
||||
|
||||
user = conn.admin_get_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username=username
|
||||
)
|
||||
attributes = user['UserAttributes']
|
||||
user = conn.admin_get_user(UserPoolId=user_pool_id, Username=username)
|
||||
attributes = user["UserAttributes"]
|
||||
attributes.should.be.a(list)
|
||||
for attr in attributes:
|
||||
val = attr['Value']
|
||||
if attr['Name'] == 'family_name':
|
||||
val.should.equal('Doe')
|
||||
elif attr['Name'] == 'given_name':
|
||||
val.should.equal('Jane')
|
||||
val = attr["Value"]
|
||||
if attr["Name"] == "family_name":
|
||||
val.should.equal("Doe")
|
||||
elif attr["Name"] == "given_name":
|
||||
val.should.equal("Jane")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -5,8 +5,8 @@ from moto import mock_sqs, settings
|
|||
|
||||
def test_context_manager_returns_mock():
|
||||
with mock_sqs() as sqs_mock:
|
||||
conn = boto3.client("sqs", region_name='us-west-1')
|
||||
conn = boto3.client("sqs", region_name="us-west-1")
|
||||
conn.create_queue(QueueName="queue1")
|
||||
|
||||
if not settings.TEST_SERVER_MODE:
|
||||
list(sqs_mock.backends['us-west-1'].queues.keys()).should.equal(['queue1'])
|
||||
list(sqs_mock.backends["us-west-1"].queues.keys()).should.equal(["queue1"])
|
||||
|
|
|
|||
|
|
@ -1,98 +1,96 @@
|
|||
from __future__ import unicode_literals
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa
|
||||
import unittest
|
||||
|
||||
import tests.backport_assert_raises # noqa
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_s3_deprecated
|
||||
|
||||
'''
|
||||
Test the different ways that the decorator can be used
|
||||
'''
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_basic_connect():
|
||||
boto.connect_ec2()
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_basic_decorator():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
|
||||
|
||||
def test_context_manager():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
with mock_ec2_deprecated():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn.get_all_instances()
|
||||
|
||||
|
||||
def test_decorator_start_and_stop():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
mock = mock_ec2_deprecated()
|
||||
mock.start()
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
mock.stop()
|
||||
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_decorater_wrapped_gets_set():
|
||||
"""
|
||||
Moto decorator's __wrapped__ should get set to the tests function
|
||||
"""
|
||||
test_decorater_wrapped_gets_set.__wrapped__.__name__.should.equal(
|
||||
'test_decorater_wrapped_gets_set')
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
class Tester(object):
|
||||
|
||||
def test_the_class(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_instances()).should.have.length_of(0)
|
||||
|
||||
def test_still_the_same(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_instances()).should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_s3_deprecated
|
||||
class TesterWithSetup(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.conn = boto.connect_s3()
|
||||
self.conn.create_bucket('mybucket')
|
||||
|
||||
def test_still_the_same(self):
|
||||
bucket = self.conn.get_bucket('mybucket')
|
||||
bucket.name.should.equal("mybucket")
|
||||
|
||||
|
||||
@mock_s3_deprecated
|
||||
class TesterWithStaticmethod(object):
|
||||
|
||||
@staticmethod
|
||||
def static(*args):
|
||||
assert not args or not isinstance(args[0], TesterWithStaticmethod)
|
||||
|
||||
def test_no_instance_sent_to_staticmethod(self):
|
||||
self.static()
|
||||
from __future__ import unicode_literals
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa
|
||||
import unittest
|
||||
|
||||
import tests.backport_assert_raises # noqa
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_s3_deprecated
|
||||
|
||||
"""
|
||||
Test the different ways that the decorator can be used
|
||||
"""
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_basic_connect():
|
||||
boto.connect_ec2()
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_basic_decorator():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
|
||||
|
||||
def test_context_manager():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
with mock_ec2_deprecated():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
conn.get_all_instances()
|
||||
|
||||
|
||||
def test_decorator_start_and_stop():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
mock = mock_ec2_deprecated()
|
||||
mock.start()
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_instances()).should.equal([])
|
||||
mock.stop()
|
||||
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.get_all_instances()
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_decorater_wrapped_gets_set():
|
||||
"""
|
||||
Moto decorator's __wrapped__ should get set to the tests function
|
||||
"""
|
||||
test_decorater_wrapped_gets_set.__wrapped__.__name__.should.equal(
|
||||
"test_decorater_wrapped_gets_set"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
class Tester(object):
|
||||
def test_the_class(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_instances()).should.have.length_of(0)
|
||||
|
||||
def test_still_the_same(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_instances()).should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_s3_deprecated
|
||||
class TesterWithSetup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.conn = boto.connect_s3()
|
||||
self.conn.create_bucket("mybucket")
|
||||
|
||||
def test_still_the_same(self):
|
||||
bucket = self.conn.get_bucket("mybucket")
|
||||
bucket.name.should.equal("mybucket")
|
||||
|
||||
|
||||
@mock_s3_deprecated
|
||||
class TesterWithStaticmethod(object):
|
||||
@staticmethod
|
||||
def static(*args):
|
||||
assert not args or not isinstance(args[0], TesterWithStaticmethod)
|
||||
|
||||
def test_no_instance_sent_to_staticmethod(self):
|
||||
self.static()
|
||||
|
|
|
|||
|
|
@ -1,46 +1,48 @@
|
|||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
import requests
|
||||
|
||||
from moto import mock_ec2, settings
|
||||
|
||||
if settings.TEST_SERVER_MODE:
|
||||
BASE_URL = 'http://localhost:5000'
|
||||
else:
|
||||
BASE_URL = 'http://169.254.169.254'
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_latest_meta_data():
|
||||
res = requests.get("{0}/latest/meta-data/".format(BASE_URL))
|
||||
res.content.should.equal(b"iam")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_iam():
|
||||
res = requests.get("{0}/latest/meta-data/iam".format(BASE_URL))
|
||||
json_response = res.json()
|
||||
default_role = json_response['security-credentials']['default-role']
|
||||
default_role.should.contain('AccessKeyId')
|
||||
default_role.should.contain('SecretAccessKey')
|
||||
default_role.should.contain('Token')
|
||||
default_role.should.contain('Expiration')
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_security_credentials():
|
||||
res = requests.get(
|
||||
"{0}/latest/meta-data/iam/security-credentials/".format(BASE_URL))
|
||||
res.content.should.equal(b"default-role")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_default_role():
|
||||
res = requests.get(
|
||||
"{0}/latest/meta-data/iam/security-credentials/default-role".format(BASE_URL))
|
||||
json_response = res.json()
|
||||
json_response.should.contain('AccessKeyId')
|
||||
json_response.should.contain('SecretAccessKey')
|
||||
json_response.should.contain('Token')
|
||||
json_response.should.contain('Expiration')
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
import requests
|
||||
|
||||
from moto import mock_ec2, settings
|
||||
|
||||
if settings.TEST_SERVER_MODE:
|
||||
BASE_URL = "http://localhost:5000"
|
||||
else:
|
||||
BASE_URL = "http://169.254.169.254"
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_latest_meta_data():
|
||||
res = requests.get("{0}/latest/meta-data/".format(BASE_URL))
|
||||
res.content.should.equal(b"iam")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_iam():
|
||||
res = requests.get("{0}/latest/meta-data/iam".format(BASE_URL))
|
||||
json_response = res.json()
|
||||
default_role = json_response["security-credentials"]["default-role"]
|
||||
default_role.should.contain("AccessKeyId")
|
||||
default_role.should.contain("SecretAccessKey")
|
||||
default_role.should.contain("Token")
|
||||
default_role.should.contain("Expiration")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_security_credentials():
|
||||
res = requests.get(
|
||||
"{0}/latest/meta-data/iam/security-credentials/".format(BASE_URL)
|
||||
)
|
||||
res.content.should.equal(b"default-role")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_meta_data_default_role():
|
||||
res = requests.get(
|
||||
"{0}/latest/meta-data/iam/security-credentials/default-role".format(BASE_URL)
|
||||
)
|
||||
json_response = res.json()
|
||||
json_response.should.contain("AccessKeyId")
|
||||
json_response.should.contain("SecretAccessKey")
|
||||
json_response.should.contain("Token")
|
||||
json_response.should.contain("Expiration")
|
||||
|
|
|
|||
|
|
@ -1,33 +1,37 @@
|
|||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
import requests
|
||||
|
||||
import boto3
|
||||
from moto import mock_sqs, settings
|
||||
|
||||
base_url = "http://localhost:5000" if settings.TEST_SERVER_MODE else "http://motoapi.amazonaws.com"
|
||||
|
||||
|
||||
@mock_sqs
|
||||
def test_reset_api():
|
||||
conn = boto3.client("sqs", region_name='us-west-1')
|
||||
conn.create_queue(QueueName="queue1")
|
||||
conn.list_queues()['QueueUrls'].should.have.length_of(1)
|
||||
|
||||
res = requests.post("{base_url}/moto-api/reset".format(base_url=base_url))
|
||||
res.content.should.equal(b'{"status": "ok"}')
|
||||
|
||||
conn.list_queues().shouldnt.contain('QueueUrls') # No more queues
|
||||
|
||||
|
||||
@mock_sqs
|
||||
def test_data_api():
|
||||
conn = boto3.client("sqs", region_name='us-west-1')
|
||||
conn.create_queue(QueueName="queue1")
|
||||
|
||||
res = requests.post("{base_url}/moto-api/data.json".format(base_url=base_url))
|
||||
queues = res.json()['sqs']['Queue']
|
||||
len(queues).should.equal(1)
|
||||
queue = queues[0]
|
||||
queue['name'].should.equal("queue1")
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
import requests
|
||||
|
||||
import boto3
|
||||
from moto import mock_sqs, settings
|
||||
|
||||
base_url = (
|
||||
"http://localhost:5000"
|
||||
if settings.TEST_SERVER_MODE
|
||||
else "http://motoapi.amazonaws.com"
|
||||
)
|
||||
|
||||
|
||||
@mock_sqs
|
||||
def test_reset_api():
|
||||
conn = boto3.client("sqs", region_name="us-west-1")
|
||||
conn.create_queue(QueueName="queue1")
|
||||
conn.list_queues()["QueueUrls"].should.have.length_of(1)
|
||||
|
||||
res = requests.post("{base_url}/moto-api/reset".format(base_url=base_url))
|
||||
res.content.should.equal(b'{"status": "ok"}')
|
||||
|
||||
conn.list_queues().shouldnt.contain("QueueUrls") # No more queues
|
||||
|
||||
|
||||
@mock_sqs
|
||||
def test_data_api():
|
||||
conn = boto3.client("sqs", region_name="us-west-1")
|
||||
conn.create_queue(QueueName="queue1")
|
||||
|
||||
res = requests.post("{base_url}/moto-api/data.json".format(base_url=base_url))
|
||||
queues = res.json()["sqs"]["Queue"]
|
||||
len(queues).should.equal(1)
|
||||
queue = queues[0]
|
||||
queue["name"].should.equal("queue1")
|
||||
|
|
|
|||
|
|
@ -1,29 +1,28 @@
|
|||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
from boto.sqs.connection import SQSConnection
|
||||
from boto.sqs.message import Message
|
||||
from boto.ec2 import EC2Connection
|
||||
|
||||
from moto import mock_sqs_deprecated, mock_ec2_deprecated
|
||||
|
||||
|
||||
class TestNestedDecorators(unittest.TestCase):
|
||||
|
||||
@mock_sqs_deprecated
|
||||
def setup_sqs_queue(self):
|
||||
conn = SQSConnection()
|
||||
q = conn.create_queue('some-queue')
|
||||
|
||||
m = Message()
|
||||
m.set_body('This is my first message.')
|
||||
q.write(m)
|
||||
|
||||
self.assertEqual(q.count(), 1)
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_nested(self):
|
||||
self.setup_sqs_queue()
|
||||
|
||||
conn = EC2Connection()
|
||||
conn.run_instances('ami-123456')
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
from boto.sqs.connection import SQSConnection
|
||||
from boto.sqs.message import Message
|
||||
from boto.ec2 import EC2Connection
|
||||
|
||||
from moto import mock_sqs_deprecated, mock_ec2_deprecated
|
||||
|
||||
|
||||
class TestNestedDecorators(unittest.TestCase):
|
||||
@mock_sqs_deprecated
|
||||
def setup_sqs_queue(self):
|
||||
conn = SQSConnection()
|
||||
q = conn.create_queue("some-queue")
|
||||
|
||||
m = Message()
|
||||
m.set_body("This is my first message.")
|
||||
q.write(m)
|
||||
|
||||
self.assertEqual(q.count(), 1)
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_nested(self):
|
||||
self.setup_sqs_queue()
|
||||
|
||||
conn = EC2Connection()
|
||||
conn.run_instances("ami-123456")
|
||||
|
|
|
|||
23
tests/test_core/test_request_mocking.py
Normal file
23
tests/test_core/test_request_mocking.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import requests
|
||||
import sure # noqa
|
||||
|
||||
import boto3
|
||||
from moto import mock_sqs, settings
|
||||
|
||||
|
||||
@mock_sqs
|
||||
def test_passthrough_requests():
|
||||
conn = boto3.client("sqs", region_name="us-west-1")
|
||||
conn.create_queue(QueueName="queue1")
|
||||
|
||||
res = requests.get("https://httpbin.org/ip")
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
if not settings.TEST_SERVER_MODE:
|
||||
|
||||
@mock_sqs
|
||||
def test_requests_to_amazon_subdomains_dont_work():
|
||||
res = requests.get("https://fakeservice.amazonaws.com/foo/bar")
|
||||
assert res.content == b"The method is not implemented"
|
||||
assert res.status_code == 400
|
||||
|
|
@ -9,81 +9,86 @@ from moto.core.responses import flatten_json_request_body
|
|||
|
||||
|
||||
def test_flatten_json_request_body():
|
||||
spec = AWSServiceSpec(
|
||||
'data/emr/2009-03-31/service-2.json').input_spec('RunJobFlow')
|
||||
spec = AWSServiceSpec("data/emr/2009-03-31/service-2.json").input_spec("RunJobFlow")
|
||||
|
||||
body = {
|
||||
'Name': 'cluster',
|
||||
'Instances': {
|
||||
'Ec2KeyName': 'ec2key',
|
||||
'InstanceGroups': [
|
||||
{'InstanceRole': 'MASTER',
|
||||
'InstanceType': 'm1.small'},
|
||||
{'InstanceRole': 'CORE',
|
||||
'InstanceType': 'm1.medium'},
|
||||
"Name": "cluster",
|
||||
"Instances": {
|
||||
"Ec2KeyName": "ec2key",
|
||||
"InstanceGroups": [
|
||||
{"InstanceRole": "MASTER", "InstanceType": "m1.small"},
|
||||
{"InstanceRole": "CORE", "InstanceType": "m1.medium"},
|
||||
],
|
||||
'Placement': {'AvailabilityZone': 'us-east-1'},
|
||||
"Placement": {"AvailabilityZone": "us-east-1"},
|
||||
},
|
||||
'Steps': [
|
||||
{'HadoopJarStep': {
|
||||
'Properties': [
|
||||
{'Key': 'k1', 'Value': 'v1'},
|
||||
{'Key': 'k2', 'Value': 'v2'}
|
||||
],
|
||||
'Args': ['arg1', 'arg2']}},
|
||||
"Steps": [
|
||||
{
|
||||
"HadoopJarStep": {
|
||||
"Properties": [
|
||||
{"Key": "k1", "Value": "v1"},
|
||||
{"Key": "k2", "Value": "v2"},
|
||||
],
|
||||
"Args": ["arg1", "arg2"],
|
||||
}
|
||||
}
|
||||
],
|
||||
"Configurations": [
|
||||
{
|
||||
"Classification": "class",
|
||||
"Properties": {"propkey1": "propkey1", "propkey2": "propkey2"},
|
||||
},
|
||||
{"Classification": "anotherclass", "Properties": {"propkey3": "propkey3"}},
|
||||
],
|
||||
'Configurations': [
|
||||
{'Classification': 'class',
|
||||
'Properties': {'propkey1': 'propkey1',
|
||||
'propkey2': 'propkey2'}},
|
||||
{'Classification': 'anotherclass',
|
||||
'Properties': {'propkey3': 'propkey3'}},
|
||||
]
|
||||
}
|
||||
|
||||
flat = flatten_json_request_body('', body, spec)
|
||||
flat['Name'].should.equal(body['Name'])
|
||||
flat['Instances.Ec2KeyName'].should.equal(body['Instances']['Ec2KeyName'])
|
||||
flat = flatten_json_request_body("", body, spec)
|
||||
flat["Name"].should.equal(body["Name"])
|
||||
flat["Instances.Ec2KeyName"].should.equal(body["Instances"]["Ec2KeyName"])
|
||||
for idx in range(2):
|
||||
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceRole'].should.equal(
|
||||
body['Instances']['InstanceGroups'][idx]['InstanceRole'])
|
||||
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceType'].should.equal(
|
||||
body['Instances']['InstanceGroups'][idx]['InstanceType'])
|
||||
flat['Instances.Placement.AvailabilityZone'].should.equal(
|
||||
body['Instances']['Placement']['AvailabilityZone'])
|
||||
flat[
|
||||
"Instances.InstanceGroups.member." + str(idx + 1) + ".InstanceRole"
|
||||
].should.equal(body["Instances"]["InstanceGroups"][idx]["InstanceRole"])
|
||||
flat[
|
||||
"Instances.InstanceGroups.member." + str(idx + 1) + ".InstanceType"
|
||||
].should.equal(body["Instances"]["InstanceGroups"][idx]["InstanceType"])
|
||||
flat["Instances.Placement.AvailabilityZone"].should.equal(
|
||||
body["Instances"]["Placement"]["AvailabilityZone"]
|
||||
)
|
||||
|
||||
for idx in range(1):
|
||||
prefix = 'Steps.member.' + str(idx + 1) + '.HadoopJarStep'
|
||||
step = body['Steps'][idx]['HadoopJarStep']
|
||||
prefix = "Steps.member." + str(idx + 1) + ".HadoopJarStep"
|
||||
step = body["Steps"][idx]["HadoopJarStep"]
|
||||
i = 0
|
||||
while prefix + '.Properties.member.' + str(i + 1) + '.Key' in flat:
|
||||
flat[prefix + '.Properties.member.' +
|
||||
str(i + 1) + '.Key'].should.equal(step['Properties'][i]['Key'])
|
||||
flat[prefix + '.Properties.member.' +
|
||||
str(i + 1) + '.Value'].should.equal(step['Properties'][i]['Value'])
|
||||
while prefix + ".Properties.member." + str(i + 1) + ".Key" in flat:
|
||||
flat[prefix + ".Properties.member." + str(i + 1) + ".Key"].should.equal(
|
||||
step["Properties"][i]["Key"]
|
||||
)
|
||||
flat[prefix + ".Properties.member." + str(i + 1) + ".Value"].should.equal(
|
||||
step["Properties"][i]["Value"]
|
||||
)
|
||||
i += 1
|
||||
i = 0
|
||||
while prefix + '.Args.member.' + str(i + 1) in flat:
|
||||
flat[prefix + '.Args.member.' +
|
||||
str(i + 1)].should.equal(step['Args'][i])
|
||||
while prefix + ".Args.member." + str(i + 1) in flat:
|
||||
flat[prefix + ".Args.member." + str(i + 1)].should.equal(step["Args"][i])
|
||||
i += 1
|
||||
|
||||
for idx in range(2):
|
||||
flat['Configurations.member.' + str(idx + 1) + '.Classification'].should.equal(
|
||||
body['Configurations'][idx]['Classification'])
|
||||
flat["Configurations.member." + str(idx + 1) + ".Classification"].should.equal(
|
||||
body["Configurations"][idx]["Classification"]
|
||||
)
|
||||
|
||||
props = {}
|
||||
i = 1
|
||||
keyfmt = 'Configurations.member.{0}.Properties.entry.{1}'
|
||||
keyfmt = "Configurations.member.{0}.Properties.entry.{1}"
|
||||
key = keyfmt.format(idx + 1, i)
|
||||
while key + '.key' in flat:
|
||||
props[flat[key + '.key']] = flat[key + '.value']
|
||||
while key + ".key" in flat:
|
||||
props[flat[key + ".key"]] = flat[key + ".value"]
|
||||
i += 1
|
||||
key = keyfmt.format(idx + 1, i)
|
||||
props.should.equal(body['Configurations'][idx]['Properties'])
|
||||
props.should.equal(body["Configurations"][idx]["Properties"])
|
||||
|
||||
|
||||
def test_parse_qs_unicode_decode_error():
|
||||
body = b'{"key": "%D0"}, "C": "#0 = :0"}'
|
||||
request = AWSPreparedRequest('GET', 'http://request', {'foo': 'bar'}, body, False)
|
||||
request = AWSPreparedRequest("GET", "http://request", {"foo": "bar"}, body, False)
|
||||
BaseResponse().setup_class(request, request.url, request.headers)
|
||||
|
|
|
|||
|
|
@ -1,47 +1,49 @@
|
|||
from __future__ import unicode_literals
|
||||
from mock import patch
|
||||
import sure # noqa
|
||||
|
||||
from moto.server import main, create_backend_app, DomainDispatcherApplication
|
||||
|
||||
|
||||
def test_wrong_arguments():
|
||||
try:
|
||||
main(["name", "test1", "test2", "test3"])
|
||||
assert False, ("main() when called with the incorrect number of args"
|
||||
" should raise a system exit")
|
||||
except SystemExit:
|
||||
pass
|
||||
|
||||
|
||||
@patch('moto.server.run_simple')
|
||||
def test_right_arguments(run_simple):
|
||||
main(["s3"])
|
||||
func_call = run_simple.call_args[0]
|
||||
func_call[0].should.equal("127.0.0.1")
|
||||
func_call[1].should.equal(5000)
|
||||
|
||||
|
||||
@patch('moto.server.run_simple')
|
||||
def test_port_argument(run_simple):
|
||||
main(["s3", "--port", "8080"])
|
||||
func_call = run_simple.call_args[0]
|
||||
func_call[0].should.equal("127.0.0.1")
|
||||
func_call[1].should.equal(8080)
|
||||
|
||||
|
||||
def test_domain_dispatched():
|
||||
dispatcher = DomainDispatcherApplication(create_backend_app)
|
||||
backend_app = dispatcher.get_application(
|
||||
{"HTTP_HOST": "email.us-east1.amazonaws.com"})
|
||||
keys = list(backend_app.view_functions.keys())
|
||||
keys[0].should.equal('EmailResponse.dispatch')
|
||||
|
||||
|
||||
def test_domain_dispatched_with_service():
|
||||
# If we pass a particular service, always return that.
|
||||
dispatcher = DomainDispatcherApplication(create_backend_app, service="s3")
|
||||
backend_app = dispatcher.get_application(
|
||||
{"HTTP_HOST": "s3.us-east1.amazonaws.com"})
|
||||
keys = set(backend_app.view_functions.keys())
|
||||
keys.should.contain('ResponseObject.key_response')
|
||||
from __future__ import unicode_literals
|
||||
from mock import patch
|
||||
import sure # noqa
|
||||
|
||||
from moto.server import main, create_backend_app, DomainDispatcherApplication
|
||||
|
||||
|
||||
def test_wrong_arguments():
|
||||
try:
|
||||
main(["name", "test1", "test2", "test3"])
|
||||
assert False, (
|
||||
"main() when called with the incorrect number of args"
|
||||
" should raise a system exit"
|
||||
)
|
||||
except SystemExit:
|
||||
pass
|
||||
|
||||
|
||||
@patch("moto.server.run_simple")
|
||||
def test_right_arguments(run_simple):
|
||||
main(["s3"])
|
||||
func_call = run_simple.call_args[0]
|
||||
func_call[0].should.equal("127.0.0.1")
|
||||
func_call[1].should.equal(5000)
|
||||
|
||||
|
||||
@patch("moto.server.run_simple")
|
||||
def test_port_argument(run_simple):
|
||||
main(["s3", "--port", "8080"])
|
||||
func_call = run_simple.call_args[0]
|
||||
func_call[0].should.equal("127.0.0.1")
|
||||
func_call[1].should.equal(8080)
|
||||
|
||||
|
||||
def test_domain_dispatched():
|
||||
dispatcher = DomainDispatcherApplication(create_backend_app)
|
||||
backend_app = dispatcher.get_application(
|
||||
{"HTTP_HOST": "email.us-east1.amazonaws.com"}
|
||||
)
|
||||
keys = list(backend_app.view_functions.keys())
|
||||
keys[0].should.equal("EmailResponse.dispatch")
|
||||
|
||||
|
||||
def test_domain_dispatched_with_service():
|
||||
# If we pass a particular service, always return that.
|
||||
dispatcher = DomainDispatcherApplication(create_backend_app, service="s3")
|
||||
backend_app = dispatcher.get_application({"HTTP_HOST": "s3.us-east1.amazonaws.com"})
|
||||
keys = set(backend_app.view_functions.keys())
|
||||
keys.should.contain("ResponseObject.key_response")
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@ from six import PY3
|
|||
|
||||
|
||||
class TestSocketPair(unittest.TestCase):
|
||||
|
||||
@mock_dynamodb2_deprecated
|
||||
def test_asyncio_deprecated(self):
|
||||
if PY3:
|
||||
self.assertIn(
|
||||
'moto.packages.httpretty.core.fakesock.socket',
|
||||
"moto.packages.httpretty.core.fakesock.socket",
|
||||
str(socket.socket),
|
||||
'Our mock should be present'
|
||||
"Our mock should be present",
|
||||
)
|
||||
import asyncio
|
||||
|
||||
self.assertIsNotNone(asyncio.get_event_loop())
|
||||
|
||||
@mock_dynamodb2_deprecated
|
||||
|
|
@ -24,9 +24,9 @@ class TestSocketPair(unittest.TestCase):
|
|||
# In Python2, the fakesocket is not set, for some reason.
|
||||
if PY3:
|
||||
self.assertIn(
|
||||
'moto.packages.httpretty.core.fakesock.socket',
|
||||
"moto.packages.httpretty.core.fakesock.socket",
|
||||
str(socket.socket),
|
||||
'Our mock should be present'
|
||||
"Our mock should be present",
|
||||
)
|
||||
a, b = socket.socketpair()
|
||||
self.assertIsNotNone(a)
|
||||
|
|
@ -36,7 +36,6 @@ class TestSocketPair(unittest.TestCase):
|
|||
if b:
|
||||
b.close()
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_socket_pair(self):
|
||||
a, b = socket.socketpair()
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
from moto.core.utils import convert_regex_to_flask_path
|
||||
|
||||
|
||||
def test_flask_path_converting_simple():
|
||||
convert_regex_to_flask_path("/").should.equal("/")
|
||||
convert_regex_to_flask_path("/$").should.equal("/")
|
||||
|
||||
convert_regex_to_flask_path("/foo").should.equal("/foo")
|
||||
|
||||
convert_regex_to_flask_path("/foo/bar/").should.equal("/foo/bar/")
|
||||
|
||||
|
||||
def test_flask_path_converting_regex():
|
||||
convert_regex_to_flask_path(
|
||||
"/(?P<key_name>[a-zA-Z0-9\-_]+)").should.equal('/<regex("[a-zA-Z0-9\-_]+"):key_name>')
|
||||
|
||||
convert_regex_to_flask_path("(?P<account_id>\d+)/(?P<queue_name>.*)$").should.equal(
|
||||
'<regex("\d+"):account_id>/<regex(".*"):queue_name>'
|
||||
)
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
from moto.core.utils import convert_regex_to_flask_path
|
||||
|
||||
|
||||
def test_flask_path_converting_simple():
|
||||
convert_regex_to_flask_path("/").should.equal("/")
|
||||
convert_regex_to_flask_path("/$").should.equal("/")
|
||||
|
||||
convert_regex_to_flask_path("/foo").should.equal("/foo")
|
||||
|
||||
convert_regex_to_flask_path("/foo/bar/").should.equal("/foo/bar/")
|
||||
|
||||
|
||||
def test_flask_path_converting_regex():
|
||||
convert_regex_to_flask_path("/(?P<key_name>[a-zA-Z0-9\-_]+)").should.equal(
|
||||
'/<regex("[a-zA-Z0-9\-_]+"):key_name>'
|
||||
)
|
||||
|
||||
convert_regex_to_flask_path("(?P<account_id>\d+)/(?P<queue_name>.*)$").should.equal(
|
||||
'<regex("\d+"):account_id>/<regex(".*"):queue_name>'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,30 +1,62 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import sure # noqa
|
||||
from freezegun import freeze_time
|
||||
|
||||
from moto.core.utils import camelcase_to_underscores, underscores_to_camelcase, unix_time
|
||||
|
||||
|
||||
def test_camelcase_to_underscores():
|
||||
cases = {
|
||||
"theNewAttribute": "the_new_attribute",
|
||||
"attri bute With Space": "attribute_with_space",
|
||||
"FirstLetterCapital": "first_letter_capital",
|
||||
"ListMFADevices": "list_mfa_devices",
|
||||
}
|
||||
for arg, expected in cases.items():
|
||||
camelcase_to_underscores(arg).should.equal(expected)
|
||||
|
||||
|
||||
def test_underscores_to_camelcase():
|
||||
cases = {
|
||||
"the_new_attribute": "theNewAttribute",
|
||||
}
|
||||
for arg, expected in cases.items():
|
||||
underscores_to_camelcase(arg).should.equal(expected)
|
||||
|
||||
|
||||
@freeze_time("2015-01-01 12:00:00")
|
||||
def test_unix_time():
|
||||
unix_time().should.equal(1420113600.0)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import copy
|
||||
import sys
|
||||
|
||||
import sure # noqa
|
||||
from freezegun import freeze_time
|
||||
|
||||
from moto.core.utils import (
|
||||
camelcase_to_underscores,
|
||||
underscores_to_camelcase,
|
||||
unix_time,
|
||||
py2_strip_unicode_keys,
|
||||
)
|
||||
|
||||
|
||||
def test_camelcase_to_underscores():
|
||||
cases = {
|
||||
"theNewAttribute": "the_new_attribute",
|
||||
"attri bute With Space": "attribute_with_space",
|
||||
"FirstLetterCapital": "first_letter_capital",
|
||||
"ListMFADevices": "list_mfa_devices",
|
||||
}
|
||||
for arg, expected in cases.items():
|
||||
camelcase_to_underscores(arg).should.equal(expected)
|
||||
|
||||
|
||||
def test_underscores_to_camelcase():
|
||||
cases = {"the_new_attribute": "theNewAttribute"}
|
||||
for arg, expected in cases.items():
|
||||
underscores_to_camelcase(arg).should.equal(expected)
|
||||
|
||||
|
||||
@freeze_time("2015-01-01 12:00:00")
|
||||
def test_unix_time():
|
||||
unix_time().should.equal(1420113600.0)
|
||||
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
# Tests for unicode removals (Python 2 only)
|
||||
def _verify_no_unicode(blob):
|
||||
"""Verify that no unicode values exist"""
|
||||
if type(blob) == dict:
|
||||
for key, value in blob.items():
|
||||
assert type(key) != unicode
|
||||
_verify_no_unicode(value)
|
||||
|
||||
elif type(blob) in [list, set]:
|
||||
for item in blob:
|
||||
_verify_no_unicode(item)
|
||||
|
||||
assert blob != unicode
|
||||
|
||||
def test_py2_strip_unicode_keys():
|
||||
bad_dict = {
|
||||
"some": "value",
|
||||
"a": {"nested": ["List", "of", {"unicode": "values"}]},
|
||||
"and a": {"nested", "set", "of", 5, "values"},
|
||||
}
|
||||
|
||||
result = py2_strip_unicode_keys(copy.deepcopy(bad_dict))
|
||||
_verify_no_unicode(result)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ from moto.datapipeline.utils import remove_capitalization_of_dict_keys
|
|||
|
||||
def get_value_from_fields(key, fields):
|
||||
for field in fields:
|
||||
if field['key'] == key:
|
||||
return field['stringValue']
|
||||
if field["key"] == key:
|
||||
return field["stringValue"]
|
||||
|
||||
|
||||
@mock_datapipeline_deprecated
|
||||
|
|
@ -20,62 +20,46 @@ def test_create_pipeline():
|
|||
res = conn.create_pipeline("mypipeline", "some-unique-id")
|
||||
|
||||
pipeline_id = res["pipelineId"]
|
||||
pipeline_descriptions = conn.describe_pipelines(
|
||||
[pipeline_id])["pipelineDescriptionList"]
|
||||
pipeline_descriptions = conn.describe_pipelines([pipeline_id])[
|
||||
"pipelineDescriptionList"
|
||||
]
|
||||
pipeline_descriptions.should.have.length_of(1)
|
||||
|
||||
pipeline_description = pipeline_descriptions[0]
|
||||
pipeline_description['name'].should.equal("mypipeline")
|
||||
pipeline_description["name"].should.equal("mypipeline")
|
||||
pipeline_description["pipelineId"].should.equal(pipeline_id)
|
||||
fields = pipeline_description['fields']
|
||||
fields = pipeline_description["fields"]
|
||||
|
||||
get_value_from_fields('@pipelineState', fields).should.equal("PENDING")
|
||||
get_value_from_fields('uniqueId', fields).should.equal("some-unique-id")
|
||||
get_value_from_fields("@pipelineState", fields).should.equal("PENDING")
|
||||
get_value_from_fields("uniqueId", fields).should.equal("some-unique-id")
|
||||
|
||||
|
||||
PIPELINE_OBJECTS = [
|
||||
{
|
||||
"id": "Default",
|
||||
"name": "Default",
|
||||
"fields": [{
|
||||
"key": "workerGroup",
|
||||
"stringValue": "workerGroup"
|
||||
}]
|
||||
"fields": [{"key": "workerGroup", "stringValue": "workerGroup"}],
|
||||
},
|
||||
{
|
||||
"id": "Schedule",
|
||||
"name": "Schedule",
|
||||
"fields": [{
|
||||
"key": "startDateTime",
|
||||
"stringValue": "2012-12-12T00:00:00"
|
||||
}, {
|
||||
"key": "type",
|
||||
"stringValue": "Schedule"
|
||||
}, {
|
||||
"key": "period",
|
||||
"stringValue": "1 hour"
|
||||
}, {
|
||||
"key": "endDateTime",
|
||||
"stringValue": "2012-12-21T18:00:00"
|
||||
}]
|
||||
"fields": [
|
||||
{"key": "startDateTime", "stringValue": "2012-12-12T00:00:00"},
|
||||
{"key": "type", "stringValue": "Schedule"},
|
||||
{"key": "period", "stringValue": "1 hour"},
|
||||
{"key": "endDateTime", "stringValue": "2012-12-21T18:00:00"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "SayHello",
|
||||
"name": "SayHello",
|
||||
"fields": [{
|
||||
"key": "type",
|
||||
"stringValue": "ShellCommandActivity"
|
||||
}, {
|
||||
"key": "command",
|
||||
"stringValue": "echo hello"
|
||||
}, {
|
||||
"key": "parent",
|
||||
"refValue": "Default"
|
||||
}, {
|
||||
"key": "schedule",
|
||||
"refValue": "Schedule"
|
||||
}]
|
||||
}
|
||||
"fields": [
|
||||
{"key": "type", "stringValue": "ShellCommandActivity"},
|
||||
{"key": "command", "stringValue": "echo hello"},
|
||||
{"key": "parent", "refValue": "Default"},
|
||||
{"key": "schedule", "refValue": "Schedule"},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -88,14 +72,13 @@ def test_creating_pipeline_definition():
|
|||
conn.put_pipeline_definition(PIPELINE_OBJECTS, pipeline_id)
|
||||
|
||||
pipeline_definition = conn.get_pipeline_definition(pipeline_id)
|
||||
pipeline_definition['pipelineObjects'].should.have.length_of(3)
|
||||
default_object = pipeline_definition['pipelineObjects'][0]
|
||||
default_object['name'].should.equal("Default")
|
||||
default_object['id'].should.equal("Default")
|
||||
default_object['fields'].should.equal([{
|
||||
"key": "workerGroup",
|
||||
"stringValue": "workerGroup"
|
||||
}])
|
||||
pipeline_definition["pipelineObjects"].should.have.length_of(3)
|
||||
default_object = pipeline_definition["pipelineObjects"][0]
|
||||
default_object["name"].should.equal("Default")
|
||||
default_object["id"].should.equal("Default")
|
||||
default_object["fields"].should.equal(
|
||||
[{"key": "workerGroup", "stringValue": "workerGroup"}]
|
||||
)
|
||||
|
||||
|
||||
@mock_datapipeline_deprecated
|
||||
|
|
@ -107,15 +90,15 @@ def test_describing_pipeline_objects():
|
|||
conn.put_pipeline_definition(PIPELINE_OBJECTS, pipeline_id)
|
||||
|
||||
objects = conn.describe_objects(["Schedule", "Default"], pipeline_id)[
|
||||
'pipelineObjects']
|
||||
"pipelineObjects"
|
||||
]
|
||||
|
||||
objects.should.have.length_of(2)
|
||||
default_object = [x for x in objects if x['id'] == 'Default'][0]
|
||||
default_object['name'].should.equal("Default")
|
||||
default_object['fields'].should.equal([{
|
||||
"key": "workerGroup",
|
||||
"stringValue": "workerGroup"
|
||||
}])
|
||||
default_object = [x for x in objects if x["id"] == "Default"][0]
|
||||
default_object["name"].should.equal("Default")
|
||||
default_object["fields"].should.equal(
|
||||
[{"key": "workerGroup", "stringValue": "workerGroup"}]
|
||||
)
|
||||
|
||||
|
||||
@mock_datapipeline_deprecated
|
||||
|
|
@ -127,13 +110,14 @@ def test_activate_pipeline():
|
|||
pipeline_id = res["pipelineId"]
|
||||
conn.activate_pipeline(pipeline_id)
|
||||
|
||||
pipeline_descriptions = conn.describe_pipelines(
|
||||
[pipeline_id])["pipelineDescriptionList"]
|
||||
pipeline_descriptions = conn.describe_pipelines([pipeline_id])[
|
||||
"pipelineDescriptionList"
|
||||
]
|
||||
pipeline_descriptions.should.have.length_of(1)
|
||||
pipeline_description = pipeline_descriptions[0]
|
||||
fields = pipeline_description['fields']
|
||||
fields = pipeline_description["fields"]
|
||||
|
||||
get_value_from_fields('@pipelineState', fields).should.equal("SCHEDULED")
|
||||
get_value_from_fields("@pipelineState", fields).should.equal("SCHEDULED")
|
||||
|
||||
|
||||
@mock_datapipeline_deprecated
|
||||
|
|
@ -160,14 +144,12 @@ def test_listing_pipelines():
|
|||
response["hasMoreResults"].should.be(False)
|
||||
response["marker"].should.be.none
|
||||
response["pipelineIdList"].should.have.length_of(2)
|
||||
response["pipelineIdList"].should.contain({
|
||||
"id": res1["pipelineId"],
|
||||
"name": "mypipeline1",
|
||||
})
|
||||
response["pipelineIdList"].should.contain({
|
||||
"id": res2["pipelineId"],
|
||||
"name": "mypipeline2"
|
||||
})
|
||||
response["pipelineIdList"].should.contain(
|
||||
{"id": res1["pipelineId"], "name": "mypipeline1"}
|
||||
)
|
||||
response["pipelineIdList"].should.contain(
|
||||
{"id": res2["pipelineId"], "name": "mypipeline2"}
|
||||
)
|
||||
|
||||
|
||||
@mock_datapipeline_deprecated
|
||||
|
|
@ -179,7 +161,7 @@ def test_listing_paginated_pipelines():
|
|||
response = conn.list_pipelines()
|
||||
|
||||
response["hasMoreResults"].should.be(True)
|
||||
response["marker"].should.equal(response["pipelineIdList"][-1]['id'])
|
||||
response["marker"].should.equal(response["pipelineIdList"][-1]["id"])
|
||||
response["pipelineIdList"].should.have.length_of(50)
|
||||
|
||||
|
||||
|
|
@ -188,17 +170,13 @@ def test_remove_capitalization_of_dict_keys():
|
|||
result = remove_capitalization_of_dict_keys(
|
||||
{
|
||||
"Id": "IdValue",
|
||||
"Fields": [{
|
||||
"Key": "KeyValue",
|
||||
"StringValue": "StringValueValue"
|
||||
}]
|
||||
"Fields": [{"Key": "KeyValue", "StringValue": "StringValueValue"}],
|
||||
}
|
||||
)
|
||||
|
||||
result.should.equal({
|
||||
"id": "IdValue",
|
||||
"fields": [{
|
||||
"key": "KeyValue",
|
||||
"stringValue": "StringValueValue"
|
||||
}],
|
||||
})
|
||||
result.should.equal(
|
||||
{
|
||||
"id": "IdValue",
|
||||
"fields": [{"key": "KeyValue", "stringValue": "StringValueValue"}],
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,28 +1,26 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
from moto import mock_datapipeline
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
@mock_datapipeline
|
||||
def test_list_streams():
|
||||
backend = server.create_backend_app("datapipeline")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post('/',
|
||||
data={"pipelineIds": ["ASdf"]},
|
||||
headers={
|
||||
"X-Amz-Target": "DataPipeline.DescribePipelines"},
|
||||
)
|
||||
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
json_data.should.equal({
|
||||
'pipelineDescriptionList': []
|
||||
})
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
from moto import mock_datapipeline
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
@mock_datapipeline
|
||||
def test_list_streams():
|
||||
backend = server.create_backend_app("datapipeline")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.post(
|
||||
"/",
|
||||
data={"pipelineIds": ["ASdf"]},
|
||||
headers={"X-Amz-Target": "DataPipeline.DescribePipelines"},
|
||||
)
|
||||
|
||||
json_data = json.loads(res.data.decode("utf-8"))
|
||||
json_data.should.equal({"pipelineDescriptionList": []})
|
||||
|
|
|
|||
0
tests/test_datasync/__init__.py
Normal file
0
tests/test_datasync/__init__.py
Normal file
425
tests/test_datasync/test_datasync.py
Normal file
425
tests/test_datasync/test_datasync.py
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
import logging
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_datasync
|
||||
from nose.tools import assert_raises
|
||||
|
||||
|
||||
def create_locations(client, create_smb=False, create_s3=False):
|
||||
"""
|
||||
Convenience function for creating locations.
|
||||
Locations must exist before tasks can be created.
|
||||
"""
|
||||
smb_arn = None
|
||||
s3_arn = None
|
||||
if create_smb:
|
||||
response = client.create_location_smb(
|
||||
ServerHostname="host",
|
||||
Subdirectory="somewhere",
|
||||
User="",
|
||||
Password="",
|
||||
AgentArns=["stuff"],
|
||||
)
|
||||
smb_arn = response["LocationArn"]
|
||||
if create_s3:
|
||||
response = client.create_location_s3(
|
||||
S3BucketArn="arn:aws:s3:::my_bucket",
|
||||
Subdirectory="dir",
|
||||
S3Config={"BucketAccessRoleArn": "role"},
|
||||
)
|
||||
s3_arn = response["LocationArn"]
|
||||
return {"smb_arn": smb_arn, "s3_arn": s3_arn}
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_create_location_smb():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
response = client.create_location_smb(
|
||||
ServerHostname="host",
|
||||
Subdirectory="somewhere",
|
||||
User="",
|
||||
Password="",
|
||||
AgentArns=["stuff"],
|
||||
)
|
||||
assert "LocationArn" in response
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_location_smb():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
agent_arns = ["stuff"]
|
||||
user = "user"
|
||||
response = client.create_location_smb(
|
||||
ServerHostname="host",
|
||||
Subdirectory="somewhere",
|
||||
User=user,
|
||||
Password="",
|
||||
AgentArns=agent_arns,
|
||||
)
|
||||
response = client.describe_location_smb(LocationArn=response["LocationArn"])
|
||||
assert "LocationArn" in response
|
||||
assert "LocationUri" in response
|
||||
assert response["User"] == user
|
||||
assert response["AgentArns"] == agent_arns
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_create_location_s3():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
response = client.create_location_s3(
|
||||
S3BucketArn="arn:aws:s3:::my_bucket",
|
||||
Subdirectory="dir",
|
||||
S3Config={"BucketAccessRoleArn": "role"},
|
||||
)
|
||||
assert "LocationArn" in response
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_location_s3():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
s3_config = {"BucketAccessRoleArn": "role"}
|
||||
response = client.create_location_s3(
|
||||
S3BucketArn="arn:aws:s3:::my_bucket", Subdirectory="dir", S3Config=s3_config
|
||||
)
|
||||
response = client.describe_location_s3(LocationArn=response["LocationArn"])
|
||||
assert "LocationArn" in response
|
||||
assert "LocationUri" in response
|
||||
assert response["S3Config"] == s3_config
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_location_wrong():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
agent_arns = ["stuff"]
|
||||
user = "user"
|
||||
response = client.create_location_smb(
|
||||
ServerHostname="host",
|
||||
Subdirectory="somewhere",
|
||||
User=user,
|
||||
Password="",
|
||||
AgentArns=agent_arns,
|
||||
)
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.describe_location_s3(LocationArn=response["LocationArn"])
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_list_locations():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 0
|
||||
|
||||
create_locations(client, create_smb=True)
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 1
|
||||
assert response["Locations"][0]["LocationUri"] == "smb://host/somewhere"
|
||||
|
||||
create_locations(client, create_s3=True)
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 2
|
||||
assert response["Locations"][1]["LocationUri"] == "s3://my_bucket/dir"
|
||||
|
||||
create_locations(client, create_s3=True)
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 3
|
||||
assert response["Locations"][2]["LocationUri"] == "s3://my_bucket/dir"
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_delete_location():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_smb=True)
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 1
|
||||
location_arn = locations["smb_arn"]
|
||||
|
||||
response = client.delete_location(LocationArn=location_arn)
|
||||
response = client.list_locations()
|
||||
assert len(response["Locations"]) == 0
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.delete_location(LocationArn=location_arn)
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_create_task():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_smb=True, create_s3=True)
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
)
|
||||
assert "TaskArn" in response
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_create_task_fail():
|
||||
""" Test that Locations must exist before a Task can be created """
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_smb=True, create_s3=True)
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.create_task(
|
||||
SourceLocationArn="1", DestinationLocationArn=locations["s3_arn"]
|
||||
)
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"], DestinationLocationArn="2"
|
||||
)
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_list_tasks():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
)
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["s3_arn"],
|
||||
DestinationLocationArn=locations["smb_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
response = client.list_tasks()
|
||||
tasks = response["Tasks"]
|
||||
assert len(tasks) == 2
|
||||
|
||||
task = tasks[0]
|
||||
assert task["Status"] == "AVAILABLE"
|
||||
assert "Name" not in task
|
||||
|
||||
task = tasks[1]
|
||||
assert task["Status"] == "AVAILABLE"
|
||||
assert task["Name"] == "task_name"
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_task():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
|
||||
assert "TaskArn" in response
|
||||
assert "Status" in response
|
||||
assert "SourceLocationArn" in response
|
||||
assert "DestinationLocationArn" in response
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_task_not_exist():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.describe_task(TaskArn="abc")
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_update_task():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
initial_name = "Initial_Name"
|
||||
updated_name = "Updated_Name"
|
||||
initial_options = {
|
||||
"VerifyMode": "NONE",
|
||||
"Atime": "BEST_EFFORT",
|
||||
"Mtime": "PRESERVE",
|
||||
}
|
||||
updated_options = {
|
||||
"VerifyMode": "POINT_IN_TIME_CONSISTENT",
|
||||
"Atime": "BEST_EFFORT",
|
||||
"Mtime": "PRESERVE",
|
||||
}
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name=initial_name,
|
||||
Options=initial_options,
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["TaskArn"] == task_arn
|
||||
assert response["Name"] == initial_name
|
||||
assert response["Options"] == initial_options
|
||||
|
||||
response = client.update_task(
|
||||
TaskArn=task_arn, Name=updated_name, Options=updated_options
|
||||
)
|
||||
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["TaskArn"] == task_arn
|
||||
assert response["Name"] == updated_name
|
||||
assert response["Options"] == updated_options
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.update_task(TaskArn="doesnt_exist")
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_delete_task():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
|
||||
response = client.list_tasks()
|
||||
assert len(response["Tasks"]) == 1
|
||||
task_arn = response["Tasks"][0]["TaskArn"]
|
||||
assert task_arn is not None
|
||||
|
||||
response = client.delete_task(TaskArn=task_arn)
|
||||
response = client.list_tasks()
|
||||
assert len(response["Tasks"]) == 0
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.delete_task(TaskArn=task_arn)
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_start_task_execution():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert "CurrentTaskExecutionArn" not in response
|
||||
|
||||
response = client.start_task_execution(TaskArn=task_arn)
|
||||
assert "TaskExecutionArn" in response
|
||||
task_execution_arn = response["TaskExecutionArn"]
|
||||
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["CurrentTaskExecutionArn"] == task_execution_arn
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_start_task_execution_twice():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
|
||||
response = client.start_task_execution(TaskArn=task_arn)
|
||||
assert "TaskExecutionArn" in response
|
||||
task_execution_arn = response["TaskExecutionArn"]
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
response = client.start_task_execution(TaskArn=task_arn)
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_task_execution():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "AVAILABLE"
|
||||
|
||||
response = client.start_task_execution(TaskArn=task_arn)
|
||||
task_execution_arn = response["TaskExecutionArn"]
|
||||
|
||||
# Each time task_execution is described the Status will increment
|
||||
# This is a simple way to simulate a task being executed
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "INITIALIZING"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "RUNNING"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "PREPARING"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "RUNNING"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "TRANSFERRING"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "RUNNING"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "VERIFYING"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "RUNNING"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "SUCCESS"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "AVAILABLE"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["TaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "SUCCESS"
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["Status"] == "AVAILABLE"
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_describe_task_execution_not_exist():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as e:
|
||||
client.describe_task_execution(TaskExecutionArn="abc")
|
||||
|
||||
|
||||
@mock_datasync
|
||||
def test_cancel_task_execution():
|
||||
client = boto3.client("datasync", region_name="us-east-1")
|
||||
locations = create_locations(client, create_s3=True, create_smb=True)
|
||||
|
||||
response = client.create_task(
|
||||
SourceLocationArn=locations["smb_arn"],
|
||||
DestinationLocationArn=locations["s3_arn"],
|
||||
Name="task_name",
|
||||
)
|
||||
task_arn = response["TaskArn"]
|
||||
|
||||
response = client.start_task_execution(TaskArn=task_arn)
|
||||
task_execution_arn = response["TaskExecutionArn"]
|
||||
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert response["CurrentTaskExecutionArn"] == task_execution_arn
|
||||
assert response["Status"] == "RUNNING"
|
||||
|
||||
response = client.cancel_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
|
||||
response = client.describe_task(TaskArn=task_arn)
|
||||
assert "CurrentTaskExecutionArn" not in response
|
||||
assert response["Status"] == "AVAILABLE"
|
||||
|
||||
response = client.describe_task_execution(TaskExecutionArn=task_execution_arn)
|
||||
assert response["Status"] == "ERROR"
|
||||
|
|
@ -1,54 +1,51 @@
|
|||
from __future__ import unicode_literals
|
||||
import six
|
||||
import boto
|
||||
import boto.dynamodb
|
||||
import sure # noqa
|
||||
import requests
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_dynamodb, mock_dynamodb_deprecated
|
||||
from moto.dynamodb import dynamodb_backend
|
||||
|
||||
from boto.exception import DynamoDBResponseError
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_list_tables():
|
||||
name = 'TestTable'
|
||||
dynamodb_backend.create_table(
|
||||
name, hash_key_attr="name", hash_key_type="S")
|
||||
conn = boto.connect_dynamodb('the_key', 'the_secret')
|
||||
assert conn.list_tables() == ['TestTable']
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_list_tables_layer_1():
|
||||
dynamodb_backend.create_table(
|
||||
"test_1", hash_key_attr="name", hash_key_type="S")
|
||||
dynamodb_backend.create_table(
|
||||
"test_2", hash_key_attr="name", hash_key_type="S")
|
||||
conn = boto.connect_dynamodb('the_key', 'the_secret')
|
||||
res = conn.layer1.list_tables(limit=1)
|
||||
expected = {"TableNames": ["test_1"], "LastEvaluatedTableName": "test_1"}
|
||||
res.should.equal(expected)
|
||||
|
||||
res = conn.layer1.list_tables(limit=1, start_table="test_1")
|
||||
expected = {"TableNames": ["test_2"]}
|
||||
res.should.equal(expected)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_describe_missing_table():
|
||||
conn = boto.connect_dynamodb('the_key', 'the_secret')
|
||||
with assert_raises(DynamoDBResponseError):
|
||||
conn.describe_table('messages')
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_dynamodb_with_connect_to_region():
|
||||
# this will work if connected with boto.connect_dynamodb()
|
||||
dynamodb = boto.dynamodb.connect_to_region('us-west-2')
|
||||
|
||||
schema = dynamodb.create_schema('column1', str(), 'column2', int())
|
||||
dynamodb.create_table('table1', schema, 200, 200)
|
||||
from __future__ import unicode_literals
|
||||
import six
|
||||
import boto
|
||||
import boto.dynamodb
|
||||
import sure # noqa
|
||||
import requests
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from moto import mock_dynamodb, mock_dynamodb_deprecated
|
||||
from moto.dynamodb import dynamodb_backend
|
||||
|
||||
from boto.exception import DynamoDBResponseError
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_list_tables():
|
||||
name = "TestTable"
|
||||
dynamodb_backend.create_table(name, hash_key_attr="name", hash_key_type="S")
|
||||
conn = boto.connect_dynamodb("the_key", "the_secret")
|
||||
assert conn.list_tables() == ["TestTable"]
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_list_tables_layer_1():
|
||||
dynamodb_backend.create_table("test_1", hash_key_attr="name", hash_key_type="S")
|
||||
dynamodb_backend.create_table("test_2", hash_key_attr="name", hash_key_type="S")
|
||||
conn = boto.connect_dynamodb("the_key", "the_secret")
|
||||
res = conn.layer1.list_tables(limit=1)
|
||||
expected = {"TableNames": ["test_1"], "LastEvaluatedTableName": "test_1"}
|
||||
res.should.equal(expected)
|
||||
|
||||
res = conn.layer1.list_tables(limit=1, start_table="test_1")
|
||||
expected = {"TableNames": ["test_2"]}
|
||||
res.should.equal(expected)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_describe_missing_table():
|
||||
conn = boto.connect_dynamodb("the_key", "the_secret")
|
||||
with assert_raises(DynamoDBResponseError):
|
||||
conn.describe_table("messages")
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
def test_dynamodb_with_connect_to_region():
|
||||
# this will work if connected with boto.connect_dynamodb()
|
||||
dynamodb = boto.dynamodb.connect_to_region("us-west-2")
|
||||
|
||||
schema = dynamodb.create_schema("column1", str(), "column2", int())
|
||||
dynamodb.create_table("table1", schema, 200, 200)
|
||||
|
|
|
|||
|
|
@ -13,17 +13,14 @@ from boto.exception import DynamoDBResponseError
|
|||
|
||||
def create_table(conn):
|
||||
message_table_schema = conn.create_schema(
|
||||
hash_key_name='forum_name',
|
||||
hash_key_name="forum_name",
|
||||
hash_key_proto_value=str,
|
||||
range_key_name='subject',
|
||||
range_key_proto_value=str
|
||||
range_key_name="subject",
|
||||
range_key_proto_value=str,
|
||||
)
|
||||
|
||||
table = conn.create_table(
|
||||
name='messages',
|
||||
schema=message_table_schema,
|
||||
read_units=10,
|
||||
write_units=10
|
||||
name="messages", schema=message_table_schema, read_units=10, write_units=10
|
||||
)
|
||||
return table
|
||||
|
||||
|
|
@ -35,29 +32,23 @@ def test_create_table():
|
|||
create_table(conn)
|
||||
|
||||
expected = {
|
||||
'Table': {
|
||||
'CreationDateTime': 1326499200.0,
|
||||
'ItemCount': 0,
|
||||
'KeySchema': {
|
||||
'HashKeyElement': {
|
||||
'AttributeName': 'forum_name',
|
||||
'AttributeType': 'S'
|
||||
},
|
||||
'RangeKeyElement': {
|
||||
'AttributeName': 'subject',
|
||||
'AttributeType': 'S'
|
||||
}
|
||||
"Table": {
|
||||
"CreationDateTime": 1326499200.0,
|
||||
"ItemCount": 0,
|
||||
"KeySchema": {
|
||||
"HashKeyElement": {"AttributeName": "forum_name", "AttributeType": "S"},
|
||||
"RangeKeyElement": {"AttributeName": "subject", "AttributeType": "S"},
|
||||
},
|
||||
'ProvisionedThroughput': {
|
||||
'ReadCapacityUnits': 10,
|
||||
'WriteCapacityUnits': 10
|
||||
"ProvisionedThroughput": {
|
||||
"ReadCapacityUnits": 10,
|
||||
"WriteCapacityUnits": 10,
|
||||
},
|
||||
'TableName': 'messages',
|
||||
'TableSizeBytes': 0,
|
||||
'TableStatus': 'ACTIVE'
|
||||
"TableName": "messages",
|
||||
"TableSizeBytes": 0,
|
||||
"TableStatus": "ACTIVE",
|
||||
}
|
||||
}
|
||||
conn.describe_table('messages').should.equal(expected)
|
||||
conn.describe_table("messages").should.equal(expected)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -66,11 +57,12 @@ def test_delete_table():
|
|||
create_table(conn)
|
||||
conn.list_tables().should.have.length_of(1)
|
||||
|
||||
conn.layer1.delete_table('messages')
|
||||
conn.layer1.delete_table("messages")
|
||||
conn.list_tables().should.have.length_of(0)
|
||||
|
||||
conn.layer1.delete_table.when.called_with(
|
||||
'messages').should.throw(DynamoDBResponseError)
|
||||
conn.layer1.delete_table.when.called_with("messages").should.throw(
|
||||
DynamoDBResponseError
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -93,45 +85,47 @@ def test_item_add_and_describe_and_update():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
attrs=item_data,
|
||||
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
|
||||
)
|
||||
item.put()
|
||||
|
||||
table.has_item("LOLCat Forum", "Check this out!").should.equal(True)
|
||||
|
||||
returned_item = table.get_item(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
attributes_to_get=['Body', 'SentBy']
|
||||
hash_key="LOLCat Forum",
|
||||
range_key="Check this out!",
|
||||
attributes_to_get=["Body", "SentBy"],
|
||||
)
|
||||
dict(returned_item).should.equal(
|
||||
{
|
||||
"forum_name": "LOLCat Forum",
|
||||
"subject": "Check this out!",
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
}
|
||||
)
|
||||
dict(returned_item).should.equal({
|
||||
'forum_name': 'LOLCat Forum',
|
||||
'subject': 'Check this out!',
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
})
|
||||
|
||||
item['SentBy'] = 'User B'
|
||||
item["SentBy"] = "User B"
|
||||
item.put()
|
||||
|
||||
returned_item = table.get_item(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
attributes_to_get=['Body', 'SentBy']
|
||||
hash_key="LOLCat Forum",
|
||||
range_key="Check this out!",
|
||||
attributes_to_get=["Body", "SentBy"],
|
||||
)
|
||||
dict(returned_item).should.equal(
|
||||
{
|
||||
"forum_name": "LOLCat Forum",
|
||||
"subject": "Check this out!",
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
}
|
||||
)
|
||||
dict(returned_item).should.equal({
|
||||
'forum_name': 'LOLCat Forum',
|
||||
'subject': 'Check this out!',
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
})
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -139,11 +133,8 @@ def test_item_put_without_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.put_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
item=dict(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
),
|
||||
table_name="undeclared-table",
|
||||
item=dict(hash_key="LOLCat Forum", range_key="Check this out!"),
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
||||
|
||||
|
|
@ -152,10 +143,9 @@ def test_get_missing_item():
|
|||
conn = boto.connect_dynamodb()
|
||||
table = create_table(conn)
|
||||
|
||||
table.get_item.when.called_with(
|
||||
hash_key='tester',
|
||||
range_key='other',
|
||||
).should.throw(DynamoDBKeyNotFoundError)
|
||||
table.get_item.when.called_with(hash_key="tester", range_key="other").should.throw(
|
||||
DynamoDBKeyNotFoundError
|
||||
)
|
||||
table.has_item("foobar", "more").should.equal(False)
|
||||
|
||||
|
||||
|
|
@ -164,11 +154,8 @@ def test_get_item_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.get_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
key={
|
||||
'HashKeyElement': {'S': 'tester'},
|
||||
'RangeKeyElement': {'S': 'test-range'},
|
||||
},
|
||||
table_name="undeclared-table",
|
||||
key={"HashKeyElement": {"S": "tester"}, "RangeKeyElement": {"S": "test-range"}},
|
||||
).should.throw(DynamoDBKeyNotFoundError)
|
||||
|
||||
|
||||
|
|
@ -182,10 +169,7 @@ def test_get_item_without_range_key():
|
|||
range_key_proto_value=int,
|
||||
)
|
||||
table = conn.create_table(
|
||||
name='messages',
|
||||
schema=message_table_schema,
|
||||
read_units=10,
|
||||
write_units=10
|
||||
name="messages", schema=message_table_schema, read_units=10, write_units=10
|
||||
)
|
||||
|
||||
hash_key = 3241526475
|
||||
|
|
@ -193,8 +177,9 @@ def test_get_item_without_range_key():
|
|||
new_item = table.new_item(hash_key=hash_key, range_key=range_key)
|
||||
new_item.put()
|
||||
|
||||
table.get_item.when.called_with(
|
||||
hash_key=hash_key).should.throw(DynamoDBValidationError)
|
||||
table.get_item.when.called_with(hash_key=hash_key).should.throw(
|
||||
DynamoDBValidationError
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -203,14 +188,12 @@ def test_delete_item():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
attrs=item_data,
|
||||
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
|
||||
)
|
||||
item.put()
|
||||
|
||||
|
|
@ -218,7 +201,7 @@ def test_delete_item():
|
|||
table.item_count.should.equal(1)
|
||||
|
||||
response = item.delete()
|
||||
response.should.equal({u'Attributes': [], u'ConsumedCapacityUnits': 0.5})
|
||||
response.should.equal({"Attributes": [], "ConsumedCapacityUnits": 0.5})
|
||||
table.refresh()
|
||||
table.item_count.should.equal(0)
|
||||
|
||||
|
|
@ -231,31 +214,31 @@ def test_delete_item_with_attribute_response():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
range_key='Check this out!',
|
||||
attrs=item_data,
|
||||
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
|
||||
)
|
||||
item.put()
|
||||
|
||||
table.refresh()
|
||||
table.item_count.should.equal(1)
|
||||
|
||||
response = item.delete(return_values='ALL_OLD')
|
||||
response.should.equal({
|
||||
'Attributes': {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'forum_name': 'LOLCat Forum',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'SentBy': 'User A',
|
||||
'subject': 'Check this out!'
|
||||
},
|
||||
'ConsumedCapacityUnits': 0.5
|
||||
})
|
||||
response = item.delete(return_values="ALL_OLD")
|
||||
response.should.equal(
|
||||
{
|
||||
"Attributes": {
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"forum_name": "LOLCat Forum",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"SentBy": "User A",
|
||||
"subject": "Check this out!",
|
||||
},
|
||||
"ConsumedCapacityUnits": 0.5,
|
||||
}
|
||||
)
|
||||
table.refresh()
|
||||
table.item_count.should.equal(0)
|
||||
|
||||
|
|
@ -267,11 +250,8 @@ def test_delete_item_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.delete_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
key={
|
||||
'HashKeyElement': {'S': 'tester'},
|
||||
'RangeKeyElement': {'S': 'test-range'},
|
||||
},
|
||||
table_name="undeclared-table",
|
||||
key={"HashKeyElement": {"S": "tester"}, "RangeKeyElement": {"S": "test-range"}},
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
||||
|
||||
|
|
@ -281,54 +261,42 @@ def test_query():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='456',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='123',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='789',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="789", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.GT('1'))
|
||||
results.response['Items'].should.have.length_of(3)
|
||||
results = table.query(hash_key="the-key", range_key_condition=condition.GT("1"))
|
||||
results.response["Items"].should.have.length_of(3)
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.GT('234'))
|
||||
results.response['Items'].should.have.length_of(2)
|
||||
results = table.query(hash_key="the-key", range_key_condition=condition.GT("234"))
|
||||
results.response["Items"].should.have.length_of(2)
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.GT('9999'))
|
||||
results.response['Items'].should.have.length_of(0)
|
||||
results = table.query(hash_key="the-key", range_key_condition=condition.GT("9999"))
|
||||
results.response["Items"].should.have.length_of(0)
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.CONTAINS('12'))
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.query(
|
||||
hash_key="the-key", range_key_condition=condition.CONTAINS("12")
|
||||
)
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.BEGINS_WITH('7'))
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.query(
|
||||
hash_key="the-key", range_key_condition=condition.BEGINS_WITH("7")
|
||||
)
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.query(hash_key='the-key',
|
||||
range_key_condition=condition.BETWEEN('567', '890'))
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.query(
|
||||
hash_key="the-key", range_key_condition=condition.BETWEEN("567", "890")
|
||||
)
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -336,12 +304,10 @@ def test_query_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.query.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
hash_key_value={'S': 'the-key'},
|
||||
table_name="undeclared-table",
|
||||
hash_key_value={"S": "the-key"},
|
||||
range_key_conditions={
|
||||
"AttributeValueList": [{
|
||||
"S": "User B"
|
||||
}],
|
||||
"AttributeValueList": [{"S": "User B"}],
|
||||
"ComparisonOperator": "EQ",
|
||||
},
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
|
@ -353,61 +319,49 @@ def test_scan():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='456',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='123',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='789',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="789", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
results = table.scan()
|
||||
results.response['Items'].should.have.length_of(3)
|
||||
results.response["Items"].should.have.length_of(3)
|
||||
|
||||
results = table.scan(scan_filter={'SentBy': condition.EQ('User B')})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"SentBy": condition.EQ("User B")})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Body': condition.BEGINS_WITH('http')})
|
||||
results.response['Items'].should.have.length_of(3)
|
||||
results = table.scan(scan_filter={"Body": condition.BEGINS_WITH("http")})
|
||||
results.response["Items"].should.have.length_of(3)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.CONTAINS(2)})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"Ids": condition.CONTAINS(2)})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.NOT_NULL()})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"Ids": condition.NOT_NULL()})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.NULL()})
|
||||
results.response['Items'].should.have.length_of(2)
|
||||
results = table.scan(scan_filter={"Ids": condition.NULL()})
|
||||
results.response["Items"].should.have.length_of(2)
|
||||
|
||||
results = table.scan(scan_filter={'PK': condition.BETWEEN(8, 9)})
|
||||
results.response['Items'].should.have.length_of(0)
|
||||
results = table.scan(scan_filter={"PK": condition.BETWEEN(8, 9)})
|
||||
results.response["Items"].should.have.length_of(0)
|
||||
|
||||
results = table.scan(scan_filter={'PK': condition.BETWEEN(5, 8)})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"PK": condition.BETWEEN(5, 8)})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -415,13 +369,11 @@ def test_scan_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.scan.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
table_name="undeclared-table",
|
||||
scan_filter={
|
||||
"SentBy": {
|
||||
"AttributeValueList": [{
|
||||
"S": "User B"}
|
||||
],
|
||||
"ComparisonOperator": "EQ"
|
||||
"AttributeValueList": [{"S": "User B"}],
|
||||
"ComparisonOperator": "EQ",
|
||||
}
|
||||
},
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
|
@ -433,7 +385,7 @@ def test_scan_after_has_item():
|
|||
table = create_table(conn)
|
||||
list(table.scan()).should.equal([])
|
||||
|
||||
table.has_item(hash_key='the-key', range_key='123')
|
||||
table.has_item(hash_key="the-key", range_key="123")
|
||||
|
||||
list(table.scan()).should.equal([])
|
||||
|
||||
|
|
@ -446,27 +398,31 @@ def test_write_batch():
|
|||
batch_list = conn.new_batch_write_list()
|
||||
|
||||
items = []
|
||||
items.append(table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='123',
|
||||
attrs={
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
},
|
||||
))
|
||||
items.append(
|
||||
table.new_item(
|
||||
hash_key="the-key",
|
||||
range_key="123",
|
||||
attrs={
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
items.append(table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='789',
|
||||
attrs={
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
},
|
||||
))
|
||||
items.append(
|
||||
table.new_item(
|
||||
hash_key="the-key",
|
||||
range_key="789",
|
||||
attrs={
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
batch_list.add_batch(table, puts=items)
|
||||
conn.batch_write_item(batch_list)
|
||||
|
|
@ -475,7 +431,7 @@ def test_write_batch():
|
|||
table.item_count.should.equal(2)
|
||||
|
||||
batch_list = conn.new_batch_write_list()
|
||||
batch_list.add_batch(table, deletes=[('the-key', '789')])
|
||||
batch_list.add_batch(table, deletes=[("the-key", "789")])
|
||||
conn.batch_write_item(batch_list)
|
||||
|
||||
table.refresh()
|
||||
|
|
@ -488,39 +444,27 @@ def test_batch_read():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='456',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
range_key='123',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='another-key',
|
||||
range_key='789',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="another-key", range_key="789", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
items = table.batch_get_item([('the-key', '123'), ('another-key', '789')])
|
||||
items = table.batch_get_item([("the-key", "123"), ("another-key", "789")])
|
||||
# Iterate through so that batch_item gets called
|
||||
count = len([x for x in items])
|
||||
count.should.equal(2)
|
||||
|
|
|
|||
|
|
@ -13,15 +13,11 @@ from boto.exception import DynamoDBResponseError
|
|||
|
||||
def create_table(conn):
|
||||
message_table_schema = conn.create_schema(
|
||||
hash_key_name='forum_name',
|
||||
hash_key_proto_value=str,
|
||||
hash_key_name="forum_name", hash_key_proto_value=str
|
||||
)
|
||||
|
||||
table = conn.create_table(
|
||||
name='messages',
|
||||
schema=message_table_schema,
|
||||
read_units=10,
|
||||
write_units=10
|
||||
name="messages", schema=message_table_schema, read_units=10, write_units=10
|
||||
)
|
||||
return table
|
||||
|
||||
|
|
@ -33,25 +29,22 @@ def test_create_table():
|
|||
create_table(conn)
|
||||
|
||||
expected = {
|
||||
'Table': {
|
||||
'CreationDateTime': 1326499200.0,
|
||||
'ItemCount': 0,
|
||||
'KeySchema': {
|
||||
'HashKeyElement': {
|
||||
'AttributeName': 'forum_name',
|
||||
'AttributeType': 'S'
|
||||
},
|
||||
"Table": {
|
||||
"CreationDateTime": 1326499200.0,
|
||||
"ItemCount": 0,
|
||||
"KeySchema": {
|
||||
"HashKeyElement": {"AttributeName": "forum_name", "AttributeType": "S"}
|
||||
},
|
||||
'ProvisionedThroughput': {
|
||||
'ReadCapacityUnits': 10,
|
||||
'WriteCapacityUnits': 10
|
||||
"ProvisionedThroughput": {
|
||||
"ReadCapacityUnits": 10,
|
||||
"WriteCapacityUnits": 10,
|
||||
},
|
||||
'TableName': 'messages',
|
||||
'TableSizeBytes': 0,
|
||||
'TableStatus': 'ACTIVE',
|
||||
"TableName": "messages",
|
||||
"TableSizeBytes": 0,
|
||||
"TableStatus": "ACTIVE",
|
||||
}
|
||||
}
|
||||
conn.describe_table('messages').should.equal(expected)
|
||||
conn.describe_table("messages").should.equal(expected)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -60,11 +53,12 @@ def test_delete_table():
|
|||
create_table(conn)
|
||||
conn.list_tables().should.have.length_of(1)
|
||||
|
||||
conn.layer1.delete_table('messages')
|
||||
conn.layer1.delete_table("messages")
|
||||
conn.list_tables().should.have.length_of(0)
|
||||
|
||||
conn.layer1.delete_table.when.called_with(
|
||||
'messages').should.throw(DynamoDBResponseError)
|
||||
conn.layer1.delete_table.when.called_with("messages").should.throw(
|
||||
DynamoDBResponseError
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -87,38 +81,37 @@ def test_item_add_and_describe_and_update():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
returned_item = table.get_item(
|
||||
hash_key='LOLCat Forum',
|
||||
attributes_to_get=['Body', 'SentBy']
|
||||
hash_key="LOLCat Forum", attributes_to_get=["Body", "SentBy"]
|
||||
)
|
||||
dict(returned_item).should.equal(
|
||||
{
|
||||
"forum_name": "LOLCat Forum",
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
}
|
||||
)
|
||||
dict(returned_item).should.equal({
|
||||
'forum_name': 'LOLCat Forum',
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
})
|
||||
|
||||
item['SentBy'] = 'User B'
|
||||
item["SentBy"] = "User B"
|
||||
item.put()
|
||||
|
||||
returned_item = table.get_item(
|
||||
hash_key='LOLCat Forum',
|
||||
attributes_to_get=['Body', 'SentBy']
|
||||
hash_key="LOLCat Forum", attributes_to_get=["Body", "SentBy"]
|
||||
)
|
||||
dict(returned_item).should.equal(
|
||||
{
|
||||
"forum_name": "LOLCat Forum",
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
}
|
||||
)
|
||||
dict(returned_item).should.equal({
|
||||
'forum_name': 'LOLCat Forum',
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
})
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -126,10 +119,7 @@ def test_item_put_without_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.put_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
item=dict(
|
||||
hash_key='LOLCat Forum',
|
||||
),
|
||||
table_name="undeclared-table", item=dict(hash_key="LOLCat Forum")
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
||||
|
||||
|
|
@ -138,9 +128,9 @@ def test_get_missing_item():
|
|||
conn = boto.connect_dynamodb()
|
||||
table = create_table(conn)
|
||||
|
||||
table.get_item.when.called_with(
|
||||
hash_key='tester',
|
||||
).should.throw(DynamoDBKeyNotFoundError)
|
||||
table.get_item.when.called_with(hash_key="tester").should.throw(
|
||||
DynamoDBKeyNotFoundError
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -148,10 +138,7 @@ def test_get_item_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.get_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
key={
|
||||
'HashKeyElement': {'S': 'tester'},
|
||||
},
|
||||
table_name="undeclared-table", key={"HashKeyElement": {"S": "tester"}}
|
||||
).should.throw(DynamoDBKeyNotFoundError)
|
||||
|
||||
|
||||
|
|
@ -161,21 +148,18 @@ def test_delete_item():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
table.refresh()
|
||||
table.item_count.should.equal(1)
|
||||
|
||||
response = item.delete()
|
||||
response.should.equal({u'Attributes': [], u'ConsumedCapacityUnits': 0.5})
|
||||
response.should.equal({"Attributes": [], "ConsumedCapacityUnits": 0.5})
|
||||
table.refresh()
|
||||
table.item_count.should.equal(0)
|
||||
|
||||
|
|
@ -188,29 +172,28 @@ def test_delete_item_with_attribute_response():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='LOLCat Forum',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
table.refresh()
|
||||
table.item_count.should.equal(1)
|
||||
|
||||
response = item.delete(return_values='ALL_OLD')
|
||||
response.should.equal({
|
||||
u'Attributes': {
|
||||
u'Body': u'http://url_to_lolcat.gif',
|
||||
u'forum_name': u'LOLCat Forum',
|
||||
u'ReceivedTime': u'12/9/2011 11:36:03 PM',
|
||||
u'SentBy': u'User A',
|
||||
},
|
||||
u'ConsumedCapacityUnits': 0.5
|
||||
})
|
||||
response = item.delete(return_values="ALL_OLD")
|
||||
response.should.equal(
|
||||
{
|
||||
"Attributes": {
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"forum_name": "LOLCat Forum",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"SentBy": "User A",
|
||||
},
|
||||
"ConsumedCapacityUnits": 0.5,
|
||||
}
|
||||
)
|
||||
table.refresh()
|
||||
table.item_count.should.equal(0)
|
||||
|
||||
|
|
@ -222,10 +205,7 @@ def test_delete_item_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.delete_item.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
key={
|
||||
'HashKeyElement': {'S': 'tester'},
|
||||
},
|
||||
table_name="undeclared-table", key={"HashKeyElement": {"S": "tester"}}
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
||||
|
||||
|
|
@ -235,18 +215,15 @@ def test_query():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
results = table.query(hash_key='the-key')
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.query(hash_key="the-key")
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -254,8 +231,7 @@ def test_query_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.query.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
hash_key_value={'S': 'the-key'},
|
||||
table_name="undeclared-table", hash_key_value={"S": "the-key"}
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
||||
|
||||
|
|
@ -265,58 +241,49 @@ def test_scan():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key2',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key2", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key3',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key3", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
results = table.scan()
|
||||
results.response['Items'].should.have.length_of(3)
|
||||
results.response["Items"].should.have.length_of(3)
|
||||
|
||||
results = table.scan(scan_filter={'SentBy': condition.EQ('User B')})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"SentBy": condition.EQ("User B")})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Body': condition.BEGINS_WITH('http')})
|
||||
results.response['Items'].should.have.length_of(3)
|
||||
results = table.scan(scan_filter={"Body": condition.BEGINS_WITH("http")})
|
||||
results.response["Items"].should.have.length_of(3)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.CONTAINS(2)})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"Ids": condition.CONTAINS(2)})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.NOT_NULL()})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"Ids": condition.NOT_NULL()})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
results = table.scan(scan_filter={'Ids': condition.NULL()})
|
||||
results.response['Items'].should.have.length_of(2)
|
||||
results = table.scan(scan_filter={"Ids": condition.NULL()})
|
||||
results.response["Items"].should.have.length_of(2)
|
||||
|
||||
results = table.scan(scan_filter={'PK': condition.BETWEEN(8, 9)})
|
||||
results.response['Items'].should.have.length_of(0)
|
||||
results = table.scan(scan_filter={"PK": condition.BETWEEN(8, 9)})
|
||||
results.response["Items"].should.have.length_of(0)
|
||||
|
||||
results = table.scan(scan_filter={'PK': condition.BETWEEN(5, 8)})
|
||||
results.response['Items'].should.have.length_of(1)
|
||||
results = table.scan(scan_filter={"PK": condition.BETWEEN(5, 8)})
|
||||
results.response["Items"].should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_dynamodb_deprecated
|
||||
|
|
@ -324,13 +291,11 @@ def test_scan_with_undeclared_table():
|
|||
conn = boto.connect_dynamodb()
|
||||
|
||||
conn.layer1.scan.when.called_with(
|
||||
table_name='undeclared-table',
|
||||
table_name="undeclared-table",
|
||||
scan_filter={
|
||||
"SentBy": {
|
||||
"AttributeValueList": [{
|
||||
"S": "User B"}
|
||||
],
|
||||
"ComparisonOperator": "EQ"
|
||||
"AttributeValueList": [{"S": "User B"}],
|
||||
"ComparisonOperator": "EQ",
|
||||
}
|
||||
},
|
||||
).should.throw(DynamoDBResponseError)
|
||||
|
|
@ -342,7 +307,7 @@ def test_scan_after_has_item():
|
|||
table = create_table(conn)
|
||||
list(table.scan()).should.equal([])
|
||||
|
||||
table.has_item('the-key')
|
||||
table.has_item("the-key")
|
||||
|
||||
list(table.scan()).should.equal([])
|
||||
|
||||
|
|
@ -355,25 +320,29 @@ def test_write_batch():
|
|||
batch_list = conn.new_batch_write_list()
|
||||
|
||||
items = []
|
||||
items.append(table.new_item(
|
||||
hash_key='the-key',
|
||||
attrs={
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
},
|
||||
))
|
||||
items.append(
|
||||
table.new_item(
|
||||
hash_key="the-key",
|
||||
attrs={
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
items.append(table.new_item(
|
||||
hash_key='the-key2',
|
||||
attrs={
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
},
|
||||
))
|
||||
items.append(
|
||||
table.new_item(
|
||||
hash_key="the-key2",
|
||||
attrs={
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
batch_list.add_batch(table, puts=items)
|
||||
conn.batch_write_item(batch_list)
|
||||
|
|
@ -382,7 +351,7 @@ def test_write_batch():
|
|||
table.item_count.should.equal(2)
|
||||
|
||||
batch_list = conn.new_batch_write_list()
|
||||
batch_list.add_batch(table, deletes=[('the-key')])
|
||||
batch_list.add_batch(table, deletes=[("the-key")])
|
||||
conn.batch_write_item(batch_list)
|
||||
|
||||
table.refresh()
|
||||
|
|
@ -395,36 +364,27 @@ def test_batch_read():
|
|||
table = create_table(conn)
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User A',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User A",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='the-key1',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key1", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item = table.new_item(
|
||||
hash_key='the-key2',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="the-key2", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
item_data = {
|
||||
'Body': 'http://url_to_lolcat.gif',
|
||||
'SentBy': 'User B',
|
||||
'ReceivedTime': '12/9/2011 11:36:03 PM',
|
||||
'Ids': set([1, 2, 3]),
|
||||
'PK': 7,
|
||||
"Body": "http://url_to_lolcat.gif",
|
||||
"SentBy": "User B",
|
||||
"ReceivedTime": "12/9/2011 11:36:03 PM",
|
||||
"Ids": set([1, 2, 3]),
|
||||
"PK": 7,
|
||||
}
|
||||
item = table.new_item(
|
||||
hash_key='another-key',
|
||||
attrs=item_data,
|
||||
)
|
||||
item = table.new_item(hash_key="another-key", attrs=item_data)
|
||||
item.put()
|
||||
|
||||
items = table.batch_get_item([('the-key1'), ('another-key')])
|
||||
items = table.batch_get_item([("the-key1"), ("another-key")])
|
||||
# Iterate through so that batch_item gets called
|
||||
count = len([x for x in items])
|
||||
count.should.have.equal(2)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
def test_table_list():
|
||||
backend = server.create_backend_app("dynamodb")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get('/')
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
headers = {'X-Amz-Target': 'TestTable.ListTables'}
|
||||
res = test_client.get('/', headers=headers)
|
||||
res.data.should.contain(b'TableNames')
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
def test_table_list():
|
||||
backend = server.create_backend_app("dynamodb")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get("/")
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
headers = {"X-Amz-Target": "TestTable.ListTables"}
|
||||
res = test_client.get("/", headers=headers)
|
||||
res.data.should.contain(b"TableNames")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,19 +1,19 @@
|
|||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
def test_table_list():
|
||||
backend = server.create_backend_app("dynamodb2")
|
||||
test_client = backend.test_client()
|
||||
res = test_client.get('/')
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
headers = {'X-Amz-Target': 'TestTable.ListTables'}
|
||||
res = test_client.get('/', headers=headers)
|
||||
res.data.should.contain(b'TableNames')
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
def test_table_list():
|
||||
backend = server.create_backend_app("dynamodb2")
|
||||
test_client = backend.test_client()
|
||||
res = test_client.get("/")
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
headers = {"X-Amz-Target": "TestTable.ListTables"}
|
||||
res = test_client.get("/", headers=headers)
|
||||
res.data.should.contain(b"TableNames")
|
||||
|
|
|
|||
|
|
@ -6,142 +6,190 @@ import boto3
|
|||
from moto import mock_dynamodb2, mock_dynamodbstreams
|
||||
|
||||
|
||||
class TestCore():
|
||||
class TestCore:
|
||||
stream_arn = None
|
||||
mocks = []
|
||||
|
||||
|
||||
def setup(self):
|
||||
self.mocks = [mock_dynamodb2(), mock_dynamodbstreams()]
|
||||
for m in self.mocks:
|
||||
m.start()
|
||||
|
||||
|
||||
# create a table with a stream
|
||||
conn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
resp = conn.create_table(
|
||||
TableName='test-streams',
|
||||
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
|
||||
AttributeDefinitions=[{'AttributeName': 'id',
|
||||
'AttributeType': 'S'}],
|
||||
ProvisionedThroughput={'ReadCapacityUnits': 1,
|
||||
'WriteCapacityUnits': 1},
|
||||
TableName="test-streams",
|
||||
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
|
||||
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1},
|
||||
StreamSpecification={
|
||||
'StreamEnabled': True,
|
||||
'StreamViewType': 'NEW_AND_OLD_IMAGES'
|
||||
}
|
||||
"StreamEnabled": True,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES",
|
||||
},
|
||||
)
|
||||
self.stream_arn = resp['TableDescription']['LatestStreamArn']
|
||||
self.stream_arn = resp["TableDescription"]["LatestStreamArn"]
|
||||
|
||||
def teardown(self):
|
||||
conn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
conn.delete_table(TableName='test-streams')
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
conn.delete_table(TableName="test-streams")
|
||||
self.stream_arn = None
|
||||
|
||||
for m in self.mocks:
|
||||
m.stop()
|
||||
|
||||
|
||||
def test_verify_stream(self):
|
||||
conn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
resp = conn.describe_table(TableName='test-streams')
|
||||
assert 'LatestStreamArn' in resp['Table']
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
resp = conn.describe_table(TableName="test-streams")
|
||||
assert "LatestStreamArn" in resp["Table"]
|
||||
|
||||
def test_describe_stream(self):
|
||||
conn = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
assert 'StreamDescription' in resp
|
||||
desc = resp['StreamDescription']
|
||||
assert desc['StreamArn'] == self.stream_arn
|
||||
assert desc['TableName'] == 'test-streams'
|
||||
assert "StreamDescription" in resp
|
||||
desc = resp["StreamDescription"]
|
||||
assert desc["StreamArn"] == self.stream_arn
|
||||
assert desc["TableName"] == "test-streams"
|
||||
|
||||
def test_list_streams(self):
|
||||
conn = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.list_streams()
|
||||
assert resp['Streams'][0]['StreamArn'] == self.stream_arn
|
||||
assert resp["Streams"][0]["StreamArn"] == self.stream_arn
|
||||
|
||||
resp = conn.list_streams(TableName='no-stream')
|
||||
assert not resp['Streams']
|
||||
resp = conn.list_streams(TableName="no-stream")
|
||||
assert not resp["Streams"]
|
||||
|
||||
def test_get_shard_iterator(self):
|
||||
conn = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
shard_id = resp['StreamDescription']['Shards'][0]['ShardId']
|
||||
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType='TRIM_HORIZON'
|
||||
ShardIteratorType="TRIM_HORIZON",
|
||||
)
|
||||
assert 'ShardIterator' in resp
|
||||
|
||||
assert "ShardIterator" in resp
|
||||
|
||||
def test_get_shard_iterator_at_sequence_number(self):
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType="AT_SEQUENCE_NUMBER",
|
||||
SequenceNumber=resp["StreamDescription"]["Shards"][0][
|
||||
"SequenceNumberRange"
|
||||
]["StartingSequenceNumber"],
|
||||
)
|
||||
assert "ShardIterator" in resp
|
||||
|
||||
def test_get_shard_iterator_after_sequence_number(self):
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType="AFTER_SEQUENCE_NUMBER",
|
||||
SequenceNumber=resp["StreamDescription"]["Shards"][0][
|
||||
"SequenceNumberRange"
|
||||
]["StartingSequenceNumber"],
|
||||
)
|
||||
assert "ShardIterator" in resp
|
||||
|
||||
def test_get_records_empty(self):
|
||||
conn = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
shard_id = resp['StreamDescription']['Shards'][0]['ShardId']
|
||||
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType='LATEST'
|
||||
StreamArn=self.stream_arn, ShardId=shard_id, ShardIteratorType="LATEST"
|
||||
)
|
||||
iterator_id = resp['ShardIterator']
|
||||
iterator_id = resp["ShardIterator"]
|
||||
|
||||
resp = conn.get_records(ShardIterator=iterator_id)
|
||||
assert 'Records' in resp
|
||||
assert len(resp['Records']) == 0
|
||||
assert "Records" in resp
|
||||
assert len(resp["Records"]) == 0
|
||||
|
||||
def test_get_records_seq(self):
|
||||
conn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
conn.put_item(
|
||||
TableName='test-streams',
|
||||
Item={
|
||||
'id': {'S': 'entry1'},
|
||||
'first_col': {'S': 'foo'}
|
||||
}
|
||||
TableName="test-streams",
|
||||
Item={"id": {"S": "entry1"}, "first_col": {"S": "foo"}},
|
||||
)
|
||||
conn.put_item(
|
||||
TableName='test-streams',
|
||||
TableName="test-streams",
|
||||
Item={
|
||||
'id': {'S': 'entry1'},
|
||||
'first_col': {'S': 'bar'},
|
||||
'second_col': {'S': 'baz'}
|
||||
}
|
||||
"id": {"S": "entry1"},
|
||||
"first_col": {"S": "bar"},
|
||||
"second_col": {"S": "baz"},
|
||||
},
|
||||
)
|
||||
conn.delete_item(
|
||||
TableName='test-streams',
|
||||
Key={'id': {'S': 'entry1'}}
|
||||
)
|
||||
|
||||
conn = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
|
||||
conn.delete_item(TableName="test-streams", Key={"id": {"S": "entry1"}})
|
||||
|
||||
conn = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
|
||||
resp = conn.describe_stream(StreamArn=self.stream_arn)
|
||||
shard_id = resp['StreamDescription']['Shards'][0]['ShardId']
|
||||
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType='TRIM_HORIZON'
|
||||
ShardIteratorType="TRIM_HORIZON",
|
||||
)
|
||||
iterator_id = resp['ShardIterator']
|
||||
iterator_id = resp["ShardIterator"]
|
||||
|
||||
resp = conn.get_records(ShardIterator=iterator_id)
|
||||
assert len(resp['Records']) == 3
|
||||
assert resp['Records'][0]['eventName'] == 'INSERT'
|
||||
assert resp['Records'][1]['eventName'] == 'MODIFY'
|
||||
assert resp['Records'][2]['eventName'] == 'DELETE'
|
||||
assert len(resp["Records"]) == 3
|
||||
assert resp["Records"][0]["eventName"] == "INSERT"
|
||||
assert resp["Records"][1]["eventName"] == "MODIFY"
|
||||
assert resp["Records"][2]["eventName"] == "DELETE"
|
||||
|
||||
sequence_number_modify = resp["Records"][1]["dynamodb"]["SequenceNumber"]
|
||||
|
||||
# now try fetching from the next shard iterator, it should be
|
||||
# empty
|
||||
resp = conn.get_records(ShardIterator=resp['NextShardIterator'])
|
||||
assert len(resp['Records']) == 0
|
||||
resp = conn.get_records(ShardIterator=resp["NextShardIterator"])
|
||||
assert len(resp["Records"]) == 0
|
||||
|
||||
# check that if we get the shard iterator AT_SEQUENCE_NUMBER will get the MODIFY event
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType="AT_SEQUENCE_NUMBER",
|
||||
SequenceNumber=sequence_number_modify,
|
||||
)
|
||||
iterator_id = resp["ShardIterator"]
|
||||
resp = conn.get_records(ShardIterator=iterator_id)
|
||||
assert len(resp["Records"]) == 2
|
||||
assert resp["Records"][0]["eventName"] == "MODIFY"
|
||||
assert resp["Records"][1]["eventName"] == "DELETE"
|
||||
|
||||
# check that if we get the shard iterator AFTER_SEQUENCE_NUMBER will get the DELETE event
|
||||
resp = conn.get_shard_iterator(
|
||||
StreamArn=self.stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType="AFTER_SEQUENCE_NUMBER",
|
||||
SequenceNumber=sequence_number_modify,
|
||||
)
|
||||
iterator_id = resp["ShardIterator"]
|
||||
resp = conn.get_records(ShardIterator=iterator_id)
|
||||
assert len(resp["Records"]) == 1
|
||||
assert resp["Records"][0]["eventName"] == "DELETE"
|
||||
|
||||
|
||||
class TestEdges():
|
||||
class TestEdges:
|
||||
mocks = []
|
||||
|
||||
def setup(self):
|
||||
|
|
@ -153,82 +201,73 @@ class TestEdges():
|
|||
for m in self.mocks:
|
||||
m.stop()
|
||||
|
||||
|
||||
def test_enable_stream_on_table(self):
|
||||
conn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
resp = conn.create_table(
|
||||
TableName='test-streams',
|
||||
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
|
||||
AttributeDefinitions=[{'AttributeName': 'id',
|
||||
'AttributeType': 'S'}],
|
||||
ProvisionedThroughput={'ReadCapacityUnits': 1,
|
||||
'WriteCapacityUnits': 1}
|
||||
TableName="test-streams",
|
||||
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
|
||||
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1},
|
||||
)
|
||||
assert 'StreamSpecification' not in resp['TableDescription']
|
||||
|
||||
assert "StreamSpecification" not in resp["TableDescription"]
|
||||
|
||||
resp = conn.update_table(
|
||||
TableName='test-streams',
|
||||
StreamSpecification={
|
||||
'StreamViewType': 'KEYS_ONLY'
|
||||
}
|
||||
TableName="test-streams",
|
||||
StreamSpecification={"StreamViewType": "KEYS_ONLY", "StreamEnabled": True},
|
||||
)
|
||||
assert 'StreamSpecification' in resp['TableDescription']
|
||||
assert resp['TableDescription']['StreamSpecification'] == {
|
||||
'StreamEnabled': True,
|
||||
'StreamViewType': 'KEYS_ONLY'
|
||||
assert "StreamSpecification" in resp["TableDescription"]
|
||||
assert resp["TableDescription"]["StreamSpecification"] == {
|
||||
"StreamEnabled": True,
|
||||
"StreamViewType": "KEYS_ONLY",
|
||||
}
|
||||
assert 'LatestStreamLabel' in resp['TableDescription']
|
||||
assert "LatestStreamLabel" in resp["TableDescription"]
|
||||
|
||||
# now try to enable it again
|
||||
with assert_raises(conn.exceptions.ResourceInUseException):
|
||||
resp = conn.update_table(
|
||||
TableName='test-streams',
|
||||
TableName="test-streams",
|
||||
StreamSpecification={
|
||||
'StreamViewType': 'OLD_IMAGES'
|
||||
}
|
||||
"StreamViewType": "OLD_IMAGES",
|
||||
"StreamEnabled": True,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_stream_with_range_key(self):
|
||||
dyn = boto3.client('dynamodb', region_name='us-east-1')
|
||||
dyn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
resp = dyn.create_table(
|
||||
TableName='test-streams',
|
||||
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'},
|
||||
{'AttributeName': 'color', 'KeyType': 'RANGE'}],
|
||||
AttributeDefinitions=[{'AttributeName': 'id',
|
||||
'AttributeType': 'S'},
|
||||
{'AttributeName': 'color',
|
||||
'AttributeType': 'S'}],
|
||||
ProvisionedThroughput={'ReadCapacityUnits': 1,
|
||||
'WriteCapacityUnits': 1},
|
||||
StreamSpecification={
|
||||
'StreamViewType': 'NEW_IMAGES'
|
||||
}
|
||||
TableName="test-streams",
|
||||
KeySchema=[
|
||||
{"AttributeName": "id", "KeyType": "HASH"},
|
||||
{"AttributeName": "color", "KeyType": "RANGE"},
|
||||
],
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "id", "AttributeType": "S"},
|
||||
{"AttributeName": "color", "AttributeType": "S"},
|
||||
],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1},
|
||||
StreamSpecification={"StreamViewType": "NEW_IMAGES", "StreamEnabled": True},
|
||||
)
|
||||
stream_arn = resp['TableDescription']['LatestStreamArn']
|
||||
stream_arn = resp["TableDescription"]["LatestStreamArn"]
|
||||
|
||||
streams = boto3.client('dynamodbstreams', region_name='us-east-1')
|
||||
streams = boto3.client("dynamodbstreams", region_name="us-east-1")
|
||||
resp = streams.describe_stream(StreamArn=stream_arn)
|
||||
shard_id = resp['StreamDescription']['Shards'][0]['ShardId']
|
||||
shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"]
|
||||
|
||||
resp = streams.get_shard_iterator(
|
||||
StreamArn=stream_arn,
|
||||
ShardId=shard_id,
|
||||
ShardIteratorType='LATEST'
|
||||
StreamArn=stream_arn, ShardId=shard_id, ShardIteratorType="LATEST"
|
||||
)
|
||||
iterator_id = resp['ShardIterator']
|
||||
iterator_id = resp["ShardIterator"]
|
||||
|
||||
dyn.put_item(
|
||||
TableName='test-streams',
|
||||
Item={'id': {'S': 'row1'}, 'color': {'S': 'blue'}}
|
||||
TableName="test-streams", Item={"id": {"S": "row1"}, "color": {"S": "blue"}}
|
||||
)
|
||||
dyn.put_item(
|
||||
TableName='test-streams',
|
||||
Item={'id': {'S': 'row2'}, 'color': {'S': 'green'}}
|
||||
TableName="test-streams",
|
||||
Item={"id": {"S": "row2"}, "color": {"S": "green"}},
|
||||
)
|
||||
|
||||
resp = streams.get_records(ShardIterator=iterator_id)
|
||||
assert len(resp['Records']) == 2
|
||||
assert resp['Records'][0]['eventName'] == 'INSERT'
|
||||
assert resp['Records'][1]['eventName'] == 'INSERT'
|
||||
|
||||
assert len(resp["Records"]) == 2
|
||||
assert resp["Records"][0]["eventName"] == "INSERT"
|
||||
assert resp["Records"][1]["eventName"] == "INSERT"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ def rsa_check_private_key(private_key_material):
|
|||
assert isinstance(private_key_material, six.string_types)
|
||||
|
||||
private_key = serialization.load_pem_private_key(
|
||||
data=private_key_material.encode('ascii'),
|
||||
data=private_key_material.encode("ascii"),
|
||||
backend=default_backend(),
|
||||
password=None)
|
||||
password=None,
|
||||
)
|
||||
assert isinstance(private_key, rsa.RSAPrivateKey)
|
||||
|
|
|
|||
|
|
@ -6,39 +6,32 @@ import sure # noqa
|
|||
|
||||
@mock_ec2
|
||||
def test_describe_account_attributes():
|
||||
conn = boto3.client('ec2', region_name='us-east-1')
|
||||
conn = boto3.client("ec2", region_name="us-east-1")
|
||||
response = conn.describe_account_attributes()
|
||||
expected_attribute_values = [{
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': '5'
|
||||
}],
|
||||
'AttributeName': 'vpc-max-security-groups-per-interface'
|
||||
}, {
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': '20'
|
||||
}],
|
||||
'AttributeName': 'max-instances'
|
||||
}, {
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': 'EC2'
|
||||
}, {
|
||||
'AttributeValue': 'VPC'
|
||||
}],
|
||||
'AttributeName': 'supported-platforms'
|
||||
}, {
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': 'none'
|
||||
}],
|
||||
'AttributeName': 'default-vpc'
|
||||
}, {
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': '5'
|
||||
}],
|
||||
'AttributeName': 'max-elastic-ips'
|
||||
}, {
|
||||
'AttributeValues': [{
|
||||
'AttributeValue': '5'
|
||||
}],
|
||||
'AttributeName': 'vpc-max-elastic-ips'
|
||||
}]
|
||||
response['AccountAttributes'].should.equal(expected_attribute_values)
|
||||
expected_attribute_values = [
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "5"}],
|
||||
"AttributeName": "vpc-max-security-groups-per-interface",
|
||||
},
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "20"}],
|
||||
"AttributeName": "max-instances",
|
||||
},
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "EC2"}, {"AttributeValue": "VPC"}],
|
||||
"AttributeName": "supported-platforms",
|
||||
},
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "none"}],
|
||||
"AttributeName": "default-vpc",
|
||||
},
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "5"}],
|
||||
"AttributeName": "max-elastic-ips",
|
||||
},
|
||||
{
|
||||
"AttributeValues": [{"AttributeValue": "5"}],
|
||||
"AttributeName": "vpc-max-elastic-ips",
|
||||
},
|
||||
]
|
||||
response["AccountAttributes"].should.equal(expected_attribute_values)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,54 +1,54 @@
|
|||
from __future__ import unicode_literals
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_regions():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
regions = conn.get_all_regions()
|
||||
regions.should.have.length_of(16)
|
||||
for region in regions:
|
||||
region.endpoint.should.contain(region.name)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_availability_zones():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
regions = conn.get_all_regions()
|
||||
for region in regions:
|
||||
conn = boto.ec2.connect_to_region(region.name)
|
||||
if conn is None:
|
||||
continue
|
||||
for zone in conn.get_all_zones():
|
||||
zone.name.should.contain(region.name)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_boto3_describe_regions():
|
||||
ec2 = boto3.client('ec2', 'us-east-1')
|
||||
resp = ec2.describe_regions()
|
||||
resp['Regions'].should.have.length_of(16)
|
||||
for rec in resp['Regions']:
|
||||
rec['Endpoint'].should.contain(rec['RegionName'])
|
||||
|
||||
test_region = 'us-east-1'
|
||||
resp = ec2.describe_regions(RegionNames=[test_region])
|
||||
resp['Regions'].should.have.length_of(1)
|
||||
resp['Regions'][0].should.have.key('RegionName').which.should.equal(test_region)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_boto3_availability_zones():
|
||||
ec2 = boto3.client('ec2', 'us-east-1')
|
||||
resp = ec2.describe_regions()
|
||||
regions = [r['RegionName'] for r in resp['Regions']]
|
||||
for region in regions:
|
||||
conn = boto3.client('ec2', region)
|
||||
resp = conn.describe_availability_zones()
|
||||
for rec in resp['AvailabilityZones']:
|
||||
rec['ZoneName'].should.contain(region)
|
||||
from __future__ import unicode_literals
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_regions():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
regions = conn.get_all_regions()
|
||||
regions.should.have.length_of(16)
|
||||
for region in regions:
|
||||
region.endpoint.should.contain(region.name)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_availability_zones():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
regions = conn.get_all_regions()
|
||||
for region in regions:
|
||||
conn = boto.ec2.connect_to_region(region.name)
|
||||
if conn is None:
|
||||
continue
|
||||
for zone in conn.get_all_zones():
|
||||
zone.name.should.contain(region.name)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_boto3_describe_regions():
|
||||
ec2 = boto3.client("ec2", "us-east-1")
|
||||
resp = ec2.describe_regions()
|
||||
resp["Regions"].should.have.length_of(16)
|
||||
for rec in resp["Regions"]:
|
||||
rec["Endpoint"].should.contain(rec["RegionName"])
|
||||
|
||||
test_region = "us-east-1"
|
||||
resp = ec2.describe_regions(RegionNames=[test_region])
|
||||
resp["Regions"].should.have.length_of(1)
|
||||
resp["Regions"][0].should.have.key("RegionName").which.should.equal(test_region)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_boto3_availability_zones():
|
||||
ec2 = boto3.client("ec2", "us-east-1")
|
||||
resp = ec2.describe_regions()
|
||||
regions = [r["RegionName"] for r in resp["Regions"]]
|
||||
for region in regions:
|
||||
conn = boto3.client("ec2", region)
|
||||
resp = conn.describe_availability_zones()
|
||||
for rec in resp["AvailabilityZones"]:
|
||||
rec["ZoneName"].should.contain(region)
|
||||
|
|
|
|||
|
|
@ -1,52 +1,49 @@
|
|||
from __future__ import unicode_literals
|
||||
import boto
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
from nose.tools import assert_false
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_customer_gateways():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
customer_gateway = conn.create_customer_gateway(
|
||||
'ipsec.1', '205.251.242.54', 65534)
|
||||
customer_gateway.should_not.be.none
|
||||
customer_gateway.id.should.match(r'cgw-\w+')
|
||||
customer_gateway.type.should.equal('ipsec.1')
|
||||
customer_gateway.bgp_asn.should.equal(65534)
|
||||
customer_gateway.ip_address.should.equal('205.251.242.54')
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_customer_gateways():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
customer_gateway = conn.create_customer_gateway(
|
||||
'ipsec.1', '205.251.242.54', 65534)
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws.should.have.length_of(1)
|
||||
cgws[0].id.should.match(customer_gateway.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_customer_gateways():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
customer_gateway = conn.create_customer_gateway(
|
||||
'ipsec.1', '205.251.242.54', 65534)
|
||||
customer_gateway.should_not.be.none
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws[0].id.should.match(customer_gateway.id)
|
||||
deleted = conn.delete_customer_gateway(customer_gateway.id)
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_customer_gateways_bad_id():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_customer_gateway('cgw-0123abcd')
|
||||
from __future__ import unicode_literals
|
||||
import boto
|
||||
import sure # noqa
|
||||
from nose.tools import assert_raises
|
||||
from nose.tools import assert_false
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_customer_gateways():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
|
||||
customer_gateway.should_not.be.none
|
||||
customer_gateway.id.should.match(r"cgw-\w+")
|
||||
customer_gateway.type.should.equal("ipsec.1")
|
||||
customer_gateway.bgp_asn.should.equal(65534)
|
||||
customer_gateway.ip_address.should.equal("205.251.242.54")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_customer_gateways():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws.should.have.length_of(1)
|
||||
cgws[0].id.should.match(customer_gateway.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_customer_gateways():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
|
||||
customer_gateway.should_not.be.none
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws[0].id.should.match(customer_gateway.id)
|
||||
deleted = conn.delete_customer_gateway(customer_gateway.id)
|
||||
cgws = conn.get_all_customer_gateways()
|
||||
cgws.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_customer_gateways_bad_id():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_customer_gateway("cgw-0123abcd")
|
||||
|
|
|
|||
|
|
@ -1,333 +1,337 @@
|
|||
from __future__ import unicode_literals
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import boto3
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
SAMPLE_DOMAIN_NAME = u'example.com'
|
||||
SAMPLE_NAME_SERVERS = [u'10.0.0.6', u'10.0.0.7']
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate():
|
||||
""" associate dhcp option """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
dhcp_options = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
rval = conn.associate_dhcp_options(dhcp_options.id, vpc.id)
|
||||
rval.should.be.equal(True)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate_invalid_dhcp_id():
|
||||
""" associate dhcp option bad dhcp options id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_dhcp_options("foo", vpc.id)
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate_invalid_vpc_id():
|
||||
""" associate dhcp option invalid vpc id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
dhcp_options = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_dhcp_options(dhcp_options.id, "foo")
|
||||
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_delete_with_vpc():
|
||||
"""Test deletion of dhcp options with vpc"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
dhcp_options = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_options_id = dhcp_options.id
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
rval = conn.associate_dhcp_options(dhcp_options_id, vpc.id)
|
||||
rval.should.be.equal(True)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options(dhcp_options_id)
|
||||
cm.exception.code.should.equal('DependencyViolation')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
vpc.delete()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options([dhcp_options_id])
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_dhcp_options():
|
||||
"""Create most basic dhcp option"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
dhcp_option = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_option.options[u'domain-name'][0].should.be.equal(SAMPLE_DOMAIN_NAME)
|
||||
dhcp_option.options[
|
||||
u'domain-name-servers'][0].should.be.equal(SAMPLE_NAME_SERVERS[0])
|
||||
dhcp_option.options[
|
||||
u'domain-name-servers'][1].should.be.equal(SAMPLE_NAME_SERVERS[1])
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_dhcp_options_invalid_options():
|
||||
"""Create invalid dhcp options"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
servers = ["f", "f", "f", "f", "f"]
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_dhcp_options(ntp_servers=servers)
|
||||
cm.exception.code.should.equal('InvalidParameterValue')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_dhcp_options(netbios_node_type="0")
|
||||
cm.exception.code.should.equal('InvalidParameterValue')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_dhcp_options():
|
||||
"""Test dhcp options lookup by id"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
dhcp_options = conn.get_all_dhcp_options()
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_dhcp_options_invalid_id():
|
||||
"""get error on invalid dhcp_option_id lookup"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options(["1"])
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options():
|
||||
"""delete dhcp option"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
conn.delete_dhcp_options(dhcp_option.id) # .should.be.equal(True)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options([dhcp_option.id])
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options_invalid_id():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
conn.create_dhcp_options()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options("dopt-abcd1234")
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options_malformed_id():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
conn.create_dhcp_options()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options("foo-abcd1234")
|
||||
cm.exception.code.should.equal('InvalidDhcpOptionsId.Malformed')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_tagging():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
|
||||
dhcp_option.add_tag("a key", "some value")
|
||||
|
||||
tag = conn.get_all_tags()[0]
|
||||
tag.name.should.equal("a key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
# Refresh the DHCP options
|
||||
dhcp_option = conn.get_all_dhcp_options()[0]
|
||||
dhcp_option.tags.should.have.length_of(1)
|
||||
dhcp_option.tags["a key"].should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_tag():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
dhcp1 = conn.create_dhcp_options('example.com', ['10.0.10.2'])
|
||||
dhcp1.add_tag('Name', 'TestDhcpOptions1')
|
||||
dhcp1.add_tag('test-tag', 'test-value')
|
||||
|
||||
dhcp2 = conn.create_dhcp_options('example.com', ['10.0.20.2'])
|
||||
dhcp2.add_tag('Name', 'TestDhcpOptions2')
|
||||
dhcp2.add_tag('test-tag', 'test-value')
|
||||
|
||||
filters = {'tag:Name': 'TestDhcpOptions1', 'tag:test-tag': 'test-value'}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name'][0].should.be.equal('example.com')
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name-servers'][0].should.be.equal('10.0.10.2')
|
||||
dhcp_options_sets[0].tags['Name'].should.equal('TestDhcpOptions1')
|
||||
dhcp_options_sets[0].tags['test-tag'].should.equal('test-value')
|
||||
|
||||
filters = {'tag:Name': 'TestDhcpOptions2', 'tag:test-tag': 'test-value'}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name'][0].should.be.equal('example.com')
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name-servers'][0].should.be.equal('10.0.20.2')
|
||||
dhcp_options_sets[0].tags['Name'].should.equal('TestDhcpOptions2')
|
||||
dhcp_options_sets[0].tags['test-tag'].should.equal('test-value')
|
||||
|
||||
filters = {'tag:test-tag': 'test-value'}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(2)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_id():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
dhcp1 = conn.create_dhcp_options('test1.com', ['10.0.10.2'])
|
||||
dhcp1.add_tag('Name', 'TestDhcpOptions1')
|
||||
dhcp1.add_tag('test-tag', 'test-value')
|
||||
dhcp1_id = dhcp1.id
|
||||
|
||||
dhcp2 = conn.create_dhcp_options('test2.com', ['10.0.20.2'])
|
||||
dhcp2.add_tag('Name', 'TestDhcpOptions2')
|
||||
dhcp2.add_tag('test-tag', 'test-value')
|
||||
dhcp2_id = dhcp2.id
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options()
|
||||
dhcp_options_sets.should.have.length_of(2)
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(
|
||||
filters={'dhcp-options-id': dhcp1_id})
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options['domain-name'][0].should.be.equal('test1.com')
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name-servers'][0].should.be.equal('10.0.10.2')
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(
|
||||
filters={'dhcp-options-id': dhcp2_id})
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options['domain-name'][0].should.be.equal('test2.com')
|
||||
dhcp_options_sets[0].options[
|
||||
'domain-name-servers'][0].should.be.equal('10.0.20.2')
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_dhcp_options_get_by_value_filter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.10.2']}
|
||||
])
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.20.2']}
|
||||
])
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.30.2']}
|
||||
])
|
||||
|
||||
filters = [{'Name': 'value', 'Values': ['10.0.10.2']}]
|
||||
dhcp_options_sets = list(ec2.dhcp_options_sets.filter(Filters=filters))
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_dhcp_options_get_by_key_filter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.10.2']}
|
||||
])
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.20.2']}
|
||||
])
|
||||
|
||||
ec2.create_dhcp_options(DhcpConfigurations=[
|
||||
{'Key': 'domain-name', 'Values': ['example.com']},
|
||||
{'Key': 'domain-name-servers', 'Values': ['10.0.30.2']}
|
||||
])
|
||||
|
||||
filters = [{'Name': 'key', 'Values': ['domain-name']}]
|
||||
dhcp_options_sets = list(ec2.dhcp_options_sets.filter(Filters=filters))
|
||||
dhcp_options_sets.should.have.length_of(3)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_invalid_filter():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
filters = {'invalid-filter': 'invalid-value'}
|
||||
|
||||
conn.get_all_dhcp_options.when.called_with(
|
||||
filters=filters).should.throw(NotImplementedError)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import boto3
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
SAMPLE_DOMAIN_NAME = "example.com"
|
||||
SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"]
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate():
|
||||
""" associate dhcp option """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
rval = conn.associate_dhcp_options(dhcp_options.id, vpc.id)
|
||||
rval.should.be.equal(True)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate_invalid_dhcp_id():
|
||||
""" associate dhcp option bad dhcp options id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_dhcp_options("foo", vpc.id)
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_associate_invalid_vpc_id():
|
||||
""" associate dhcp option invalid vpc id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_dhcp_options(dhcp_options.id, "foo")
|
||||
cm.exception.code.should.equal("InvalidVpcID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_delete_with_vpc():
|
||||
"""Test deletion of dhcp options with vpc"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_options_id = dhcp_options.id
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
rval = conn.associate_dhcp_options(dhcp_options_id, vpc.id)
|
||||
rval.should.be.equal(True)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options(dhcp_options_id)
|
||||
cm.exception.code.should.equal("DependencyViolation")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
vpc.delete()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options([dhcp_options_id])
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_dhcp_options():
|
||||
"""Create most basic dhcp option"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
dhcp_option = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_option.options["domain-name"][0].should.be.equal(SAMPLE_DOMAIN_NAME)
|
||||
dhcp_option.options["domain-name-servers"][0].should.be.equal(
|
||||
SAMPLE_NAME_SERVERS[0]
|
||||
)
|
||||
dhcp_option.options["domain-name-servers"][1].should.be.equal(
|
||||
SAMPLE_NAME_SERVERS[1]
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_dhcp_options_invalid_options():
|
||||
"""Create invalid dhcp options"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
servers = ["f", "f", "f", "f", "f"]
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_dhcp_options(ntp_servers=servers)
|
||||
cm.exception.code.should.equal("InvalidParameterValue")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_dhcp_options(netbios_node_type="0")
|
||||
cm.exception.code.should.equal("InvalidParameterValue")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_dhcp_options():
|
||||
"""Test dhcp options lookup by id"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
dhcp_options = conn.get_all_dhcp_options()
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_dhcp_options_invalid_id():
|
||||
"""get error on invalid dhcp_option_id lookup"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options(["1"])
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options():
|
||||
"""delete dhcp option"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
|
||||
dhcp_options.should.be.length_of(1)
|
||||
|
||||
conn.delete_dhcp_options(dhcp_option.id) # .should.be.equal(True)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_dhcp_options([dhcp_option.id])
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options_invalid_id():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
conn.create_dhcp_options()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options("dopt-abcd1234")
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_dhcp_options_malformed_id():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
conn.create_dhcp_options()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_dhcp_options("foo-abcd1234")
|
||||
cm.exception.code.should.equal("InvalidDhcpOptionsId.Malformed")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_tagging():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
dhcp_option = conn.create_dhcp_options()
|
||||
|
||||
dhcp_option.add_tag("a key", "some value")
|
||||
|
||||
tag = conn.get_all_tags()[0]
|
||||
tag.name.should.equal("a key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
# Refresh the DHCP options
|
||||
dhcp_option = conn.get_all_dhcp_options()[0]
|
||||
dhcp_option.tags.should.have.length_of(1)
|
||||
dhcp_option.tags["a key"].should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_tag():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
dhcp1 = conn.create_dhcp_options("example.com", ["10.0.10.2"])
|
||||
dhcp1.add_tag("Name", "TestDhcpOptions1")
|
||||
dhcp1.add_tag("test-tag", "test-value")
|
||||
|
||||
dhcp2 = conn.create_dhcp_options("example.com", ["10.0.20.2"])
|
||||
dhcp2.add_tag("Name", "TestDhcpOptions2")
|
||||
dhcp2.add_tag("test-tag", "test-value")
|
||||
|
||||
filters = {"tag:Name": "TestDhcpOptions1", "tag:test-tag": "test-value"}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("example.com")
|
||||
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.10.2")
|
||||
dhcp_options_sets[0].tags["Name"].should.equal("TestDhcpOptions1")
|
||||
dhcp_options_sets[0].tags["test-tag"].should.equal("test-value")
|
||||
|
||||
filters = {"tag:Name": "TestDhcpOptions2", "tag:test-tag": "test-value"}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("example.com")
|
||||
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.20.2")
|
||||
dhcp_options_sets[0].tags["Name"].should.equal("TestDhcpOptions2")
|
||||
dhcp_options_sets[0].tags["test-tag"].should.equal("test-value")
|
||||
|
||||
filters = {"tag:test-tag": "test-value"}
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
|
||||
|
||||
dhcp_options_sets.should.have.length_of(2)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_id():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
dhcp1 = conn.create_dhcp_options("test1.com", ["10.0.10.2"])
|
||||
dhcp1.add_tag("Name", "TestDhcpOptions1")
|
||||
dhcp1.add_tag("test-tag", "test-value")
|
||||
dhcp1_id = dhcp1.id
|
||||
|
||||
dhcp2 = conn.create_dhcp_options("test2.com", ["10.0.20.2"])
|
||||
dhcp2.add_tag("Name", "TestDhcpOptions2")
|
||||
dhcp2.add_tag("test-tag", "test-value")
|
||||
dhcp2_id = dhcp2.id
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options()
|
||||
dhcp_options_sets.should.have.length_of(2)
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters={"dhcp-options-id": dhcp1_id})
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("test1.com")
|
||||
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.10.2")
|
||||
|
||||
dhcp_options_sets = conn.get_all_dhcp_options(filters={"dhcp-options-id": dhcp2_id})
|
||||
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("test2.com")
|
||||
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.20.2")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_dhcp_options_get_by_value_filter():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.10.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.20.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.30.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
filters = [{"Name": "value", "Values": ["10.0.10.2"]}]
|
||||
dhcp_options_sets = list(ec2.dhcp_options_sets.filter(Filters=filters))
|
||||
dhcp_options_sets.should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_dhcp_options_get_by_key_filter():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.10.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.20.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
ec2.create_dhcp_options(
|
||||
DhcpConfigurations=[
|
||||
{"Key": "domain-name", "Values": ["example.com"]},
|
||||
{"Key": "domain-name-servers", "Values": ["10.0.30.2"]},
|
||||
]
|
||||
)
|
||||
|
||||
filters = [{"Name": "key", "Values": ["domain-name"]}]
|
||||
dhcp_options_sets = list(ec2.dhcp_options_sets.filter(Filters=filters))
|
||||
dhcp_options_sets.should.have.length_of(3)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_dhcp_options_get_by_invalid_filter():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
filters = {"invalid-filter": "invalid-value"}
|
||||
|
||||
conn.get_all_dhcp_options.when.called_with(filters=filters).should.throw(
|
||||
NotImplementedError
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -32,10 +33,11 @@ def test_create_and_delete_volume():
|
|||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
volume.delete(dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DeleteVolume operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the DeleteVolume operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
volume.delete()
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ def test_create_and_delete_volume():
|
|||
# Deleting something that was already deleted should throw an error
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
volume.delete()
|
||||
cm.exception.code.should.equal('InvalidVolume.NotFound')
|
||||
cm.exception.code.should.equal("InvalidVolume.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -56,10 +58,11 @@ def test_create_encrypted_volume_dryrun():
|
|||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.create_volume(80, "us-east-1a", encrypted=True, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
|
|
@ -69,10 +72,11 @@ def test_create_encrypted_volume():
|
|||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.create_volume(80, "us-east-1a", encrypted=True, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
all_volumes = [vol for vol in conn.get_all_volumes() if vol.id == volume.id]
|
||||
all_volumes[0].encrypted.should.be(True)
|
||||
|
|
@ -87,13 +91,13 @@ def test_filter_volume_by_id():
|
|||
vol1 = conn.get_all_volumes(volume_ids=volume3.id)
|
||||
vol1.should.have.length_of(1)
|
||||
vol1[0].size.should.equal(20)
|
||||
vol1[0].zone.should.equal('us-east-1c')
|
||||
vol1[0].zone.should.equal("us-east-1c")
|
||||
vol2 = conn.get_all_volumes(volume_ids=[volume1.id, volume2.id])
|
||||
vol2.should.have.length_of(2)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_volumes(volume_ids=['vol-does_not_exist'])
|
||||
cm.exception.code.should.equal('InvalidVolume.NotFound')
|
||||
conn.get_all_volumes(volume_ids=["vol-does_not_exist"])
|
||||
cm.exception.code.should.equal("InvalidVolume.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -102,7 +106,7 @@ def test_filter_volume_by_id():
|
|||
def test_volume_filters():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
instance.update()
|
||||
|
|
@ -111,142 +115,155 @@ def test_volume_filters():
|
|||
volume2 = conn.create_volume(36, "us-east-1b", encrypted=False)
|
||||
volume3 = conn.create_volume(20, "us-east-1c", encrypted=True)
|
||||
|
||||
snapshot = volume3.create_snapshot(description='testsnap')
|
||||
snapshot = volume3.create_snapshot(description="testsnap")
|
||||
volume4 = conn.create_volume(25, "us-east-1a", snapshot=snapshot)
|
||||
|
||||
conn.create_tags([volume1.id], {'testkey1': 'testvalue1'})
|
||||
conn.create_tags([volume2.id], {'testkey2': 'testvalue2'})
|
||||
conn.create_tags([volume1.id], {"testkey1": "testvalue1"})
|
||||
conn.create_tags([volume2.id], {"testkey2": "testvalue2"})
|
||||
|
||||
volume1.update()
|
||||
volume2.update()
|
||||
volume3.update()
|
||||
volume4.update()
|
||||
|
||||
block_mapping = instance.block_device_mapping['/dev/sda1']
|
||||
block_mapping = instance.block_device_mapping["/dev/sda1"]
|
||||
|
||||
volume_ids = (volume1.id, volume2.id, volume3.id, volume4.id, block_mapping.volume_id)
|
||||
|
||||
volumes_by_attach_time = conn.get_all_volumes(
|
||||
filters={'attachment.attach-time': block_mapping.attach_time})
|
||||
set([vol.id for vol in volumes_by_attach_time]
|
||||
).should.equal({block_mapping.volume_id})
|
||||
|
||||
volumes_by_attach_device = conn.get_all_volumes(
|
||||
filters={'attachment.device': '/dev/sda1'})
|
||||
set([vol.id for vol in volumes_by_attach_device]
|
||||
).should.equal({block_mapping.volume_id})
|
||||
|
||||
volumes_by_attach_instance_id = conn.get_all_volumes(
|
||||
filters={'attachment.instance-id': instance.id})
|
||||
set([vol.id for vol in volumes_by_attach_instance_id]
|
||||
).should.equal({block_mapping.volume_id})
|
||||
|
||||
volumes_by_attach_status = conn.get_all_volumes(
|
||||
filters={'attachment.status': 'attached'})
|
||||
set([vol.id for vol in volumes_by_attach_status]
|
||||
).should.equal({block_mapping.volume_id})
|
||||
|
||||
volumes_by_create_time = conn.get_all_volumes(
|
||||
filters={'create-time': volume4.create_time})
|
||||
set([vol.create_time for vol in volumes_by_create_time]
|
||||
).should.equal({volume4.create_time})
|
||||
|
||||
volumes_by_size = conn.get_all_volumes(filters={'size': volume2.size})
|
||||
set([vol.id for vol in volumes_by_size]).should.equal({volume2.id})
|
||||
|
||||
volumes_by_snapshot_id = conn.get_all_volumes(
|
||||
filters={'snapshot-id': snapshot.id})
|
||||
set([vol.id for vol in volumes_by_snapshot_id]
|
||||
).should.equal({volume4.id})
|
||||
|
||||
volumes_by_status = conn.get_all_volumes(filters={'status': 'in-use'})
|
||||
set([vol.id for vol in volumes_by_status]).should.equal(
|
||||
{block_mapping.volume_id})
|
||||
|
||||
volumes_by_id = conn.get_all_volumes(filters={'volume-id': volume1.id})
|
||||
set([vol.id for vol in volumes_by_id]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag_key = conn.get_all_volumes(filters={'tag-key': 'testkey1'})
|
||||
set([vol.id for vol in volumes_by_tag_key]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag_value = conn.get_all_volumes(
|
||||
filters={'tag-value': 'testvalue1'})
|
||||
set([vol.id for vol in volumes_by_tag_value]
|
||||
).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag = conn.get_all_volumes(
|
||||
filters={'tag:testkey1': 'testvalue1'})
|
||||
set([vol.id for vol in volumes_by_tag]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_unencrypted = conn.get_all_volumes(
|
||||
filters={'encrypted': 'false'})
|
||||
set([vol.id for vol in volumes_by_unencrypted if vol.id in volume_ids]).should.equal(
|
||||
{block_mapping.volume_id, volume2.id}
|
||||
volume_ids = (
|
||||
volume1.id,
|
||||
volume2.id,
|
||||
volume3.id,
|
||||
volume4.id,
|
||||
block_mapping.volume_id,
|
||||
)
|
||||
|
||||
volumes_by_encrypted = conn.get_all_volumes(filters={'encrypted': 'true'})
|
||||
volumes_by_attach_time = conn.get_all_volumes(
|
||||
filters={"attachment.attach-time": block_mapping.attach_time}
|
||||
)
|
||||
set([vol.id for vol in volumes_by_attach_time]).should.equal(
|
||||
{block_mapping.volume_id}
|
||||
)
|
||||
|
||||
volumes_by_attach_device = conn.get_all_volumes(
|
||||
filters={"attachment.device": "/dev/sda1"}
|
||||
)
|
||||
set([vol.id for vol in volumes_by_attach_device]).should.equal(
|
||||
{block_mapping.volume_id}
|
||||
)
|
||||
|
||||
volumes_by_attach_instance_id = conn.get_all_volumes(
|
||||
filters={"attachment.instance-id": instance.id}
|
||||
)
|
||||
set([vol.id for vol in volumes_by_attach_instance_id]).should.equal(
|
||||
{block_mapping.volume_id}
|
||||
)
|
||||
|
||||
volumes_by_attach_status = conn.get_all_volumes(
|
||||
filters={"attachment.status": "attached"}
|
||||
)
|
||||
set([vol.id for vol in volumes_by_attach_status]).should.equal(
|
||||
{block_mapping.volume_id}
|
||||
)
|
||||
|
||||
volumes_by_create_time = conn.get_all_volumes(
|
||||
filters={"create-time": volume4.create_time}
|
||||
)
|
||||
set([vol.create_time for vol in volumes_by_create_time]).should.equal(
|
||||
{volume4.create_time}
|
||||
)
|
||||
|
||||
volumes_by_size = conn.get_all_volumes(filters={"size": volume2.size})
|
||||
set([vol.id for vol in volumes_by_size]).should.equal({volume2.id})
|
||||
|
||||
volumes_by_snapshot_id = conn.get_all_volumes(filters={"snapshot-id": snapshot.id})
|
||||
set([vol.id for vol in volumes_by_snapshot_id]).should.equal({volume4.id})
|
||||
|
||||
volumes_by_status = conn.get_all_volumes(filters={"status": "in-use"})
|
||||
set([vol.id for vol in volumes_by_status]).should.equal({block_mapping.volume_id})
|
||||
|
||||
volumes_by_id = conn.get_all_volumes(filters={"volume-id": volume1.id})
|
||||
set([vol.id for vol in volumes_by_id]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag_key = conn.get_all_volumes(filters={"tag-key": "testkey1"})
|
||||
set([vol.id for vol in volumes_by_tag_key]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag_value = conn.get_all_volumes(filters={"tag-value": "testvalue1"})
|
||||
set([vol.id for vol in volumes_by_tag_value]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_tag = conn.get_all_volumes(filters={"tag:testkey1": "testvalue1"})
|
||||
set([vol.id for vol in volumes_by_tag]).should.equal({volume1.id})
|
||||
|
||||
volumes_by_unencrypted = conn.get_all_volumes(filters={"encrypted": "false"})
|
||||
set(
|
||||
[vol.id for vol in volumes_by_unencrypted if vol.id in volume_ids]
|
||||
).should.equal({block_mapping.volume_id, volume2.id})
|
||||
|
||||
volumes_by_encrypted = conn.get_all_volumes(filters={"encrypted": "true"})
|
||||
set([vol.id for vol in volumes_by_encrypted if vol.id in volume_ids]).should.equal(
|
||||
{volume1.id, volume3.id, volume4.id}
|
||||
)
|
||||
|
||||
volumes_by_availability_zone = conn.get_all_volumes(filters={'availability-zone': 'us-east-1b'})
|
||||
set([vol.id for vol in volumes_by_availability_zone if vol.id in volume_ids]).should.equal(
|
||||
{volume2.id}
|
||||
volumes_by_availability_zone = conn.get_all_volumes(
|
||||
filters={"availability-zone": "us-east-1b"}
|
||||
)
|
||||
set(
|
||||
[vol.id for vol in volumes_by_availability_zone if vol.id in volume_ids]
|
||||
).should.equal({volume2.id})
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_volume_attach_and_detach():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
volume = conn.create_volume(80, "us-east-1a")
|
||||
|
||||
volume.update()
|
||||
volume.volume_state().should.equal('available')
|
||||
volume.volume_state().should.equal("available")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
volume.attach(instance.id, "/dev/sdh", dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the AttachVolume operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the AttachVolume operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
volume.attach(instance.id, "/dev/sdh")
|
||||
|
||||
volume.update()
|
||||
volume.volume_state().should.equal('in-use')
|
||||
volume.attachment_state().should.equal('attached')
|
||||
volume.volume_state().should.equal("in-use")
|
||||
volume.attachment_state().should.equal("attached")
|
||||
|
||||
volume.attach_data.instance_id.should.equal(instance.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
volume.detach(dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DetachVolume operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the DetachVolume operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
volume.detach()
|
||||
|
||||
volume.update()
|
||||
volume.volume_state().should.equal('available')
|
||||
volume.volume_state().should.equal("available")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm1:
|
||||
volume.attach('i-1234abcd', "/dev/sdh")
|
||||
cm1.exception.code.should.equal('InvalidInstanceID.NotFound')
|
||||
volume.attach("i-1234abcd", "/dev/sdh")
|
||||
cm1.exception.code.should.equal("InvalidInstanceID.NotFound")
|
||||
cm1.exception.status.should.equal(400)
|
||||
cm1.exception.request_id.should_not.be.none
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm2:
|
||||
conn.detach_volume(volume.id, instance.id, "/dev/sdh")
|
||||
cm2.exception.code.should.equal('InvalidAttachment.NotFound')
|
||||
cm2.exception.code.should.equal("InvalidAttachment.NotFound")
|
||||
cm2.exception.status.should.equal(400)
|
||||
cm2.exception.request_id.should_not.be.none
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm3:
|
||||
conn.detach_volume(volume.id, 'i-1234abcd', "/dev/sdh")
|
||||
cm3.exception.code.should.equal('InvalidInstanceID.NotFound')
|
||||
conn.detach_volume(volume.id, "i-1234abcd", "/dev/sdh")
|
||||
cm3.exception.code.should.equal("InvalidInstanceID.NotFound")
|
||||
cm3.exception.status.should.equal(400)
|
||||
cm3.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -257,19 +274,20 @@ def test_create_snapshot():
|
|||
volume = conn.create_volume(80, "us-east-1a")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
snapshot = volume.create_snapshot('a dryrun snapshot', dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
snapshot = volume.create_snapshot("a dryrun snapshot", dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
snapshot = volume.create_snapshot('a test snapshot')
|
||||
snapshot = volume.create_snapshot("a test snapshot")
|
||||
snapshot.update()
|
||||
snapshot.status.should.equal('completed')
|
||||
snapshot.status.should.equal("completed")
|
||||
|
||||
snapshots = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
|
||||
snapshots.should.have.length_of(1)
|
||||
snapshots[0].description.should.equal('a test snapshot')
|
||||
snapshots[0].description.should.equal("a test snapshot")
|
||||
snapshots[0].start_time.should_not.be.none
|
||||
snapshots[0].encrypted.should.be(False)
|
||||
|
||||
|
|
@ -285,7 +303,7 @@ def test_create_snapshot():
|
|||
# Deleting something that was already deleted should throw an error
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
snapshot.delete()
|
||||
cm.exception.code.should.equal('InvalidSnapshot.NotFound')
|
||||
cm.exception.code.should.equal("InvalidSnapshot.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -294,13 +312,13 @@ def test_create_snapshot():
|
|||
def test_create_encrypted_snapshot():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
|
||||
snapshot = volume.create_snapshot('a test snapshot')
|
||||
snapshot = volume.create_snapshot("a test snapshot")
|
||||
snapshot.update()
|
||||
snapshot.status.should.equal('completed')
|
||||
snapshot.status.should.equal("completed")
|
||||
|
||||
snapshots = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
|
||||
snapshots.should.have.length_of(1)
|
||||
snapshots[0].description.should.equal('a test snapshot')
|
||||
snapshots[0].description.should.equal("a test snapshot")
|
||||
snapshots[0].start_time.should_not.be.none
|
||||
snapshots[0].encrypted.should.be(True)
|
||||
|
||||
|
|
@ -309,11 +327,11 @@ def test_create_encrypted_snapshot():
|
|||
def test_filter_snapshot_by_id():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
volume1 = conn.create_volume(36, "us-east-1a")
|
||||
snap1 = volume1.create_snapshot('a test snapshot 1')
|
||||
volume2 = conn.create_volume(42, 'us-east-1a')
|
||||
snap2 = volume2.create_snapshot('a test snapshot 2')
|
||||
volume3 = conn.create_volume(84, 'us-east-1a')
|
||||
snap3 = volume3.create_snapshot('a test snapshot 3')
|
||||
snap1 = volume1.create_snapshot("a test snapshot 1")
|
||||
volume2 = conn.create_volume(42, "us-east-1a")
|
||||
snap2 = volume2.create_snapshot("a test snapshot 2")
|
||||
volume3 = conn.create_volume(84, "us-east-1a")
|
||||
snap3 = volume3.create_snapshot("a test snapshot 3")
|
||||
snapshots1 = conn.get_all_snapshots(snapshot_ids=snap2.id)
|
||||
snapshots1.should.have.length_of(1)
|
||||
snapshots1[0].volume_id.should.equal(volume2.id)
|
||||
|
|
@ -326,8 +344,8 @@ def test_filter_snapshot_by_id():
|
|||
s.region.name.should.equal(conn.region.name)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_snapshots(snapshot_ids=['snap-does_not_exist'])
|
||||
cm.exception.code.should.equal('InvalidSnapshot.NotFound')
|
||||
conn.get_all_snapshots(snapshot_ids=["snap-does_not_exist"])
|
||||
cm.exception.code.should.equal("InvalidSnapshot.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -338,67 +356,62 @@ def test_snapshot_filters():
|
|||
volume1 = conn.create_volume(20, "us-east-1a", encrypted=False)
|
||||
volume2 = conn.create_volume(25, "us-east-1a", encrypted=True)
|
||||
|
||||
snapshot1 = volume1.create_snapshot(description='testsnapshot1')
|
||||
snapshot2 = volume1.create_snapshot(description='testsnapshot2')
|
||||
snapshot3 = volume2.create_snapshot(description='testsnapshot3')
|
||||
snapshot1 = volume1.create_snapshot(description="testsnapshot1")
|
||||
snapshot2 = volume1.create_snapshot(description="testsnapshot2")
|
||||
snapshot3 = volume2.create_snapshot(description="testsnapshot3")
|
||||
|
||||
conn.create_tags([snapshot1.id], {'testkey1': 'testvalue1'})
|
||||
conn.create_tags([snapshot2.id], {'testkey2': 'testvalue2'})
|
||||
conn.create_tags([snapshot1.id], {"testkey1": "testvalue1"})
|
||||
conn.create_tags([snapshot2.id], {"testkey2": "testvalue2"})
|
||||
|
||||
snapshots_by_description = conn.get_all_snapshots(
|
||||
filters={'description': 'testsnapshot1'})
|
||||
set([snap.id for snap in snapshots_by_description]
|
||||
).should.equal({snapshot1.id})
|
||||
filters={"description": "testsnapshot1"}
|
||||
)
|
||||
set([snap.id for snap in snapshots_by_description]).should.equal({snapshot1.id})
|
||||
|
||||
snapshots_by_id = conn.get_all_snapshots(
|
||||
filters={'snapshot-id': snapshot1.id})
|
||||
set([snap.id for snap in snapshots_by_id]
|
||||
).should.equal({snapshot1.id})
|
||||
snapshots_by_id = conn.get_all_snapshots(filters={"snapshot-id": snapshot1.id})
|
||||
set([snap.id for snap in snapshots_by_id]).should.equal({snapshot1.id})
|
||||
|
||||
snapshots_by_start_time = conn.get_all_snapshots(
|
||||
filters={'start-time': snapshot1.start_time})
|
||||
set([snap.start_time for snap in snapshots_by_start_time]
|
||||
).should.equal({snapshot1.start_time})
|
||||
filters={"start-time": snapshot1.start_time}
|
||||
)
|
||||
set([snap.start_time for snap in snapshots_by_start_time]).should.equal(
|
||||
{snapshot1.start_time}
|
||||
)
|
||||
|
||||
snapshots_by_volume_id = conn.get_all_snapshots(
|
||||
filters={'volume-id': volume1.id})
|
||||
set([snap.id for snap in snapshots_by_volume_id]
|
||||
).should.equal({snapshot1.id, snapshot2.id})
|
||||
snapshots_by_volume_id = conn.get_all_snapshots(filters={"volume-id": volume1.id})
|
||||
set([snap.id for snap in snapshots_by_volume_id]).should.equal(
|
||||
{snapshot1.id, snapshot2.id}
|
||||
)
|
||||
|
||||
snapshots_by_status = conn.get_all_snapshots(
|
||||
filters={'status': 'completed'})
|
||||
({snapshot1.id, snapshot2.id, snapshot3.id} -
|
||||
{snap.id for snap in snapshots_by_status}).should.have.length_of(0)
|
||||
snapshots_by_status = conn.get_all_snapshots(filters={"status": "completed"})
|
||||
(
|
||||
{snapshot1.id, snapshot2.id, snapshot3.id}
|
||||
- {snap.id for snap in snapshots_by_status}
|
||||
).should.have.length_of(0)
|
||||
|
||||
snapshots_by_volume_size = conn.get_all_snapshots(
|
||||
filters={'volume-size': volume1.size})
|
||||
set([snap.id for snap in snapshots_by_volume_size]
|
||||
).should.equal({snapshot1.id, snapshot2.id})
|
||||
filters={"volume-size": volume1.size}
|
||||
)
|
||||
set([snap.id for snap in snapshots_by_volume_size]).should.equal(
|
||||
{snapshot1.id, snapshot2.id}
|
||||
)
|
||||
|
||||
snapshots_by_tag_key = conn.get_all_snapshots(
|
||||
filters={'tag-key': 'testkey1'})
|
||||
set([snap.id for snap in snapshots_by_tag_key]
|
||||
).should.equal({snapshot1.id})
|
||||
snapshots_by_tag_key = conn.get_all_snapshots(filters={"tag-key": "testkey1"})
|
||||
set([snap.id for snap in snapshots_by_tag_key]).should.equal({snapshot1.id})
|
||||
|
||||
snapshots_by_tag_value = conn.get_all_snapshots(
|
||||
filters={'tag-value': 'testvalue1'})
|
||||
set([snap.id for snap in snapshots_by_tag_value]
|
||||
).should.equal({snapshot1.id})
|
||||
snapshots_by_tag_value = conn.get_all_snapshots(filters={"tag-value": "testvalue1"})
|
||||
set([snap.id for snap in snapshots_by_tag_value]).should.equal({snapshot1.id})
|
||||
|
||||
snapshots_by_tag = conn.get_all_snapshots(
|
||||
filters={'tag:testkey1': 'testvalue1'})
|
||||
set([snap.id for snap in snapshots_by_tag]
|
||||
).should.equal({snapshot1.id})
|
||||
snapshots_by_tag = conn.get_all_snapshots(filters={"tag:testkey1": "testvalue1"})
|
||||
set([snap.id for snap in snapshots_by_tag]).should.equal({snapshot1.id})
|
||||
|
||||
snapshots_by_encrypted = conn.get_all_snapshots(
|
||||
filters={'encrypted': 'true'})
|
||||
set([snap.id for snap in snapshots_by_encrypted]
|
||||
).should.equal({snapshot3.id})
|
||||
snapshots_by_encrypted = conn.get_all_snapshots(filters={"encrypted": "true"})
|
||||
set([snap.id for snap in snapshots_by_encrypted]).should.equal({snapshot3.id})
|
||||
|
||||
snapshots_by_owner_id = conn.get_all_snapshots(
|
||||
filters={'owner-id': OWNER_ID})
|
||||
set([snap.id for snap in snapshots_by_owner_id]
|
||||
).should.equal({snapshot1.id, snapshot2.id, snapshot3.id})
|
||||
snapshots_by_owner_id = conn.get_all_snapshots(filters={"owner-id": OWNER_ID})
|
||||
set([snap.id for snap in snapshots_by_owner_id]).should.equal(
|
||||
{snapshot1.id, snapshot2.id, snapshot3.id}
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
|
|
@ -411,119 +424,139 @@ def test_snapshot_attribute():
|
|||
|
||||
# Baseline
|
||||
attributes = conn.get_snapshot_attribute(
|
||||
snapshot.id, attribute='createVolumePermission')
|
||||
attributes.name.should.equal('create_volume_permission')
|
||||
snapshot.id, attribute="createVolumePermission"
|
||||
)
|
||||
attributes.name.should.equal("create_volume_permission")
|
||||
attributes.attrs.should.have.length_of(0)
|
||||
|
||||
ADD_GROUP_ARGS = {'snapshot_id': snapshot.id,
|
||||
'attribute': 'createVolumePermission',
|
||||
'operation': 'add',
|
||||
'groups': 'all'}
|
||||
ADD_GROUP_ARGS = {
|
||||
"snapshot_id": snapshot.id,
|
||||
"attribute": "createVolumePermission",
|
||||
"operation": "add",
|
||||
"groups": "all",
|
||||
}
|
||||
|
||||
REMOVE_GROUP_ARGS = {'snapshot_id': snapshot.id,
|
||||
'attribute': 'createVolumePermission',
|
||||
'operation': 'remove',
|
||||
'groups': 'all'}
|
||||
REMOVE_GROUP_ARGS = {
|
||||
"snapshot_id": snapshot.id,
|
||||
"attribute": "createVolumePermission",
|
||||
"operation": "remove",
|
||||
"groups": "all",
|
||||
}
|
||||
|
||||
# Add 'all' group and confirm
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.modify_snapshot_attribute(
|
||||
**dict(ADD_GROUP_ARGS, **{'dry_run': True}))
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
conn.modify_snapshot_attribute(**dict(ADD_GROUP_ARGS, **{"dry_run": True}))
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.modify_snapshot_attribute(**ADD_GROUP_ARGS)
|
||||
|
||||
attributes = conn.get_snapshot_attribute(
|
||||
snapshot.id, attribute='createVolumePermission')
|
||||
attributes.attrs['groups'].should.have.length_of(1)
|
||||
attributes.attrs['groups'].should.equal(['all'])
|
||||
snapshot.id, attribute="createVolumePermission"
|
||||
)
|
||||
attributes.attrs["groups"].should.have.length_of(1)
|
||||
attributes.attrs["groups"].should.equal(["all"])
|
||||
|
||||
# Add is idempotent
|
||||
conn.modify_snapshot_attribute.when.called_with(
|
||||
**ADD_GROUP_ARGS).should_not.throw(EC2ResponseError)
|
||||
conn.modify_snapshot_attribute.when.called_with(**ADD_GROUP_ARGS).should_not.throw(
|
||||
EC2ResponseError
|
||||
)
|
||||
|
||||
# Remove 'all' group and confirm
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.modify_snapshot_attribute(
|
||||
**dict(REMOVE_GROUP_ARGS, **{'dry_run': True}))
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
conn.modify_snapshot_attribute(**dict(REMOVE_GROUP_ARGS, **{"dry_run": True}))
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.modify_snapshot_attribute(**REMOVE_GROUP_ARGS)
|
||||
|
||||
attributes = conn.get_snapshot_attribute(
|
||||
snapshot.id, attribute='createVolumePermission')
|
||||
snapshot.id, attribute="createVolumePermission"
|
||||
)
|
||||
attributes.attrs.should.have.length_of(0)
|
||||
|
||||
# Remove is idempotent
|
||||
conn.modify_snapshot_attribute.when.called_with(
|
||||
**REMOVE_GROUP_ARGS).should_not.throw(EC2ResponseError)
|
||||
**REMOVE_GROUP_ARGS
|
||||
).should_not.throw(EC2ResponseError)
|
||||
|
||||
# Error: Add with group != 'all'
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.modify_snapshot_attribute(snapshot.id,
|
||||
attribute='createVolumePermission',
|
||||
operation='add',
|
||||
groups='everyone')
|
||||
cm.exception.code.should.equal('InvalidAMIAttributeItemValue')
|
||||
conn.modify_snapshot_attribute(
|
||||
snapshot.id,
|
||||
attribute="createVolumePermission",
|
||||
operation="add",
|
||||
groups="everyone",
|
||||
)
|
||||
cm.exception.code.should.equal("InvalidAMIAttributeItemValue")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Add with invalid snapshot ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.modify_snapshot_attribute("snapshot-abcd1234",
|
||||
attribute='createVolumePermission',
|
||||
operation='add',
|
||||
groups='all')
|
||||
cm.exception.code.should.equal('InvalidSnapshot.NotFound')
|
||||
conn.modify_snapshot_attribute(
|
||||
"snapshot-abcd1234",
|
||||
attribute="createVolumePermission",
|
||||
operation="add",
|
||||
groups="all",
|
||||
)
|
||||
cm.exception.code.should.equal("InvalidSnapshot.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Remove with invalid snapshot ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.modify_snapshot_attribute("snapshot-abcd1234",
|
||||
attribute='createVolumePermission',
|
||||
operation='remove',
|
||||
groups='all')
|
||||
cm.exception.code.should.equal('InvalidSnapshot.NotFound')
|
||||
conn.modify_snapshot_attribute(
|
||||
"snapshot-abcd1234",
|
||||
attribute="createVolumePermission",
|
||||
operation="remove",
|
||||
groups="all",
|
||||
)
|
||||
cm.exception.code.should.equal("InvalidSnapshot.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Add or remove with user ID instead of group
|
||||
conn.modify_snapshot_attribute.when.called_with(snapshot.id,
|
||||
attribute='createVolumePermission',
|
||||
operation='add',
|
||||
user_ids=['user']).should.throw(NotImplementedError)
|
||||
conn.modify_snapshot_attribute.when.called_with(snapshot.id,
|
||||
attribute='createVolumePermission',
|
||||
operation='remove',
|
||||
user_ids=['user']).should.throw(NotImplementedError)
|
||||
conn.modify_snapshot_attribute.when.called_with(
|
||||
snapshot.id,
|
||||
attribute="createVolumePermission",
|
||||
operation="add",
|
||||
user_ids=["user"],
|
||||
).should.throw(NotImplementedError)
|
||||
conn.modify_snapshot_attribute.when.called_with(
|
||||
snapshot.id,
|
||||
attribute="createVolumePermission",
|
||||
operation="remove",
|
||||
user_ids=["user"],
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_volume_from_snapshot():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
volume = conn.create_volume(80, "us-east-1a")
|
||||
snapshot = volume.create_snapshot('a test snapshot')
|
||||
snapshot = volume.create_snapshot("a test snapshot")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
snapshot = volume.create_snapshot('a test snapshot', dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
snapshot = volume.create_snapshot("a test snapshot", dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
snapshot = volume.create_snapshot('a test snapshot')
|
||||
snapshot = volume.create_snapshot("a test snapshot")
|
||||
snapshot.update()
|
||||
snapshot.status.should.equal('completed')
|
||||
snapshot.status.should.equal("completed")
|
||||
|
||||
new_volume = snapshot.create_volume('us-east-1a')
|
||||
new_volume = snapshot.create_volume("us-east-1a")
|
||||
new_volume.size.should.equal(80)
|
||||
new_volume.snapshot_id.should.equal(snapshot.id)
|
||||
|
||||
|
|
@ -533,11 +566,11 @@ def test_create_volume_from_encrypted_snapshot():
|
|||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
|
||||
|
||||
snapshot = volume.create_snapshot('a test snapshot')
|
||||
snapshot = volume.create_snapshot("a test snapshot")
|
||||
snapshot.update()
|
||||
snapshot.status.should.equal('completed')
|
||||
snapshot.status.should.equal("completed")
|
||||
|
||||
new_volume = snapshot.create_volume('us-east-1a')
|
||||
new_volume = snapshot.create_volume("us-east-1a")
|
||||
new_volume.size.should.equal(80)
|
||||
new_volume.snapshot_id.should.equal(snapshot.id)
|
||||
new_volume.encrypted.should.be(True)
|
||||
|
|
@ -553,131 +586,133 @@ def test_modify_attribute_blockDeviceMapping():
|
|||
"""
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
|
||||
instance = reservation.instances[0]
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
instance.modify_attribute('blockDeviceMapping', {
|
||||
'/dev/sda1': True}, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
instance.modify_attribute(
|
||||
"blockDeviceMapping", {"/dev/sda1": True}, dry_run=True
|
||||
)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
instance.modify_attribute('blockDeviceMapping', {'/dev/sda1': True})
|
||||
instance.modify_attribute("blockDeviceMapping", {"/dev/sda1": True})
|
||||
|
||||
instance = ec2_backends[conn.region.name].get_instance(instance.id)
|
||||
instance.block_device_mapping.should.have.key('/dev/sda1')
|
||||
instance.block_device_mapping[
|
||||
'/dev/sda1'].delete_on_termination.should.be(True)
|
||||
instance.block_device_mapping.should.have.key("/dev/sda1")
|
||||
instance.block_device_mapping["/dev/sda1"].delete_on_termination.should.be(True)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_volume_tag_escaping():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
vol = conn.create_volume(10, 'us-east-1a')
|
||||
snapshot = conn.create_snapshot(vol.id, 'Desc')
|
||||
vol = conn.create_volume(10, "us-east-1a")
|
||||
snapshot = conn.create_snapshot(vol.id, "Desc")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
snapshot.add_tags({'key': '</closed>'}, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
snapshot.add_tags({"key": "</closed>"}, dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
snaps = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
|
||||
dict(snaps[0].tags).should_not.be.equal(
|
||||
{'key': '</closed>'})
|
||||
dict(snaps[0].tags).should_not.be.equal({"key": "</closed>"})
|
||||
|
||||
snapshot.add_tags({'key': '</closed>'})
|
||||
snapshot.add_tags({"key": "</closed>"})
|
||||
|
||||
snaps = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
|
||||
dict(snaps[0].tags).should.equal({'key': '</closed>'})
|
||||
dict(snaps[0].tags).should.equal({"key": "</closed>"})
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_volume_property_hidden_when_no_tags_exist():
|
||||
ec2_client = boto3.client('ec2', region_name='us-east-1')
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
volume_response = ec2_client.create_volume(
|
||||
Size=10,
|
||||
AvailabilityZone='us-east-1a'
|
||||
)
|
||||
volume_response = ec2_client.create_volume(Size=10, AvailabilityZone="us-east-1a")
|
||||
|
||||
volume_response.get('Tags').should.equal(None)
|
||||
volume_response.get("Tags").should.equal(None)
|
||||
|
||||
|
||||
@freeze_time
|
||||
@mock_ec2
|
||||
def test_copy_snapshot():
|
||||
ec2_client = boto3.client('ec2', region_name='eu-west-1')
|
||||
dest_ec2_client = boto3.client('ec2', region_name='eu-west-2')
|
||||
ec2_client = boto3.client("ec2", region_name="eu-west-1")
|
||||
dest_ec2_client = boto3.client("ec2", region_name="eu-west-2")
|
||||
|
||||
volume_response = ec2_client.create_volume(
|
||||
AvailabilityZone='eu-west-1a', Size=10
|
||||
)
|
||||
volume_response = ec2_client.create_volume(AvailabilityZone="eu-west-1a", Size=10)
|
||||
|
||||
create_snapshot_response = ec2_client.create_snapshot(
|
||||
VolumeId=volume_response['VolumeId']
|
||||
VolumeId=volume_response["VolumeId"]
|
||||
)
|
||||
|
||||
copy_snapshot_response = dest_ec2_client.copy_snapshot(
|
||||
SourceSnapshotId=create_snapshot_response['SnapshotId'],
|
||||
SourceRegion="eu-west-1"
|
||||
SourceSnapshotId=create_snapshot_response["SnapshotId"],
|
||||
SourceRegion="eu-west-1",
|
||||
)
|
||||
|
||||
ec2 = boto3.resource('ec2', region_name='eu-west-1')
|
||||
dest_ec2 = boto3.resource('ec2', region_name='eu-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="eu-west-1")
|
||||
dest_ec2 = boto3.resource("ec2", region_name="eu-west-2")
|
||||
|
||||
source = ec2.Snapshot(create_snapshot_response['SnapshotId'])
|
||||
dest = dest_ec2.Snapshot(copy_snapshot_response['SnapshotId'])
|
||||
source = ec2.Snapshot(create_snapshot_response["SnapshotId"])
|
||||
dest = dest_ec2.Snapshot(copy_snapshot_response["SnapshotId"])
|
||||
|
||||
attribs = ['data_encryption_key_id', 'encrypted',
|
||||
'kms_key_id', 'owner_alias', 'owner_id',
|
||||
'progress', 'state', 'state_message',
|
||||
'tags', 'volume_id', 'volume_size']
|
||||
attribs = [
|
||||
"data_encryption_key_id",
|
||||
"encrypted",
|
||||
"kms_key_id",
|
||||
"owner_alias",
|
||||
"owner_id",
|
||||
"progress",
|
||||
"state",
|
||||
"state_message",
|
||||
"tags",
|
||||
"volume_id",
|
||||
"volume_size",
|
||||
]
|
||||
|
||||
for attrib in attribs:
|
||||
getattr(source, attrib).should.equal(getattr(dest, attrib))
|
||||
|
||||
# Copy from non-existent source ID.
|
||||
with assert_raises(ClientError) as cm:
|
||||
create_snapshot_error = ec2_client.create_snapshot(
|
||||
VolumeId='vol-abcd1234'
|
||||
)
|
||||
cm.exception.response['Error']['Code'].should.equal('InvalidVolume.NotFound')
|
||||
cm.exception.response['Error']['Message'].should.equal("The volume 'vol-abcd1234' does not exist.")
|
||||
cm.exception.response['ResponseMetadata']['RequestId'].should_not.be.none
|
||||
cm.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
|
||||
create_snapshot_error = ec2_client.create_snapshot(VolumeId="vol-abcd1234")
|
||||
cm.exception.response["Error"]["Code"].should.equal("InvalidVolume.NotFound")
|
||||
cm.exception.response["Error"]["Message"].should.equal(
|
||||
"The volume 'vol-abcd1234' does not exist."
|
||||
)
|
||||
cm.exception.response["ResponseMetadata"]["RequestId"].should_not.be.none
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
# Copy from non-existent source region.
|
||||
with assert_raises(ClientError) as cm:
|
||||
copy_snapshot_response = dest_ec2_client.copy_snapshot(
|
||||
SourceSnapshotId=create_snapshot_response['SnapshotId'],
|
||||
SourceRegion="eu-west-2"
|
||||
SourceSnapshotId=create_snapshot_response["SnapshotId"],
|
||||
SourceRegion="eu-west-2",
|
||||
)
|
||||
cm.exception.response['Error']['Code'].should.equal('InvalidSnapshot.NotFound')
|
||||
cm.exception.response['Error']['Message'].should.be.none
|
||||
cm.exception.response['ResponseMetadata']['RequestId'].should_not.be.none
|
||||
cm.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
|
||||
cm.exception.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound")
|
||||
cm.exception.response["Error"]["Message"].should.be.none
|
||||
cm.exception.response["ResponseMetadata"]["RequestId"].should_not.be.none
|
||||
cm.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_search_for_many_snapshots():
|
||||
ec2_client = boto3.client('ec2', region_name='eu-west-1')
|
||||
ec2_client = boto3.client("ec2", region_name="eu-west-1")
|
||||
|
||||
volume_response = ec2_client.create_volume(
|
||||
AvailabilityZone='eu-west-1a', Size=10
|
||||
)
|
||||
volume_response = ec2_client.create_volume(AvailabilityZone="eu-west-1a", Size=10)
|
||||
|
||||
snapshot_ids = []
|
||||
for i in range(1, 20):
|
||||
create_snapshot_response = ec2_client.create_snapshot(
|
||||
VolumeId=volume_response['VolumeId']
|
||||
VolumeId=volume_response["VolumeId"]
|
||||
)
|
||||
snapshot_ids.append(create_snapshot_response['SnapshotId'])
|
||||
snapshot_ids.append(create_snapshot_response["SnapshotId"])
|
||||
|
||||
snapshots_response = ec2_client.describe_snapshots(
|
||||
SnapshotIds=snapshot_ids
|
||||
)
|
||||
snapshots_response = ec2_client.describe_snapshots(SnapshotIds=snapshot_ids)
|
||||
|
||||
assert len(snapshots_response['Snapshots']) == len(snapshot_ids)
|
||||
assert len(snapshots_response["Snapshots"]) == len(snapshot_ids)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -19,16 +20,17 @@ import json
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
eni = conn.create_network_interface(subnet.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateNetworkInterface operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
eni = conn.create_network_interface(subnet.id)
|
||||
|
||||
|
|
@ -37,14 +39,15 @@ def test_elastic_network_interfaces():
|
|||
eni = all_enis[0]
|
||||
eni.groups.should.have.length_of(0)
|
||||
eni.private_ip_addresses.should.have.length_of(1)
|
||||
eni.private_ip_addresses[0].private_ip_address.startswith('10.').should.be.true
|
||||
eni.private_ip_addresses[0].private_ip_address.startswith("10.").should.be.true
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.delete_network_interface(eni.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DeleteNetworkInterface operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the DeleteNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.delete_network_interface(eni.id)
|
||||
|
||||
|
|
@ -53,25 +56,25 @@ def test_elastic_network_interfaces():
|
|||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_network_interface(eni.id)
|
||||
cm.exception.error_code.should.equal('InvalidNetworkInterfaceID.NotFound')
|
||||
cm.exception.error_code.should.equal("InvalidNetworkInterfaceID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces_subnet_validation():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_network_interface("subnet-abcd1234")
|
||||
cm.exception.error_code.should.equal('InvalidSubnetID.NotFound')
|
||||
cm.exception.error_code.should.equal("InvalidSubnetID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces_with_private_ip():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
private_ip = "54.0.0.1"
|
||||
|
|
@ -89,15 +92,18 @@ def test_elastic_network_interfaces_with_private_ip():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces_with_groups():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
security_group1 = conn.create_security_group(
|
||||
'test security group #1', 'this is a test security group')
|
||||
"test security group #1", "this is a test security group"
|
||||
)
|
||||
security_group2 = conn.create_security_group(
|
||||
'test security group #2', 'this is a test security group')
|
||||
"test security group #2", "this is a test security group"
|
||||
)
|
||||
conn.create_network_interface(
|
||||
subnet.id, groups=[security_group1.id, security_group2.id])
|
||||
subnet.id, groups=[security_group1.id, security_group2.id]
|
||||
)
|
||||
|
||||
all_enis = conn.get_all_network_interfaces()
|
||||
all_enis.should.have.length_of(1)
|
||||
|
|
@ -105,19 +111,22 @@ def test_elastic_network_interfaces_with_groups():
|
|||
eni = all_enis[0]
|
||||
eni.groups.should.have.length_of(2)
|
||||
set([group.id for group in eni.groups]).should.equal(
|
||||
set([security_group1.id, security_group2.id]))
|
||||
set([security_group1.id, security_group2.id])
|
||||
)
|
||||
|
||||
|
||||
@requires_boto_gte("2.12.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces_modify_attribute():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
security_group1 = conn.create_security_group(
|
||||
'test security group #1', 'this is a test security group')
|
||||
"test security group #1", "this is a test security group"
|
||||
)
|
||||
security_group2 = conn.create_security_group(
|
||||
'test security group #2', 'this is a test security group')
|
||||
"test security group #2", "this is a test security group"
|
||||
)
|
||||
conn.create_network_interface(subnet.id, groups=[security_group1.id])
|
||||
|
||||
all_enis = conn.get_all_network_interfaces()
|
||||
|
|
@ -129,14 +138,15 @@ def test_elastic_network_interfaces_modify_attribute():
|
|||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.modify_network_interface_attribute(
|
||||
eni.id, 'groupset', [security_group2.id], dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
eni.id, "groupset", [security_group2.id], dry_run=True
|
||||
)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the ModifyNetworkInterface operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the ModifyNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.modify_network_interface_attribute(
|
||||
eni.id, 'groupset', [security_group2.id])
|
||||
conn.modify_network_interface_attribute(eni.id, "groupset", [security_group2.id])
|
||||
|
||||
all_enis = conn.get_all_network_interfaces()
|
||||
all_enis.should.have.length_of(1)
|
||||
|
|
@ -148,20 +158,22 @@ def test_elastic_network_interfaces_modify_attribute():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_elastic_network_interfaces_filtering():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
|
||||
security_group1 = conn.create_security_group(
|
||||
'test security group #1', 'this is a test security group')
|
||||
"test security group #1", "this is a test security group"
|
||||
)
|
||||
security_group2 = conn.create_security_group(
|
||||
'test security group #2', 'this is a test security group')
|
||||
"test security group #2", "this is a test security group"
|
||||
)
|
||||
|
||||
eni1 = conn.create_network_interface(
|
||||
subnet.id, groups=[security_group1.id, security_group2.id])
|
||||
eni2 = conn.create_network_interface(
|
||||
subnet.id, groups=[security_group1.id])
|
||||
eni3 = conn.create_network_interface(subnet.id, description='test description')
|
||||
subnet.id, groups=[security_group1.id, security_group2.id]
|
||||
)
|
||||
eni2 = conn.create_network_interface(subnet.id, groups=[security_group1.id])
|
||||
eni3 = conn.create_network_interface(subnet.id, description="test description")
|
||||
|
||||
all_enis = conn.get_all_network_interfaces()
|
||||
all_enis.should.have.length_of(3)
|
||||
|
|
@ -173,280 +185,322 @@ def test_elastic_network_interfaces_filtering():
|
|||
|
||||
# Filter by ENI ID
|
||||
enis_by_id = conn.get_all_network_interfaces(
|
||||
filters={'network-interface-id': eni1.id})
|
||||
filters={"network-interface-id": eni1.id}
|
||||
)
|
||||
enis_by_id.should.have.length_of(1)
|
||||
set([eni.id for eni in enis_by_id]).should.equal(set([eni1.id]))
|
||||
|
||||
# Filter by Security Group
|
||||
enis_by_group = conn.get_all_network_interfaces(
|
||||
filters={'group-id': security_group1.id})
|
||||
filters={"group-id": security_group1.id}
|
||||
)
|
||||
enis_by_group.should.have.length_of(2)
|
||||
set([eni.id for eni in enis_by_group]).should.equal(set([eni1.id, eni2.id]))
|
||||
|
||||
# Filter by ENI ID and Security Group
|
||||
enis_by_group = conn.get_all_network_interfaces(
|
||||
filters={'network-interface-id': eni1.id, 'group-id': security_group1.id})
|
||||
filters={"network-interface-id": eni1.id, "group-id": security_group1.id}
|
||||
)
|
||||
enis_by_group.should.have.length_of(1)
|
||||
set([eni.id for eni in enis_by_group]).should.equal(set([eni1.id]))
|
||||
|
||||
# Filter by Description
|
||||
enis_by_description = conn.get_all_network_interfaces(
|
||||
filters={'description': eni3.description })
|
||||
filters={"description": eni3.description}
|
||||
)
|
||||
enis_by_description.should.have.length_of(1)
|
||||
enis_by_description[0].description.should.equal(eni3.description)
|
||||
|
||||
# Unsupported filter
|
||||
conn.get_all_network_interfaces.when.called_with(
|
||||
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
|
||||
filters={"not-implemented-filter": "foobar"}
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_tag_name():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5"
|
||||
)
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
eni1.create_tags(Tags=[{'Key': 'Name', 'Value': 'eni1'}], DryRun=True)
|
||||
ex.exception.response['Error']['Code'].should.equal('DryRunOperation')
|
||||
ex.exception.response['ResponseMetadata'][
|
||||
'HTTPStatusCode'].should.equal(400)
|
||||
ex.exception.response['Error']['Message'].should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set')
|
||||
eni1.create_tags(Tags=[{"Key": "Name", "Value": "eni1"}], DryRun=True)
|
||||
ex.exception.response["Error"]["Code"].should.equal("DryRunOperation")
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
eni1.create_tags(Tags=[{'Key': 'Name', 'Value': 'eni1'}])
|
||||
eni1.create_tags(Tags=[{"Key": "Name", "Value": "eni1"}])
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
filters = [{'Name': 'tag:Name', 'Values': ['eni1']}]
|
||||
filters = [{"Name": "tag:Name", "Values": ["eni1"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'tag:Name', 'Values': ['wrong-name']}]
|
||||
filters = [{"Name": "tag:Name", "Values": ["wrong-name"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_availability_zone():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet1 = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
subnet2 = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.1.0/24', AvailabilityZone='us-west-2b')
|
||||
VpcId=vpc.id, CidrBlock="10.0.1.0/24", AvailabilityZone="us-west-2b"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet1.id, PrivateIpAddress='10.0.0.15')
|
||||
SubnetId=subnet1.id, PrivateIpAddress="10.0.0.15"
|
||||
)
|
||||
|
||||
eni2 = ec2.create_network_interface(
|
||||
SubnetId=subnet2.id, PrivateIpAddress='10.0.1.15')
|
||||
SubnetId=subnet2.id, PrivateIpAddress="10.0.1.15"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id, eni2.id])
|
||||
|
||||
filters = [{'Name': 'availability-zone', 'Values': ['us-west-2a']}]
|
||||
filters = [{"Name": "availability-zone", "Values": ["us-west-2a"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'availability-zone', 'Values': ['us-west-2c']}]
|
||||
filters = [{"Name": "availability-zone", "Values": ["us-west-2c"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_private_ip():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
filters = [{'Name': 'private-ip-address', 'Values': ['10.0.10.5']}]
|
||||
filters = [{"Name": "private-ip-address", "Values": ["10.0.10.5"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'private-ip-address', 'Values': ['10.0.10.10']}]
|
||||
filters = [{"Name": "private-ip-address", "Values": ["10.0.10.10"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
filters = [{'Name': 'addresses.private-ip-address', 'Values': ['10.0.10.5']}]
|
||||
filters = [{"Name": "addresses.private-ip-address", "Values": ["10.0.10.5"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'addresses.private-ip-address', 'Values': ['10.0.10.10']}]
|
||||
filters = [{"Name": "addresses.private-ip-address", "Values": ["10.0.10.10"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_vpc_id():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
filters = [{'Name': 'vpc-id', 'Values': [subnet.vpc_id]}]
|
||||
filters = [{"Name": "vpc-id", "Values": [subnet.vpc_id]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'vpc-id', 'Values': ['vpc-aaaa1111']}]
|
||||
filters = [{"Name": "vpc-id", "Values": ["vpc-aaaa1111"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_subnet_id():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
filters = [{'Name': 'subnet-id', 'Values': [subnet.id]}]
|
||||
filters = [{"Name": "subnet-id", "Values": [subnet.id]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'subnet-id', 'Values': ['subnet-aaaa1111']}]
|
||||
filters = [{"Name": "subnet-id", "Values": ["subnet-aaaa1111"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_get_by_description():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5', Description='test interface')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5", Description="test interface"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
filters = [{'Name': 'description', 'Values': [eni1.description]}]
|
||||
filters = [{"Name": "description", "Values": [eni1.description]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(1)
|
||||
|
||||
filters = [{'Name': 'description', 'Values': ['bad description']}]
|
||||
filters = [{"Name": "description", "Values": ["bad description"]}]
|
||||
enis = list(ec2.network_interfaces.filter(Filters=filters))
|
||||
enis.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-2')
|
||||
ec2_client = boto3.client('ec2', region_name='us-west-2')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-2")
|
||||
ec2_client = boto3.client("ec2", region_name="us-west-2")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-2a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
|
||||
)
|
||||
|
||||
eni1 = ec2.create_network_interface(
|
||||
SubnetId=subnet.id, PrivateIpAddress='10.0.10.5', Description='test interface')
|
||||
SubnetId=subnet.id, PrivateIpAddress="10.0.10.5", Description="test interface"
|
||||
)
|
||||
|
||||
# The status of the new interface should be 'available'
|
||||
waiter = ec2_client.get_waiter('network_interface_available')
|
||||
waiter = ec2_client.get_waiter("network_interface_available")
|
||||
waiter.wait(NetworkInterfaceIds=[eni1.id])
|
||||
|
||||
# Filter by network-interface-id
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'network-interface-id', 'Values': [eni1.id]}])
|
||||
response['NetworkInterfaces'].should.have.length_of(1)
|
||||
response['NetworkInterfaces'][0]['NetworkInterfaceId'].should.equal(eni1.id)
|
||||
response['NetworkInterfaces'][0]['PrivateIpAddress'].should.equal(eni1.private_ip_address)
|
||||
response['NetworkInterfaces'][0]['Description'].should.equal(eni1.description)
|
||||
Filters=[{"Name": "network-interface-id", "Values": [eni1.id]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(1)
|
||||
response["NetworkInterfaces"][0]["NetworkInterfaceId"].should.equal(eni1.id)
|
||||
response["NetworkInterfaces"][0]["PrivateIpAddress"].should.equal(
|
||||
eni1.private_ip_address
|
||||
)
|
||||
response["NetworkInterfaces"][0]["Description"].should.equal(eni1.description)
|
||||
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'network-interface-id', 'Values': ['bad-id']}])
|
||||
response['NetworkInterfaces'].should.have.length_of(0)
|
||||
Filters=[{"Name": "network-interface-id", "Values": ["bad-id"]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(0)
|
||||
|
||||
# Filter by private-ip-address
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'private-ip-address', 'Values': [eni1.private_ip_address]}])
|
||||
response['NetworkInterfaces'].should.have.length_of(1)
|
||||
response['NetworkInterfaces'][0]['NetworkInterfaceId'].should.equal(eni1.id)
|
||||
response['NetworkInterfaces'][0]['PrivateIpAddress'].should.equal(eni1.private_ip_address)
|
||||
response['NetworkInterfaces'][0]['Description'].should.equal(eni1.description)
|
||||
Filters=[{"Name": "private-ip-address", "Values": [eni1.private_ip_address]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(1)
|
||||
response["NetworkInterfaces"][0]["NetworkInterfaceId"].should.equal(eni1.id)
|
||||
response["NetworkInterfaces"][0]["PrivateIpAddress"].should.equal(
|
||||
eni1.private_ip_address
|
||||
)
|
||||
response["NetworkInterfaces"][0]["Description"].should.equal(eni1.description)
|
||||
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'private-ip-address', 'Values': ['11.11.11.11']}])
|
||||
response['NetworkInterfaces'].should.have.length_of(0)
|
||||
Filters=[{"Name": "private-ip-address", "Values": ["11.11.11.11"]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(0)
|
||||
|
||||
# Filter by sunet-id
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'subnet-id', 'Values': [eni1.subnet.id]}])
|
||||
response['NetworkInterfaces'].should.have.length_of(1)
|
||||
response['NetworkInterfaces'][0]['NetworkInterfaceId'].should.equal(eni1.id)
|
||||
response['NetworkInterfaces'][0]['PrivateIpAddress'].should.equal(eni1.private_ip_address)
|
||||
response['NetworkInterfaces'][0]['Description'].should.equal(eni1.description)
|
||||
Filters=[{"Name": "subnet-id", "Values": [eni1.subnet.id]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(1)
|
||||
response["NetworkInterfaces"][0]["NetworkInterfaceId"].should.equal(eni1.id)
|
||||
response["NetworkInterfaces"][0]["PrivateIpAddress"].should.equal(
|
||||
eni1.private_ip_address
|
||||
)
|
||||
response["NetworkInterfaces"][0]["Description"].should.equal(eni1.description)
|
||||
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'subnet-id', 'Values': ['sn-bad-id']}])
|
||||
response['NetworkInterfaces'].should.have.length_of(0)
|
||||
Filters=[{"Name": "subnet-id", "Values": ["sn-bad-id"]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(0)
|
||||
|
||||
# Filter by description
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'description', 'Values': [eni1.description]}])
|
||||
response['NetworkInterfaces'].should.have.length_of(1)
|
||||
response['NetworkInterfaces'][0]['NetworkInterfaceId'].should.equal(eni1.id)
|
||||
response['NetworkInterfaces'][0]['PrivateIpAddress'].should.equal(eni1.private_ip_address)
|
||||
response['NetworkInterfaces'][0]['Description'].should.equal(eni1.description)
|
||||
Filters=[{"Name": "description", "Values": [eni1.description]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(1)
|
||||
response["NetworkInterfaces"][0]["NetworkInterfaceId"].should.equal(eni1.id)
|
||||
response["NetworkInterfaces"][0]["PrivateIpAddress"].should.equal(
|
||||
eni1.private_ip_address
|
||||
)
|
||||
response["NetworkInterfaces"][0]["Description"].should.equal(eni1.description)
|
||||
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'description', 'Values': ['bad description']}])
|
||||
response['NetworkInterfaces'].should.have.length_of(0)
|
||||
Filters=[{"Name": "description", "Values": ["bad description"]}]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(0)
|
||||
|
||||
# Filter by multiple filters
|
||||
response = ec2_client.describe_network_interfaces(
|
||||
Filters=[{'Name': 'private-ip-address', 'Values': [eni1.private_ip_address]},
|
||||
{'Name': 'network-interface-id', 'Values': [eni1.id]},
|
||||
{'Name': 'subnet-id', 'Values': [eni1.subnet.id]}])
|
||||
response['NetworkInterfaces'].should.have.length_of(1)
|
||||
response['NetworkInterfaces'][0]['NetworkInterfaceId'].should.equal(eni1.id)
|
||||
response['NetworkInterfaces'][0]['PrivateIpAddress'].should.equal(eni1.private_ip_address)
|
||||
response['NetworkInterfaces'][0]['Description'].should.equal(eni1.description)
|
||||
Filters=[
|
||||
{"Name": "private-ip-address", "Values": [eni1.private_ip_address]},
|
||||
{"Name": "network-interface-id", "Values": [eni1.id]},
|
||||
{"Name": "subnet-id", "Values": [eni1.subnet.id]},
|
||||
]
|
||||
)
|
||||
response["NetworkInterfaces"].should.have.length_of(1)
|
||||
response["NetworkInterfaces"][0]["NetworkInterfaceId"].should.equal(eni1.id)
|
||||
response["NetworkInterfaces"][0]["PrivateIpAddress"].should.equal(
|
||||
eni1.private_ip_address
|
||||
)
|
||||
response["NetworkInterfaces"][0]["Description"].should.equal(eni1.description)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
|
|
@ -455,19 +509,19 @@ def test_elastic_network_interfaces_cloudformation():
|
|||
template = vpc_eni.template
|
||||
template_json = json.dumps(template)
|
||||
conn = boto.cloudformation.connect_to_region("us-west-1")
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=template_json,
|
||||
)
|
||||
conn.create_stack("test_stack", template_body=template_json)
|
||||
ec2_conn = boto.ec2.connect_to_region("us-west-1")
|
||||
eni = ec2_conn.get_all_network_interfaces()[0]
|
||||
eni.private_ip_addresses.should.have.length_of(1)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.describe_resources()
|
||||
cfn_eni = [resource for resource in resources if resource.resource_type ==
|
||||
'AWS::EC2::NetworkInterface'][0]
|
||||
cfn_eni = [
|
||||
resource
|
||||
for resource in resources
|
||||
if resource.resource_type == "AWS::EC2::NetworkInterface"
|
||||
][0]
|
||||
cfn_eni.physical_resource_id.should.equal(eni.id)
|
||||
|
||||
outputs = {output.key: output.value for output in stack.outputs}
|
||||
outputs['ENIIpAddress'].should.equal(eni.private_ip_addresses[0].private_ip_address)
|
||||
outputs["ENIIpAddress"].should.equal(eni.private_ip_addresses[0].private_ip_address)
|
||||
|
|
|
|||
|
|
@ -1,42 +1,41 @@
|
|||
from __future__ import unicode_literals
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_ec2
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_console_output():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
instance_id = reservation.instances[0].id
|
||||
output = conn.get_console_output(instance_id)
|
||||
output.output.should_not.equal(None)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_console_output_without_instance():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_console_output('i-1234abcd')
|
||||
cm.exception.code.should.equal('InvalidInstanceID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_console_output_boto3():
|
||||
conn = boto3.resource('ec2', 'us-east-1')
|
||||
instances = conn.create_instances(ImageId='ami-1234abcd',
|
||||
MinCount=1,
|
||||
MaxCount=1)
|
||||
|
||||
output = instances[0].console_output()
|
||||
output.get('Output').should_not.equal(None)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_ec2
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_console_output():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance_id = reservation.instances[0].id
|
||||
output = conn.get_console_output(instance_id)
|
||||
output.output.should_not.equal(None)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_console_output_without_instance():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_console_output("i-1234abcd")
|
||||
cm.exception.code.should.equal("InvalidInstanceID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_console_output_boto3():
|
||||
conn = boto3.resource("ec2", "us-east-1")
|
||||
instances = conn.create_instances(ImageId="ami-1234abcd", MinCount=1, MaxCount=1)
|
||||
|
||||
output = instances[0].console_output()
|
||||
output.get("Output").should_not.equal(None)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,269 +1,271 @@
|
|||
from __future__ import unicode_literals
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import re
|
||||
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
VPC_CIDR = "10.0.0.0/16"
|
||||
BAD_VPC = "vpc-deadbeef"
|
||||
BAD_IGW = "igw-deadbeef"
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_create():
|
||||
""" internet gateway create """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
igw = conn.create_internet_gateway(dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateInternetGateway operation: Request would have succeeded, but DryRun flag is set')
|
||||
|
||||
igw = conn.create_internet_gateway()
|
||||
conn.get_all_internet_gateways().should.have.length_of(1)
|
||||
igw.id.should.match(r'igw-[0-9a-f]+')
|
||||
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach():
|
||||
""" internet gateway attach """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.attach_internet_gateway(igw.id, vpc.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the AttachInternetGateway operation: Request would have succeeded, but DryRun flag is set')
|
||||
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments[0].vpc_id.should.be.equal(vpc.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach_bad_vpc():
|
||||
""" internet gateway fail to attach w/ bad vpc """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.attach_internet_gateway(igw.id, BAD_VPC)
|
||||
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach_twice():
|
||||
""" internet gateway fail to attach twice """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc1 = conn.create_vpc(VPC_CIDR)
|
||||
vpc2 = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc1.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.attach_internet_gateway(igw.id, vpc2.id)
|
||||
cm.exception.code.should.equal('Resource.AlreadyAssociated')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach():
|
||||
""" internet gateway detach"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.detach_internet_gateway(igw.id, vpc.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DetachInternetGateway operation: Request would have succeeded, but DryRun flag is set')
|
||||
|
||||
conn.detach_internet_gateway(igw.id, vpc.id)
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_wrong_vpc():
|
||||
""" internet gateway fail to detach w/ wrong vpc """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc1 = conn.create_vpc(VPC_CIDR)
|
||||
vpc2 = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc1.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, vpc2.id)
|
||||
cm.exception.code.should.equal('Gateway.NotAttached')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_invalid_vpc():
|
||||
""" internet gateway fail to detach w/ invalid vpc """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, BAD_VPC)
|
||||
cm.exception.code.should.equal('Gateway.NotAttached')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_unattached():
|
||||
""" internet gateway fail to detach unattached """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, vpc.id)
|
||||
cm.exception.code.should.equal('Gateway.NotAttached')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_delete():
|
||||
""" internet gateway delete"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
igw = conn.create_internet_gateway()
|
||||
conn.get_all_internet_gateways().should.have.length_of(1)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.delete_internet_gateway(igw.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DeleteInternetGateway operation: Request would have succeeded, but DryRun flag is set')
|
||||
|
||||
conn.delete_internet_gateway(igw.id)
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_delete_attached():
|
||||
""" internet gateway fail to delete attached """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_internet_gateway(igw.id)
|
||||
cm.exception.code.should.equal('DependencyViolation')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_desribe():
|
||||
""" internet gateway fetch by id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
igw = conn.create_internet_gateway()
|
||||
igw_by_search = conn.get_all_internet_gateways([igw.id])[0]
|
||||
igw.id.should.equal(igw_by_search.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_describe_bad_id():
|
||||
""" internet gateway fail to fetch by bad id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_internet_gateways([BAD_IGW])
|
||||
cm.exception.code.should.equal('InvalidInternetGatewayID.NotFound')
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_vpc_id():
|
||||
""" internet gateway filter by vpc id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw1.id, vpc.id)
|
||||
|
||||
result = conn.get_all_internet_gateways(
|
||||
filters={"attachment.vpc-id": vpc.id})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_tags():
|
||||
""" internet gateway filter by vpc id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
igw1.add_tag("tests", "yes")
|
||||
|
||||
result = conn.get_all_internet_gateways(filters={"tag:tests": "yes"})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_internet_gateway_id():
|
||||
""" internet gateway filter by internet gateway id """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
|
||||
result = conn.get_all_internet_gateways(
|
||||
filters={"internet-gateway-id": igw1.id})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_attachment_state():
|
||||
""" internet gateway filter by attachment state """
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw1.id, vpc.id)
|
||||
|
||||
result = conn.get_all_internet_gateways(
|
||||
filters={"attachment.state": "available"})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
||||
import re
|
||||
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
VPC_CIDR = "10.0.0.0/16"
|
||||
BAD_VPC = "vpc-deadbeef"
|
||||
BAD_IGW = "igw-deadbeef"
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_create():
|
||||
""" internet gateway create """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
igw = conn.create_internet_gateway(dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the CreateInternetGateway operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
igw = conn.create_internet_gateway()
|
||||
conn.get_all_internet_gateways().should.have.length_of(1)
|
||||
igw.id.should.match(r"igw-[0-9a-f]+")
|
||||
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach():
|
||||
""" internet gateway attach """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.attach_internet_gateway(igw.id, vpc.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the AttachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments[0].vpc_id.should.be.equal(vpc.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach_bad_vpc():
|
||||
""" internet gateway fail to attach w/ bad vpc """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.attach_internet_gateway(igw.id, BAD_VPC)
|
||||
cm.exception.code.should.equal("InvalidVpcID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_attach_twice():
|
||||
""" internet gateway fail to attach twice """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc1 = conn.create_vpc(VPC_CIDR)
|
||||
vpc2 = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc1.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.attach_internet_gateway(igw.id, vpc2.id)
|
||||
cm.exception.code.should.equal("Resource.AlreadyAssociated")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach():
|
||||
""" internet gateway detach"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.detach_internet_gateway(igw.id, vpc.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the DetachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.detach_internet_gateway(igw.id, vpc.id)
|
||||
igw = conn.get_all_internet_gateways()[0]
|
||||
igw.attachments.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_wrong_vpc():
|
||||
""" internet gateway fail to detach w/ wrong vpc """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc1 = conn.create_vpc(VPC_CIDR)
|
||||
vpc2 = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc1.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, vpc2.id)
|
||||
cm.exception.code.should.equal("Gateway.NotAttached")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_invalid_vpc():
|
||||
""" internet gateway fail to detach w/ invalid vpc """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, BAD_VPC)
|
||||
cm.exception.code.should.equal("Gateway.NotAttached")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_detach_unattached():
|
||||
""" internet gateway fail to detach unattached """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.detach_internet_gateway(igw.id, vpc.id)
|
||||
cm.exception.code.should.equal("Gateway.NotAttached")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_delete():
|
||||
""" internet gateway delete"""
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
igw = conn.create_internet_gateway()
|
||||
conn.get_all_internet_gateways().should.have.length_of(1)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.delete_internet_gateway(igw.id, dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the DeleteInternetGateway operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.delete_internet_gateway(igw.id)
|
||||
conn.get_all_internet_gateways().should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_delete_attached():
|
||||
""" internet gateway fail to delete attached """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw.id, vpc.id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_internet_gateway(igw.id)
|
||||
cm.exception.code.should.equal("DependencyViolation")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_desribe():
|
||||
""" internet gateway fetch by id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
igw = conn.create_internet_gateway()
|
||||
igw_by_search = conn.get_all_internet_gateways([igw.id])[0]
|
||||
igw.id.should.equal(igw_by_search.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_describe_bad_id():
|
||||
""" internet gateway fail to fetch by bad id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_internet_gateways([BAD_IGW])
|
||||
cm.exception.code.should.equal("InvalidInternetGatewayID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_vpc_id():
|
||||
""" internet gateway filter by vpc id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw1.id, vpc.id)
|
||||
|
||||
result = conn.get_all_internet_gateways(filters={"attachment.vpc-id": vpc.id})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_tags():
|
||||
""" internet gateway filter by vpc id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
igw1.add_tag("tests", "yes")
|
||||
|
||||
result = conn.get_all_internet_gateways(filters={"tag:tests": "yes"})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_internet_gateway_id():
|
||||
""" internet gateway filter by internet gateway id """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
|
||||
result = conn.get_all_internet_gateways(filters={"internet-gateway-id": igw1.id})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_igw_filter_by_attachment_state():
|
||||
""" internet gateway filter by attachment state """
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
igw1 = conn.create_internet_gateway()
|
||||
igw2 = conn.create_internet_gateway()
|
||||
vpc = conn.create_vpc(VPC_CIDR)
|
||||
conn.attach_internet_gateway(igw1.id, vpc.id)
|
||||
|
||||
result = conn.get_all_internet_gateways(filters={"attachment.state": "available"})
|
||||
result.should.have.length_of(1)
|
||||
result[0].id.should.equal(igw1.id)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -47,116 +48,119 @@ moto@github.com"""
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_empty():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
assert len(conn.get_all_key_pairs()) == 0
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_invalid_id():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_key_pairs('foo')
|
||||
cm.exception.code.should.equal('InvalidKeyPair.NotFound')
|
||||
conn.get_all_key_pairs("foo")
|
||||
cm.exception.code.should.equal("InvalidKeyPair.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_create():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.create_key_pair('foo', dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
conn.create_key_pair("foo", dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
kp = conn.create_key_pair('foo')
|
||||
kp = conn.create_key_pair("foo")
|
||||
rsa_check_private_key(kp.material)
|
||||
|
||||
kps = conn.get_all_key_pairs()
|
||||
assert len(kps) == 1
|
||||
assert kps[0].name == 'foo'
|
||||
assert kps[0].name == "foo"
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_create_two():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
kp1 = conn.create_key_pair('foo')
|
||||
kp1 = conn.create_key_pair("foo")
|
||||
rsa_check_private_key(kp1.material)
|
||||
|
||||
kp2 = conn.create_key_pair('bar')
|
||||
kp2 = conn.create_key_pair("bar")
|
||||
rsa_check_private_key(kp2.material)
|
||||
|
||||
assert kp1.material != kp2.material
|
||||
|
||||
kps = conn.get_all_key_pairs()
|
||||
kps.should.have.length_of(2)
|
||||
assert {i.name for i in kps} == {'foo', 'bar'}
|
||||
assert {i.name for i in kps} == {"foo", "bar"}
|
||||
|
||||
kps = conn.get_all_key_pairs('foo')
|
||||
kps = conn.get_all_key_pairs("foo")
|
||||
kps.should.have.length_of(1)
|
||||
kps[0].name.should.equal('foo')
|
||||
kps[0].name.should.equal("foo")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_create_exist():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn.create_key_pair('foo')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
conn.create_key_pair("foo")
|
||||
assert len(conn.get_all_key_pairs()) == 1
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_key_pair('foo')
|
||||
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
|
||||
conn.create_key_pair("foo")
|
||||
cm.exception.code.should.equal("InvalidKeyPair.Duplicate")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_delete_no_exist():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
assert len(conn.get_all_key_pairs()) == 0
|
||||
r = conn.delete_key_pair('foo')
|
||||
r = conn.delete_key_pair("foo")
|
||||
r.should.be.ok
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_delete_exist():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn.create_key_pair('foo')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
conn.create_key_pair("foo")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
r = conn.delete_key_pair('foo', dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
r = conn.delete_key_pair("foo", dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
r = conn.delete_key_pair('foo')
|
||||
r = conn.delete_key_pair("foo")
|
||||
r.should.be.ok
|
||||
assert len(conn.get_all_key_pairs()) == 0
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_import():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH, dry_run=True)
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
kp1 = conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH)
|
||||
assert kp1.name == 'foo'
|
||||
kp1 = conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH)
|
||||
assert kp1.name == "foo"
|
||||
assert kp1.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
|
||||
|
||||
kp2 = conn.import_key_pair('foo2', RSA_PUBLIC_KEY_RFC4716)
|
||||
assert kp2.name == 'foo2'
|
||||
kp2 = conn.import_key_pair("foo2", RSA_PUBLIC_KEY_RFC4716)
|
||||
assert kp2.name == "foo2"
|
||||
assert kp2.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
|
||||
|
||||
kps = conn.get_all_key_pairs()
|
||||
|
|
@ -167,58 +171,51 @@ def test_key_pairs_import():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_import_exist():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
kp = conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH)
|
||||
assert kp.name == 'foo'
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
kp = conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH)
|
||||
assert kp.name == "foo"
|
||||
assert len(conn.get_all_key_pairs()) == 1
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_key_pair('foo')
|
||||
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
|
||||
conn.create_key_pair("foo")
|
||||
cm.exception.code.should.equal("InvalidKeyPair.Duplicate")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pairs_invalid():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.import_key_pair('foo', b'')
|
||||
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
|
||||
conn.import_key_pair("foo", b"")
|
||||
ex.exception.error_code.should.equal("InvalidKeyPair.Format")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'Key is not in valid OpenSSH public key format')
|
||||
ex.exception.message.should.equal("Key is not in valid OpenSSH public key format")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.import_key_pair('foo', b'garbage')
|
||||
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
|
||||
conn.import_key_pair("foo", b"garbage")
|
||||
ex.exception.error_code.should.equal("InvalidKeyPair.Format")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'Key is not in valid OpenSSH public key format')
|
||||
ex.exception.message.should.equal("Key is not in valid OpenSSH public key format")
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.import_key_pair('foo', DSA_PUBLIC_KEY_OPENSSH)
|
||||
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
|
||||
conn.import_key_pair("foo", DSA_PUBLIC_KEY_OPENSSH)
|
||||
ex.exception.error_code.should.equal("InvalidKeyPair.Format")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'Key is not in valid OpenSSH public key format')
|
||||
ex.exception.message.should.equal("Key is not in valid OpenSSH public key format")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_key_pair_filters():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
|
||||
_ = conn.create_key_pair('kpfltr1')
|
||||
kp2 = conn.create_key_pair('kpfltr2')
|
||||
kp3 = conn.create_key_pair('kpfltr3')
|
||||
_ = conn.create_key_pair("kpfltr1")
|
||||
kp2 = conn.create_key_pair("kpfltr2")
|
||||
kp3 = conn.create_key_pair("kpfltr3")
|
||||
|
||||
kp_by_name = conn.get_all_key_pairs(
|
||||
filters={'key-name': 'kpfltr2'})
|
||||
set([kp.name for kp in kp_by_name]
|
||||
).should.equal(set([kp2.name]))
|
||||
kp_by_name = conn.get_all_key_pairs(filters={"key-name": "kpfltr2"})
|
||||
set([kp.name for kp in kp_by_name]).should.equal(set([kp2.name]))
|
||||
|
||||
kp_by_name = conn.get_all_key_pairs(
|
||||
filters={'fingerprint': kp3.fingerprint})
|
||||
set([kp.name for kp in kp_by_name]
|
||||
).should.equal(set([kp3.name]))
|
||||
kp_by_name = conn.get_all_key_pairs(filters={"fingerprint": kp3.fingerprint})
|
||||
set([kp.name for kp in kp_by_name]).should.equal(set([kp3.name]))
|
||||
|
|
|
|||
|
|
@ -13,16 +13,14 @@ def test_launch_template_create():
|
|||
|
||||
resp = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
|
||||
# the absolute minimum needed to create a template without other resources
|
||||
LaunchTemplateData={
|
||||
"TagSpecifications": [{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{
|
||||
"Key": "test",
|
||||
"Value": "value",
|
||||
}],
|
||||
}],
|
||||
"TagSpecifications": [
|
||||
{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{"Key": "test", "Value": "value"}],
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -36,18 +34,18 @@ def test_launch_template_create():
|
|||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"TagSpecifications": [{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{
|
||||
"Key": "test",
|
||||
"Value": "value",
|
||||
}],
|
||||
}],
|
||||
"TagSpecifications": [
|
||||
{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{"Key": "test", "Value": "value"}],
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
str(ex.exception).should.equal(
|
||||
'An error occurred (InvalidLaunchTemplateName.AlreadyExistsException) when calling the CreateLaunchTemplate operation: Launch template name already in use.')
|
||||
"An error occurred (InvalidLaunchTemplateName.AlreadyExistsException) when calling the CreateLaunchTemplate operation: Launch template name already in use."
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -55,29 +53,22 @@ def test_describe_launch_template_versions():
|
|||
template_data = {
|
||||
"ImageId": "ami-abc123",
|
||||
"DisableApiTermination": False,
|
||||
"TagSpecifications": [{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{
|
||||
"Key": "test",
|
||||
"Value": "value",
|
||||
}],
|
||||
}],
|
||||
"SecurityGroupIds": [
|
||||
"sg-1234",
|
||||
"sg-ab5678",
|
||||
"TagSpecifications": [
|
||||
{"ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}]}
|
||||
],
|
||||
"SecurityGroupIds": ["sg-1234", "sg-ab5678"],
|
||||
}
|
||||
|
||||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
create_resp = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData=template_data)
|
||||
LaunchTemplateName="test-template", LaunchTemplateData=template_data
|
||||
)
|
||||
|
||||
# test using name
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
Versions=['1'])
|
||||
LaunchTemplateName="test-template", Versions=["1"]
|
||||
)
|
||||
|
||||
templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]
|
||||
templ.should.equal(template_data)
|
||||
|
|
@ -85,7 +76,8 @@ def test_describe_launch_template_versions():
|
|||
# test using id
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateId=create_resp["LaunchTemplate"]["LaunchTemplateId"],
|
||||
Versions=['1'])
|
||||
Versions=["1"],
|
||||
)
|
||||
|
||||
templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]
|
||||
templ.should.equal(template_data)
|
||||
|
|
@ -96,22 +88,21 @@ def test_create_launch_template_version():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
create_resp = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
version_resp = cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
version_resp.should.have.key("LaunchTemplateVersion")
|
||||
version = version_resp["LaunchTemplateVersion"]
|
||||
version["DefaultVersion"].should.equal(False)
|
||||
version["LaunchTemplateId"].should.equal(create_resp["LaunchTemplate"]["LaunchTemplateId"])
|
||||
version["LaunchTemplateId"].should.equal(
|
||||
create_resp["LaunchTemplate"]["LaunchTemplateId"]
|
||||
)
|
||||
version["VersionDescription"].should.equal("new ami")
|
||||
version["VersionNumber"].should.equal(2)
|
||||
|
||||
|
|
@ -121,22 +112,21 @@ def test_create_launch_template_version_by_id():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
create_resp = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
version_resp = cli.create_launch_template_version(
|
||||
LaunchTemplateId=create_resp["LaunchTemplate"]["LaunchTemplateId"],
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
version_resp.should.have.key("LaunchTemplateVersion")
|
||||
version = version_resp["LaunchTemplateVersion"]
|
||||
version["DefaultVersion"].should.equal(False)
|
||||
version["LaunchTemplateId"].should.equal(create_resp["LaunchTemplate"]["LaunchTemplateId"])
|
||||
version["LaunchTemplateId"].should.equal(
|
||||
create_resp["LaunchTemplate"]["LaunchTemplateId"]
|
||||
)
|
||||
version["VersionDescription"].should.equal("new ami")
|
||||
version["VersionNumber"].should.equal(2)
|
||||
|
||||
|
|
@ -146,24 +136,24 @@ def test_describe_launch_template_versions_with_multiple_versions():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template")
|
||||
resp = cli.describe_launch_template_versions(LaunchTemplateName="test-template")
|
||||
|
||||
resp["LaunchTemplateVersions"].should.have.length_of(2)
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal("ami-abc123")
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal("ami-def456")
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-abc123"
|
||||
)
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-def456"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -171,32 +161,32 @@ def test_describe_launch_template_versions_with_versions_option():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-hij789"
|
||||
},
|
||||
VersionDescription="new ami, again")
|
||||
LaunchTemplateData={"ImageId": "ami-hij789"},
|
||||
VersionDescription="new ami, again",
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
Versions=["2", "3"])
|
||||
LaunchTemplateName="test-template", Versions=["2", "3"]
|
||||
)
|
||||
|
||||
resp["LaunchTemplateVersions"].should.have.length_of(2)
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal("ami-def456")
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal("ami-hij789")
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-def456"
|
||||
)
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-hij789"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -204,32 +194,32 @@ def test_describe_launch_template_versions_with_min():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-hij789"
|
||||
},
|
||||
VersionDescription="new ami, again")
|
||||
LaunchTemplateData={"ImageId": "ami-hij789"},
|
||||
VersionDescription="new ami, again",
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
MinVersion="2")
|
||||
LaunchTemplateName="test-template", MinVersion="2"
|
||||
)
|
||||
|
||||
resp["LaunchTemplateVersions"].should.have.length_of(2)
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal("ami-def456")
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal("ami-hij789")
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-def456"
|
||||
)
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-hij789"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -237,32 +227,32 @@ def test_describe_launch_template_versions_with_max():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-hij789"
|
||||
},
|
||||
VersionDescription="new ami, again")
|
||||
LaunchTemplateData={"ImageId": "ami-hij789"},
|
||||
VersionDescription="new ami, again",
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
MaxVersion="2")
|
||||
LaunchTemplateName="test-template", MaxVersion="2"
|
||||
)
|
||||
|
||||
resp["LaunchTemplateVersions"].should.have.length_of(2)
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal("ami-abc123")
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal("ami-def456")
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-abc123"
|
||||
)
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-def456"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -270,40 +260,38 @@ def test_describe_launch_template_versions_with_min_and_max():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-def456"
|
||||
},
|
||||
VersionDescription="new ami")
|
||||
LaunchTemplateData={"ImageId": "ami-def456"},
|
||||
VersionDescription="new ami",
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-hij789"
|
||||
},
|
||||
VersionDescription="new ami, again")
|
||||
LaunchTemplateData={"ImageId": "ami-hij789"},
|
||||
VersionDescription="new ami, again",
|
||||
)
|
||||
|
||||
cli.create_launch_template_version(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-345abc"
|
||||
},
|
||||
VersionDescription="new ami, because why not")
|
||||
LaunchTemplateData={"ImageId": "ami-345abc"},
|
||||
VersionDescription="new ami, because why not",
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
MinVersion="2",
|
||||
MaxVersion="3")
|
||||
LaunchTemplateName="test-template", MinVersion="2", MaxVersion="3"
|
||||
)
|
||||
|
||||
resp["LaunchTemplateVersions"].should.have.length_of(2)
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal("ami-def456")
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal("ami-hij789")
|
||||
resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-def456"
|
||||
)
|
||||
resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal(
|
||||
"ami-hij789"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -312,17 +300,14 @@ def test_describe_launch_templates():
|
|||
|
||||
lt_ids = []
|
||||
r = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
lt_ids.append(r["LaunchTemplate"]["LaunchTemplateId"])
|
||||
|
||||
r = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template2",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateData={"ImageId": "ami-abc123"},
|
||||
)
|
||||
lt_ids.append(r["LaunchTemplate"]["LaunchTemplateId"])
|
||||
|
||||
# general call, all templates
|
||||
|
|
@ -334,7 +319,8 @@ def test_describe_launch_templates():
|
|||
|
||||
# filter by names
|
||||
resp = cli.describe_launch_templates(
|
||||
LaunchTemplateNames=["test-template2", "test-template"])
|
||||
LaunchTemplateNames=["test-template2", "test-template"]
|
||||
)
|
||||
resp.should.have.key("LaunchTemplates")
|
||||
resp["LaunchTemplates"].should.have.length_of(2)
|
||||
resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal("test-template2")
|
||||
|
|
@ -353,34 +339,31 @@ def test_describe_launch_templates_with_filters():
|
|||
cli = boto3.client("ec2", region_name="us-east-1")
|
||||
|
||||
r = cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="test-template", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
cli.create_tags(
|
||||
Resources=[r["LaunchTemplate"]["LaunchTemplateId"]],
|
||||
Tags=[
|
||||
{"Key": "tag1", "Value": "a value"},
|
||||
{"Key": "another-key", "Value": "this value"},
|
||||
])
|
||||
],
|
||||
)
|
||||
|
||||
cli.create_launch_template(
|
||||
LaunchTemplateName="no-tags",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-abc123"
|
||||
})
|
||||
LaunchTemplateName="no-tags", LaunchTemplateData={"ImageId": "ami-abc123"}
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_templates(Filters=[{
|
||||
"Name": "tag:tag1", "Values": ["a value"]
|
||||
}])
|
||||
resp = cli.describe_launch_templates(
|
||||
Filters=[{"Name": "tag:tag1", "Values": ["a value"]}]
|
||||
)
|
||||
|
||||
resp["LaunchTemplates"].should.have.length_of(1)
|
||||
resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal("test-template")
|
||||
|
||||
resp = cli.describe_launch_templates(Filters=[{
|
||||
"Name": "launch-template-name", "Values": ["no-tags"]
|
||||
}])
|
||||
resp = cli.describe_launch_templates(
|
||||
Filters=[{"Name": "launch-template-name", "Values": ["no-tags"]}]
|
||||
)
|
||||
resp["LaunchTemplates"].should.have.length_of(1)
|
||||
resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal("no-tags")
|
||||
|
||||
|
|
@ -392,24 +375,18 @@ def test_create_launch_template_with_tag_spec():
|
|||
cli.create_launch_template(
|
||||
LaunchTemplateName="test-template",
|
||||
LaunchTemplateData={"ImageId": "ami-abc123"},
|
||||
TagSpecifications=[{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [
|
||||
{"Key": "key", "Value": "value"}
|
||||
]
|
||||
}],
|
||||
TagSpecifications=[
|
||||
{"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "value"}]}
|
||||
],
|
||||
)
|
||||
|
||||
resp = cli.describe_launch_template_versions(
|
||||
LaunchTemplateName="test-template",
|
||||
Versions=["1"])
|
||||
LaunchTemplateName="test-template", Versions=["1"]
|
||||
)
|
||||
version = resp["LaunchTemplateVersions"][0]
|
||||
|
||||
version["LaunchTemplateData"].should.have.key("TagSpecifications")
|
||||
version["LaunchTemplateData"]["TagSpecifications"].should.have.length_of(1)
|
||||
version["LaunchTemplateData"]["TagSpecifications"][0].should.equal({
|
||||
"ResourceType": "instance",
|
||||
"Tags": [
|
||||
{"Key": "key", "Value": "value"}
|
||||
]
|
||||
})
|
||||
version["LaunchTemplateData"]["TagSpecifications"][0].should.equal(
|
||||
{"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "value"}]}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,109 +1,225 @@
|
|||
from __future__ import unicode_literals
|
||||
import boto3
|
||||
import sure # noqa
|
||||
from moto import mock_ec2
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_nat_gateways():
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
|
||||
response = conn.describe_nat_gateways()
|
||||
|
||||
response['NatGateways'].should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_nat_gateway():
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
vpc = conn.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc_id = vpc['Vpc']['VpcId']
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id,
|
||||
CidrBlock='10.0.1.0/27',
|
||||
AvailabilityZone='us-east-1a',
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain='vpc')['AllocationId']
|
||||
subnet_id = subnet['Subnet']['SubnetId']
|
||||
|
||||
response = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id,
|
||||
AllocationId=allocation_id,
|
||||
)
|
||||
|
||||
response['NatGateway']['VpcId'].should.equal(vpc_id)
|
||||
response['NatGateway']['SubnetId'].should.equal(subnet_id)
|
||||
response['NatGateway']['State'].should.equal('available')
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_delete_nat_gateway():
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
vpc = conn.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc_id = vpc['Vpc']['VpcId']
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id,
|
||||
CidrBlock='10.0.1.0/27',
|
||||
AvailabilityZone='us-east-1a',
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain='vpc')['AllocationId']
|
||||
subnet_id = subnet['Subnet']['SubnetId']
|
||||
|
||||
nat_gateway = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id,
|
||||
AllocationId=allocation_id,
|
||||
)
|
||||
nat_gateway_id = nat_gateway['NatGateway']['NatGatewayId']
|
||||
response = conn.delete_nat_gateway(NatGatewayId=nat_gateway_id)
|
||||
|
||||
# this is hard to match against, so remove it
|
||||
response['ResponseMetadata'].pop('HTTPHeaders', None)
|
||||
response['ResponseMetadata'].pop('RetryAttempts', None)
|
||||
response.should.equal({
|
||||
'NatGatewayId': nat_gateway_id,
|
||||
'ResponseMetadata': {
|
||||
'HTTPStatusCode': 200,
|
||||
'RequestId': '741fc8ab-6ebe-452b-b92b-example'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_and_describe_nat_gateway():
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
vpc = conn.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc_id = vpc['Vpc']['VpcId']
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id,
|
||||
CidrBlock='10.0.1.0/27',
|
||||
AvailabilityZone='us-east-1a',
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain='vpc')['AllocationId']
|
||||
subnet_id = subnet['Subnet']['SubnetId']
|
||||
|
||||
create_response = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id,
|
||||
AllocationId=allocation_id,
|
||||
)
|
||||
nat_gateway_id = create_response['NatGateway']['NatGatewayId']
|
||||
describe_response = conn.describe_nat_gateways()
|
||||
|
||||
enis = conn.describe_network_interfaces()['NetworkInterfaces']
|
||||
eni_id = enis[0]['NetworkInterfaceId']
|
||||
public_ip = conn.describe_addresses(AllocationIds=[allocation_id])[
|
||||
'Addresses'][0]['PublicIp']
|
||||
|
||||
describe_response['NatGateways'].should.have.length_of(1)
|
||||
describe_response['NatGateways'][0][
|
||||
'NatGatewayId'].should.equal(nat_gateway_id)
|
||||
describe_response['NatGateways'][0]['State'].should.equal('available')
|
||||
describe_response['NatGateways'][0]['SubnetId'].should.equal(subnet_id)
|
||||
describe_response['NatGateways'][0]['VpcId'].should.equal(vpc_id)
|
||||
describe_response['NatGateways'][0]['NatGatewayAddresses'][
|
||||
0]['AllocationId'].should.equal(allocation_id)
|
||||
describe_response['NatGateways'][0]['NatGatewayAddresses'][
|
||||
0]['NetworkInterfaceId'].should.equal(eni_id)
|
||||
assert describe_response['NatGateways'][0][
|
||||
'NatGatewayAddresses'][0]['PrivateIp'].startswith('10.')
|
||||
describe_response['NatGateways'][0]['NatGatewayAddresses'][
|
||||
0]['PublicIp'].should.equal(public_ip)
|
||||
from __future__ import unicode_literals
|
||||
import boto3
|
||||
import sure # noqa
|
||||
from moto import mock_ec2
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_nat_gateways():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
|
||||
response = conn.describe_nat_gateways()
|
||||
|
||||
response["NatGateways"].should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_nat_gateway():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id = vpc["Vpc"]["VpcId"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id = subnet["Subnet"]["SubnetId"]
|
||||
|
||||
response = conn.create_nat_gateway(SubnetId=subnet_id, AllocationId=allocation_id)
|
||||
|
||||
response["NatGateway"]["VpcId"].should.equal(vpc_id)
|
||||
response["NatGateway"]["SubnetId"].should.equal(subnet_id)
|
||||
response["NatGateway"]["State"].should.equal("available")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_delete_nat_gateway():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id = vpc["Vpc"]["VpcId"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id = subnet["Subnet"]["SubnetId"]
|
||||
|
||||
nat_gateway = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id, AllocationId=allocation_id
|
||||
)
|
||||
nat_gateway_id = nat_gateway["NatGateway"]["NatGatewayId"]
|
||||
response = conn.delete_nat_gateway(NatGatewayId=nat_gateway_id)
|
||||
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
response.should.equal(
|
||||
{
|
||||
"NatGatewayId": nat_gateway_id,
|
||||
"ResponseMetadata": {
|
||||
"HTTPStatusCode": 200,
|
||||
"RequestId": "741fc8ab-6ebe-452b-b92b-example",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_and_describe_nat_gateway():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id = vpc["Vpc"]["VpcId"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id = subnet["Subnet"]["SubnetId"]
|
||||
|
||||
create_response = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id, AllocationId=allocation_id
|
||||
)
|
||||
nat_gateway_id = create_response["NatGateway"]["NatGatewayId"]
|
||||
describe_response = conn.describe_nat_gateways()
|
||||
|
||||
enis = conn.describe_network_interfaces()["NetworkInterfaces"]
|
||||
eni_id = enis[0]["NetworkInterfaceId"]
|
||||
public_ip = conn.describe_addresses(AllocationIds=[allocation_id])["Addresses"][0][
|
||||
"PublicIp"
|
||||
]
|
||||
|
||||
describe_response["NatGateways"].should.have.length_of(1)
|
||||
describe_response["NatGateways"][0]["NatGatewayId"].should.equal(nat_gateway_id)
|
||||
describe_response["NatGateways"][0]["State"].should.equal("available")
|
||||
describe_response["NatGateways"][0]["SubnetId"].should.equal(subnet_id)
|
||||
describe_response["NatGateways"][0]["VpcId"].should.equal(vpc_id)
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"AllocationId"
|
||||
].should.equal(allocation_id)
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"NetworkInterfaceId"
|
||||
].should.equal(eni_id)
|
||||
assert describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"PrivateIp"
|
||||
].startswith("10.")
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"PublicIp"
|
||||
].should.equal(public_ip)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_nat_gateway_filter_by_net_gateway_id_and_state():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id = vpc["Vpc"]["VpcId"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id = subnet["Subnet"]["SubnetId"]
|
||||
|
||||
create_response = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id, AllocationId=allocation_id
|
||||
)
|
||||
nat_gateway_id = create_response["NatGateway"]["NatGatewayId"]
|
||||
|
||||
describe_response = conn.describe_nat_gateways(
|
||||
Filters=[
|
||||
{"Name": "nat-gateway-id", "Values": ["non-existent-id"]},
|
||||
{"Name": "state", "Values": ["available"]},
|
||||
]
|
||||
)
|
||||
describe_response["NatGateways"].should.have.length_of(0)
|
||||
|
||||
describe_response = conn.describe_nat_gateways(
|
||||
Filters=[
|
||||
{"Name": "nat-gateway-id", "Values": [nat_gateway_id]},
|
||||
{"Name": "state", "Values": ["available"]},
|
||||
]
|
||||
)
|
||||
|
||||
describe_response["NatGateways"].should.have.length_of(1)
|
||||
describe_response["NatGateways"][0]["NatGatewayId"].should.equal(nat_gateway_id)
|
||||
describe_response["NatGateways"][0]["State"].should.equal("available")
|
||||
describe_response["NatGateways"][0]["SubnetId"].should.equal(subnet_id)
|
||||
describe_response["NatGateways"][0]["VpcId"].should.equal(vpc_id)
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"AllocationId"
|
||||
].should.equal(allocation_id)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_nat_gateway_filter_by_subnet_id():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id = vpc["Vpc"]["VpcId"]
|
||||
subnet_1 = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
subnet_2 = conn.create_subnet(
|
||||
VpcId=vpc_id, CidrBlock="10.0.2.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id_1 = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
allocation_id_2 = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id_1 = subnet_1["Subnet"]["SubnetId"]
|
||||
subnet_id_2 = subnet_2["Subnet"]["SubnetId"]
|
||||
|
||||
create_response_1 = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id_1, AllocationId=allocation_id_1
|
||||
)
|
||||
# create_response_2 =
|
||||
conn.create_nat_gateway(SubnetId=subnet_id_2, AllocationId=allocation_id_2)
|
||||
nat_gateway_id_1 = create_response_1["NatGateway"]["NatGatewayId"]
|
||||
# nat_gateway_id_2 = create_response_2["NatGateway"]["NatGatewayId"]
|
||||
|
||||
describe_response = conn.describe_nat_gateways()
|
||||
describe_response["NatGateways"].should.have.length_of(2)
|
||||
|
||||
describe_response = conn.describe_nat_gateways(
|
||||
Filters=[{"Name": "subnet-id", "Values": [subnet_id_1]}]
|
||||
)
|
||||
describe_response["NatGateways"].should.have.length_of(1)
|
||||
describe_response["NatGateways"][0]["NatGatewayId"].should.equal(nat_gateway_id_1)
|
||||
describe_response["NatGateways"][0]["State"].should.equal("available")
|
||||
describe_response["NatGateways"][0]["SubnetId"].should.equal(subnet_id_1)
|
||||
describe_response["NatGateways"][0]["VpcId"].should.equal(vpc_id)
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"AllocationId"
|
||||
].should.equal(allocation_id_1)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_nat_gateway_filter_vpc_id():
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc_1 = conn.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc_id_1 = vpc_1["Vpc"]["VpcId"]
|
||||
vpc_2 = conn.create_vpc(CidrBlock="10.1.0.0/16")
|
||||
vpc_id_2 = vpc_2["Vpc"]["VpcId"]
|
||||
subnet_1 = conn.create_subnet(
|
||||
VpcId=vpc_id_1, CidrBlock="10.0.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
subnet_2 = conn.create_subnet(
|
||||
VpcId=vpc_id_2, CidrBlock="10.1.1.0/27", AvailabilityZone="us-east-1a"
|
||||
)
|
||||
allocation_id_1 = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
allocation_id_2 = conn.allocate_address(Domain="vpc")["AllocationId"]
|
||||
subnet_id_1 = subnet_1["Subnet"]["SubnetId"]
|
||||
subnet_id_2 = subnet_2["Subnet"]["SubnetId"]
|
||||
|
||||
create_response_1 = conn.create_nat_gateway(
|
||||
SubnetId=subnet_id_1, AllocationId=allocation_id_1
|
||||
)
|
||||
conn.create_nat_gateway(SubnetId=subnet_id_2, AllocationId=allocation_id_2)
|
||||
nat_gateway_id_1 = create_response_1["NatGateway"]["NatGatewayId"]
|
||||
|
||||
describe_response = conn.describe_nat_gateways()
|
||||
describe_response["NatGateways"].should.have.length_of(2)
|
||||
|
||||
describe_response = conn.describe_nat_gateways(
|
||||
Filters=[{"Name": "vpc-id", "Values": [vpc_id_1]}]
|
||||
)
|
||||
describe_response["NatGateways"].should.have.length_of(1)
|
||||
describe_response["NatGateways"][0]["NatGatewayId"].should.equal(nat_gateway_id_1)
|
||||
describe_response["NatGateways"][0]["State"].should.equal("available")
|
||||
describe_response["NatGateways"][0]["SubnetId"].should.equal(subnet_id_1)
|
||||
describe_response["NatGateways"][0]["VpcId"].should.equal(vpc_id_1)
|
||||
describe_response["NatGateways"][0]["NatGatewayAddresses"][0][
|
||||
"AllocationId"
|
||||
].should.equal(allocation_id_1)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from moto import mock_ec2_deprecated, mock_ec2
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_default_network_acl_created_with_vpc():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
all_network_acls.should.have.length_of(2)
|
||||
|
|
@ -18,7 +18,7 @@ def test_default_network_acl_created_with_vpc():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_network_acls():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
|
|
@ -27,7 +27,7 @@ def test_network_acls():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_new_subnet_associates_with_default_network_acl():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.get_all_vpcs()[0]
|
||||
|
||||
subnet = conn.create_subnet(vpc.id, "172.31.112.0/20")
|
||||
|
|
@ -41,88 +41,100 @@ def test_new_subnet_associates_with_default_network_acl():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_network_acl_entries():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
||||
network_acl_entry = conn.create_network_acl_entry(
|
||||
network_acl.id, 110, 6,
|
||||
'ALLOW', '0.0.0.0/0', False,
|
||||
port_range_from='443',
|
||||
port_range_to='443'
|
||||
network_acl.id,
|
||||
110,
|
||||
6,
|
||||
"ALLOW",
|
||||
"0.0.0.0/0",
|
||||
False,
|
||||
port_range_from="443",
|
||||
port_range_to="443",
|
||||
)
|
||||
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
all_network_acls.should.have.length_of(3)
|
||||
|
||||
test_network_acl = next(na for na in all_network_acls
|
||||
if na.id == network_acl.id)
|
||||
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
|
||||
entries = test_network_acl.network_acl_entries
|
||||
entries.should.have.length_of(1)
|
||||
entries[0].rule_number.should.equal('110')
|
||||
entries[0].protocol.should.equal('6')
|
||||
entries[0].rule_action.should.equal('ALLOW')
|
||||
entries[0].rule_number.should.equal("110")
|
||||
entries[0].protocol.should.equal("6")
|
||||
entries[0].rule_action.should.equal("ALLOW")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_network_acl_entry():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
||||
conn.create_network_acl_entry(
|
||||
network_acl.id, 110, 6,
|
||||
'ALLOW', '0.0.0.0/0', False,
|
||||
port_range_from='443',
|
||||
port_range_to='443'
|
||||
)
|
||||
conn.delete_network_acl_entry(
|
||||
network_acl.id, 110, False
|
||||
network_acl.id,
|
||||
110,
|
||||
6,
|
||||
"ALLOW",
|
||||
"0.0.0.0/0",
|
||||
False,
|
||||
port_range_from="443",
|
||||
port_range_to="443",
|
||||
)
|
||||
conn.delete_network_acl_entry(network_acl.id, 110, False)
|
||||
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
|
||||
test_network_acl = next(na for na in all_network_acls
|
||||
if na.id == network_acl.id)
|
||||
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
|
||||
entries = test_network_acl.network_acl_entries
|
||||
entries.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_replace_network_acl_entry():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
||||
conn.create_network_acl_entry(
|
||||
network_acl.id, 110, 6,
|
||||
'ALLOW', '0.0.0.0/0', False,
|
||||
port_range_from='443',
|
||||
port_range_to='443'
|
||||
network_acl.id,
|
||||
110,
|
||||
6,
|
||||
"ALLOW",
|
||||
"0.0.0.0/0",
|
||||
False,
|
||||
port_range_from="443",
|
||||
port_range_to="443",
|
||||
)
|
||||
conn.replace_network_acl_entry(
|
||||
network_acl.id, 110, -1,
|
||||
'DENY', '0.0.0.0/0', False,
|
||||
port_range_from='22',
|
||||
port_range_to='22'
|
||||
network_acl.id,
|
||||
110,
|
||||
-1,
|
||||
"DENY",
|
||||
"0.0.0.0/0",
|
||||
False,
|
||||
port_range_from="22",
|
||||
port_range_to="22",
|
||||
)
|
||||
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
|
||||
test_network_acl = next(na for na in all_network_acls
|
||||
if na.id == network_acl.id)
|
||||
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
|
||||
entries = test_network_acl.network_acl_entries
|
||||
entries.should.have.length_of(1)
|
||||
entries[0].rule_number.should.equal('110')
|
||||
entries[0].protocol.should.equal('-1')
|
||||
entries[0].rule_action.should.equal('DENY')
|
||||
entries[0].rule_number.should.equal("110")
|
||||
entries[0].protocol.should.equal("-1")
|
||||
entries[0].rule_action.should.equal("DENY")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_associate_new_network_acl_with_subnet():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
|
@ -132,8 +144,7 @@ def test_associate_new_network_acl_with_subnet():
|
|||
all_network_acls = conn.get_all_network_acls()
|
||||
all_network_acls.should.have.length_of(3)
|
||||
|
||||
test_network_acl = next(na for na in all_network_acls
|
||||
if na.id == network_acl.id)
|
||||
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
|
||||
|
||||
test_network_acl.associations.should.have.length_of(1)
|
||||
test_network_acl.associations[0].subnet_id.should.equal(subnet.id)
|
||||
|
|
@ -141,7 +152,7 @@ def test_associate_new_network_acl_with_subnet():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_network_acl():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
|
@ -161,7 +172,7 @@ def test_delete_network_acl():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_network_acl_tagging():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
network_acl = conn.create_network_acl(vpc.id)
|
||||
|
||||
|
|
@ -172,46 +183,45 @@ def test_network_acl_tagging():
|
|||
tag.value.should.equal("some value")
|
||||
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
test_network_acl = next(na for na in all_network_acls
|
||||
if na.id == network_acl.id)
|
||||
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
|
||||
test_network_acl.tags.should.have.length_of(1)
|
||||
test_network_acl.tags["a key"].should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_new_subnet_in_new_vpc_associates_with_default_network_acl():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
new_vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
new_vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
new_vpc.reload()
|
||||
|
||||
subnet = ec2.create_subnet(VpcId=new_vpc.id, CidrBlock='10.0.0.0/24')
|
||||
subnet = ec2.create_subnet(VpcId=new_vpc.id, CidrBlock="10.0.0.0/24")
|
||||
subnet.reload()
|
||||
|
||||
new_vpcs_default_network_acl = next(iter(new_vpc.network_acls.all()), None)
|
||||
new_vpcs_default_network_acl.reload()
|
||||
new_vpcs_default_network_acl.vpc_id.should.equal(new_vpc.id)
|
||||
new_vpcs_default_network_acl.associations.should.have.length_of(1)
|
||||
new_vpcs_default_network_acl.associations[0]['SubnetId'].should.equal(subnet.id)
|
||||
new_vpcs_default_network_acl.associations[0]["SubnetId"].should.equal(subnet.id)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_default_network_acl_default_entries():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
default_network_acl = next(iter(ec2.network_acls.all()), None)
|
||||
default_network_acl.is_default.should.be.ok
|
||||
|
||||
default_network_acl.entries.should.have.length_of(4)
|
||||
unique_entries = []
|
||||
for entry in default_network_acl.entries:
|
||||
entry['CidrBlock'].should.equal('0.0.0.0/0')
|
||||
entry['Protocol'].should.equal('-1')
|
||||
entry['RuleNumber'].should.be.within([100, 32767])
|
||||
entry['RuleAction'].should.be.within(['allow', 'deny'])
|
||||
assert type(entry['Egress']) is bool
|
||||
if entry['RuleAction'] == 'allow':
|
||||
entry['RuleNumber'].should.be.equal(100)
|
||||
entry["CidrBlock"].should.equal("0.0.0.0/0")
|
||||
entry["Protocol"].should.equal("-1")
|
||||
entry["RuleNumber"].should.be.within([100, 32767])
|
||||
entry["RuleAction"].should.be.within(["allow", "deny"])
|
||||
assert type(entry["Egress"]) is bool
|
||||
if entry["RuleAction"] == "allow":
|
||||
entry["RuleNumber"].should.be.equal(100)
|
||||
else:
|
||||
entry['RuleNumber'].should.be.equal(32767)
|
||||
entry["RuleNumber"].should.be.equal(32767)
|
||||
if entry not in unique_entries:
|
||||
unique_entries.append(entry)
|
||||
|
||||
|
|
@ -220,33 +230,48 @@ def test_default_network_acl_default_entries():
|
|||
|
||||
@mock_ec2
|
||||
def test_delete_default_network_acl_default_entry():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
default_network_acl = next(iter(ec2.network_acls.all()), None)
|
||||
default_network_acl.is_default.should.be.ok
|
||||
|
||||
default_network_acl.entries.should.have.length_of(4)
|
||||
first_default_network_acl_entry = default_network_acl.entries[0]
|
||||
|
||||
default_network_acl.delete_entry(Egress=first_default_network_acl_entry['Egress'],
|
||||
RuleNumber=first_default_network_acl_entry['RuleNumber'])
|
||||
default_network_acl.delete_entry(
|
||||
Egress=first_default_network_acl_entry["Egress"],
|
||||
RuleNumber=first_default_network_acl_entry["RuleNumber"],
|
||||
)
|
||||
|
||||
default_network_acl.entries.should.have.length_of(3)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_duplicate_network_acl_entry():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
default_network_acl = next(iter(ec2.network_acls.all()), None)
|
||||
default_network_acl.is_default.should.be.ok
|
||||
|
||||
rule_number = 200
|
||||
egress = True
|
||||
default_network_acl.create_entry(CidrBlock="0.0.0.0/0", Egress=egress, Protocol="-1", RuleAction="allow", RuleNumber=rule_number)
|
||||
default_network_acl.create_entry(
|
||||
CidrBlock="0.0.0.0/0",
|
||||
Egress=egress,
|
||||
Protocol="-1",
|
||||
RuleAction="allow",
|
||||
RuleNumber=rule_number,
|
||||
)
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
default_network_acl.create_entry(CidrBlock="10.0.0.0/0", Egress=egress, Protocol="-1", RuleAction="deny", RuleNumber=rule_number)
|
||||
default_network_acl.create_entry(
|
||||
CidrBlock="10.0.0.0/0",
|
||||
Egress=egress,
|
||||
Protocol="-1",
|
||||
RuleAction="deny",
|
||||
RuleNumber=rule_number,
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (NetworkAclEntryAlreadyExists) when calling the CreateNetworkAclEntry "
|
||||
"operation: The network acl entry identified by {} already exists.".format(rule_number))
|
||||
|
||||
|
||||
"operation: The network acl entry identified by {} already exists.".format(
|
||||
rule_number
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,38 +7,41 @@ from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_depr
|
|||
|
||||
from moto.ec2 import ec2_backends
|
||||
|
||||
|
||||
def test_use_boto_regions():
|
||||
boto_regions = {r.name for r in boto.ec2.regions()}
|
||||
moto_regions = set(ec2_backends)
|
||||
|
||||
moto_regions.should.equal(boto_regions)
|
||||
|
||||
|
||||
def add_servers_to_region(ami_id, count, region):
|
||||
conn = boto.ec2.connect_to_region(region)
|
||||
for index in range(count):
|
||||
conn.run_instances(ami_id)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_add_servers_to_a_single_region():
|
||||
region = 'ap-northeast-1'
|
||||
add_servers_to_region('ami-1234abcd', 1, region)
|
||||
add_servers_to_region('ami-5678efgh', 1, region)
|
||||
region = "ap-northeast-1"
|
||||
add_servers_to_region("ami-1234abcd", 1, region)
|
||||
add_servers_to_region("ami-5678efgh", 1, region)
|
||||
|
||||
conn = boto.ec2.connect_to_region(region)
|
||||
reservations = conn.get_all_instances()
|
||||
len(reservations).should.equal(2)
|
||||
reservations.sort(key=lambda x: x.instances[0].image_id)
|
||||
|
||||
reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
|
||||
reservations[1].instances[0].image_id.should.equal('ami-5678efgh')
|
||||
reservations[0].instances[0].image_id.should.equal("ami-1234abcd")
|
||||
reservations[1].instances[0].image_id.should.equal("ami-5678efgh")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_add_servers_to_multiple_regions():
|
||||
region1 = 'us-east-1'
|
||||
region2 = 'ap-northeast-1'
|
||||
add_servers_to_region('ami-1234abcd', 1, region1)
|
||||
add_servers_to_region('ami-5678efgh', 1, region2)
|
||||
region1 = "us-east-1"
|
||||
region2 = "ap-northeast-1"
|
||||
add_servers_to_region("ami-1234abcd", 1, region1)
|
||||
add_servers_to_region("ami-5678efgh", 1, region2)
|
||||
|
||||
us_conn = boto.ec2.connect_to_region(region1)
|
||||
ap_conn = boto.ec2.connect_to_region(region2)
|
||||
|
|
@ -48,33 +51,35 @@ def test_add_servers_to_multiple_regions():
|
|||
len(us_reservations).should.equal(1)
|
||||
len(ap_reservations).should.equal(1)
|
||||
|
||||
us_reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
|
||||
ap_reservations[0].instances[0].image_id.should.equal('ami-5678efgh')
|
||||
us_reservations[0].instances[0].image_id.should.equal("ami-1234abcd")
|
||||
ap_reservations[0].instances[0].image_id.should.equal("ami-5678efgh")
|
||||
|
||||
|
||||
@mock_autoscaling_deprecated
|
||||
@mock_elb_deprecated
|
||||
def test_create_autoscaling_group():
|
||||
elb_conn = boto.ec2.elb.connect_to_region('us-east-1')
|
||||
elb_conn = boto.ec2.elb.connect_to_region("us-east-1")
|
||||
elb_conn.create_load_balancer(
|
||||
'us_test_lb', zones=[], listeners=[(80, 8080, 'http')])
|
||||
elb_conn = boto.ec2.elb.connect_to_region('ap-northeast-1')
|
||||
"us_test_lb", zones=[], listeners=[(80, 8080, "http")]
|
||||
)
|
||||
elb_conn = boto.ec2.elb.connect_to_region("ap-northeast-1")
|
||||
elb_conn.create_load_balancer(
|
||||
'ap_test_lb', zones=[], listeners=[(80, 8080, 'http')])
|
||||
"ap_test_lb", zones=[], listeners=[(80, 8080, "http")]
|
||||
)
|
||||
|
||||
us_conn = boto.ec2.autoscale.connect_to_region('us-east-1')
|
||||
us_conn = boto.ec2.autoscale.connect_to_region("us-east-1")
|
||||
config = boto.ec2.autoscale.LaunchConfiguration(
|
||||
name='us_tester',
|
||||
image_id='ami-abcd1234',
|
||||
instance_type='m1.small',
|
||||
name="us_tester", image_id="ami-abcd1234", instance_type="m1.small"
|
||||
)
|
||||
x = us_conn.create_launch_configuration(config)
|
||||
|
||||
us_subnet_id = list(ec2_backends['us-east-1'].subnets['us-east-1c'].keys())[0]
|
||||
ap_subnet_id = list(ec2_backends['ap-northeast-1'].subnets['ap-northeast-1a'].keys())[0]
|
||||
us_subnet_id = list(ec2_backends["us-east-1"].subnets["us-east-1c"].keys())[0]
|
||||
ap_subnet_id = list(
|
||||
ec2_backends["ap-northeast-1"].subnets["ap-northeast-1a"].keys()
|
||||
)[0]
|
||||
group = boto.ec2.autoscale.AutoScalingGroup(
|
||||
name='us_tester_group',
|
||||
availability_zones=['us-east-1c'],
|
||||
name="us_tester_group",
|
||||
availability_zones=["us-east-1c"],
|
||||
default_cooldown=60,
|
||||
desired_capacity=2,
|
||||
health_check_period=100,
|
||||
|
|
@ -89,17 +94,15 @@ def test_create_autoscaling_group():
|
|||
)
|
||||
us_conn.create_auto_scaling_group(group)
|
||||
|
||||
ap_conn = boto.ec2.autoscale.connect_to_region('ap-northeast-1')
|
||||
ap_conn = boto.ec2.autoscale.connect_to_region("ap-northeast-1")
|
||||
config = boto.ec2.autoscale.LaunchConfiguration(
|
||||
name='ap_tester',
|
||||
image_id='ami-efgh5678',
|
||||
instance_type='m1.small',
|
||||
name="ap_tester", image_id="ami-efgh5678", instance_type="m1.small"
|
||||
)
|
||||
ap_conn.create_launch_configuration(config)
|
||||
|
||||
group = boto.ec2.autoscale.AutoScalingGroup(
|
||||
name='ap_tester_group',
|
||||
availability_zones=['ap-northeast-1a'],
|
||||
name="ap_tester_group",
|
||||
availability_zones=["ap-northeast-1a"],
|
||||
default_cooldown=60,
|
||||
desired_capacity=2,
|
||||
health_check_period=100,
|
||||
|
|
@ -118,33 +121,35 @@ def test_create_autoscaling_group():
|
|||
len(ap_conn.get_all_groups()).should.equal(1)
|
||||
|
||||
us_group = us_conn.get_all_groups()[0]
|
||||
us_group.name.should.equal('us_tester_group')
|
||||
list(us_group.availability_zones).should.equal(['us-east-1c'])
|
||||
us_group.name.should.equal("us_tester_group")
|
||||
list(us_group.availability_zones).should.equal(["us-east-1c"])
|
||||
us_group.desired_capacity.should.equal(2)
|
||||
us_group.max_size.should.equal(2)
|
||||
us_group.min_size.should.equal(2)
|
||||
us_group.vpc_zone_identifier.should.equal(us_subnet_id)
|
||||
us_group.launch_config_name.should.equal('us_tester')
|
||||
us_group.launch_config_name.should.equal("us_tester")
|
||||
us_group.default_cooldown.should.equal(60)
|
||||
us_group.health_check_period.should.equal(100)
|
||||
us_group.health_check_type.should.equal("EC2")
|
||||
list(us_group.load_balancers).should.equal(["us_test_lb"])
|
||||
us_group.placement_group.should.equal("us_test_placement")
|
||||
list(us_group.termination_policies).should.equal(
|
||||
["OldestInstance", "NewestInstance"])
|
||||
["OldestInstance", "NewestInstance"]
|
||||
)
|
||||
|
||||
ap_group = ap_conn.get_all_groups()[0]
|
||||
ap_group.name.should.equal('ap_tester_group')
|
||||
list(ap_group.availability_zones).should.equal(['ap-northeast-1a'])
|
||||
ap_group.name.should.equal("ap_tester_group")
|
||||
list(ap_group.availability_zones).should.equal(["ap-northeast-1a"])
|
||||
ap_group.desired_capacity.should.equal(2)
|
||||
ap_group.max_size.should.equal(2)
|
||||
ap_group.min_size.should.equal(2)
|
||||
ap_group.vpc_zone_identifier.should.equal(ap_subnet_id)
|
||||
ap_group.launch_config_name.should.equal('ap_tester')
|
||||
ap_group.launch_config_name.should.equal("ap_tester")
|
||||
ap_group.default_cooldown.should.equal(60)
|
||||
ap_group.health_check_period.should.equal(100)
|
||||
ap_group.health_check_type.should.equal("EC2")
|
||||
list(ap_group.load_balancers).should.equal(["ap_test_lb"])
|
||||
ap_group.placement_group.should.equal("ap_test_placement")
|
||||
list(ap_group.termination_policies).should.equal(
|
||||
["OldestInstance", "NewestInstance"])
|
||||
["OldestInstance", "NewestInstance"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -15,10 +16,10 @@ from tests.helpers import requires_boto_gte
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_tables_defaults():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
all_route_tables = conn.get_all_route_tables(filters={'vpc-id': vpc.id})
|
||||
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
|
||||
all_route_tables.should.have.length_of(1)
|
||||
|
||||
main_route_table = all_route_tables[0]
|
||||
|
|
@ -28,23 +29,23 @@ def test_route_tables_defaults():
|
|||
routes.should.have.length_of(1)
|
||||
|
||||
local_route = routes[0]
|
||||
local_route.gateway_id.should.equal('local')
|
||||
local_route.state.should.equal('active')
|
||||
local_route.gateway_id.should.equal("local")
|
||||
local_route.state.should.equal("active")
|
||||
local_route.destination_cidr_block.should.equal(vpc.cidr_block)
|
||||
|
||||
vpc.delete()
|
||||
|
||||
all_route_tables = conn.get_all_route_tables(filters={'vpc-id': vpc.id})
|
||||
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
|
||||
all_route_tables.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_tables_additional():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
route_table = conn.create_route_table(vpc.id)
|
||||
|
||||
all_route_tables = conn.get_all_route_tables(filters={'vpc-id': vpc.id})
|
||||
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
|
||||
all_route_tables.should.have.length_of(2)
|
||||
all_route_tables[0].vpc_id.should.equal(vpc.id)
|
||||
all_route_tables[1].vpc_id.should.equal(vpc.id)
|
||||
|
|
@ -56,31 +57,31 @@ def test_route_tables_additional():
|
|||
routes.should.have.length_of(1)
|
||||
|
||||
local_route = routes[0]
|
||||
local_route.gateway_id.should.equal('local')
|
||||
local_route.state.should.equal('active')
|
||||
local_route.gateway_id.should.equal("local")
|
||||
local_route.state.should.equal("active")
|
||||
local_route.destination_cidr_block.should.equal(vpc.cidr_block)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_vpc(vpc.id)
|
||||
cm.exception.code.should.equal('DependencyViolation')
|
||||
cm.exception.code.should.equal("DependencyViolation")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
conn.delete_route_table(route_table.id)
|
||||
|
||||
all_route_tables = conn.get_all_route_tables(filters={'vpc-id': vpc.id})
|
||||
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
|
||||
all_route_tables.should.have.length_of(1)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_route_table("rtb-1234abcd")
|
||||
cm.exception.code.should.equal('InvalidRouteTableID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidRouteTableID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_tables_filters_standard():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
vpc1 = conn.create_vpc("10.0.0.0/16")
|
||||
route_table1 = conn.create_route_table(vpc1.id)
|
||||
|
|
@ -92,39 +93,39 @@ def test_route_tables_filters_standard():
|
|||
all_route_tables.should.have.length_of(5)
|
||||
|
||||
# Filter by main route table
|
||||
main_route_tables = conn.get_all_route_tables(
|
||||
filters={'association.main': 'true'})
|
||||
main_route_tables = conn.get_all_route_tables(filters={"association.main": "true"})
|
||||
main_route_tables.should.have.length_of(3)
|
||||
main_route_table_ids = [
|
||||
route_table.id for route_table in main_route_tables]
|
||||
main_route_table_ids = [route_table.id for route_table in main_route_tables]
|
||||
main_route_table_ids.should_not.contain(route_table1.id)
|
||||
main_route_table_ids.should_not.contain(route_table2.id)
|
||||
|
||||
# Filter by VPC
|
||||
vpc1_route_tables = conn.get_all_route_tables(filters={'vpc-id': vpc1.id})
|
||||
vpc1_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc1.id})
|
||||
vpc1_route_tables.should.have.length_of(2)
|
||||
vpc1_route_table_ids = [
|
||||
route_table.id for route_table in vpc1_route_tables]
|
||||
vpc1_route_table_ids = [route_table.id for route_table in vpc1_route_tables]
|
||||
vpc1_route_table_ids.should.contain(route_table1.id)
|
||||
vpc1_route_table_ids.should_not.contain(route_table2.id)
|
||||
|
||||
# Filter by VPC and main route table
|
||||
vpc2_main_route_tables = conn.get_all_route_tables(
|
||||
filters={'association.main': 'true', 'vpc-id': vpc2.id})
|
||||
filters={"association.main": "true", "vpc-id": vpc2.id}
|
||||
)
|
||||
vpc2_main_route_tables.should.have.length_of(1)
|
||||
vpc2_main_route_table_ids = [
|
||||
route_table.id for route_table in vpc2_main_route_tables]
|
||||
route_table.id for route_table in vpc2_main_route_tables
|
||||
]
|
||||
vpc2_main_route_table_ids.should_not.contain(route_table1.id)
|
||||
vpc2_main_route_table_ids.should_not.contain(route_table2.id)
|
||||
|
||||
# Unsupported filter
|
||||
conn.get_all_route_tables.when.called_with(
|
||||
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
|
||||
filters={"not-implemented-filter": "foobar"}
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_tables_filters_associations():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet1 = conn.create_subnet(vpc.id, "10.0.0.0/24")
|
||||
|
|
@ -142,21 +143,24 @@ def test_route_tables_filters_associations():
|
|||
|
||||
# Filter by association ID
|
||||
association1_route_tables = conn.get_all_route_tables(
|
||||
filters={'association.route-table-association-id': association_id1})
|
||||
filters={"association.route-table-association-id": association_id1}
|
||||
)
|
||||
association1_route_tables.should.have.length_of(1)
|
||||
association1_route_tables[0].id.should.equal(route_table1.id)
|
||||
association1_route_tables[0].associations.should.have.length_of(2)
|
||||
|
||||
# Filter by route table ID
|
||||
route_table2_route_tables = conn.get_all_route_tables(
|
||||
filters={'association.route-table-id': route_table2.id})
|
||||
filters={"association.route-table-id": route_table2.id}
|
||||
)
|
||||
route_table2_route_tables.should.have.length_of(1)
|
||||
route_table2_route_tables[0].id.should.equal(route_table2.id)
|
||||
route_table2_route_tables[0].associations.should.have.length_of(1)
|
||||
|
||||
# Filter by subnet ID
|
||||
subnet_route_tables = conn.get_all_route_tables(
|
||||
filters={'association.subnet-id': subnet1.id})
|
||||
filters={"association.subnet-id": subnet1.id}
|
||||
)
|
||||
subnet_route_tables.should.have.length_of(1)
|
||||
subnet_route_tables[0].id.should.equal(route_table1.id)
|
||||
association1_route_tables[0].associations.should.have.length_of(2)
|
||||
|
|
@ -164,7 +168,7 @@ def test_route_tables_filters_associations():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_table_associations():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
route_table = conn.create_route_table(vpc.id)
|
||||
|
|
@ -189,14 +193,13 @@ def test_route_table_associations():
|
|||
route_table.associations[0].subnet_id.should.equal(subnet.id)
|
||||
|
||||
# Associate is idempotent
|
||||
association_id_idempotent = conn.associate_route_table(
|
||||
route_table.id, subnet.id)
|
||||
association_id_idempotent = conn.associate_route_table(route_table.id, subnet.id)
|
||||
association_id_idempotent.should.equal(association_id)
|
||||
|
||||
# Error: Attempt delete associated route table.
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_route_table(route_table.id)
|
||||
cm.exception.code.should.equal('DependencyViolation')
|
||||
cm.exception.code.should.equal("DependencyViolation")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -210,21 +213,21 @@ def test_route_table_associations():
|
|||
# Error: Disassociate with invalid association ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.disassociate_route_table(association_id)
|
||||
cm.exception.code.should.equal('InvalidAssociationID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidAssociationID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Associate with invalid subnet ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_route_table(route_table.id, "subnet-1234abcd")
|
||||
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidSubnetID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Associate with invalid route table ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.associate_route_table("rtb-1234abcd", subnet.id)
|
||||
cm.exception.code.should.equal('InvalidRouteTableID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidRouteTableID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -236,7 +239,7 @@ def test_route_table_replace_route_table_association():
|
|||
Note: Boto has deprecated replace_route_table_assocation (which returns status)
|
||||
and now uses replace_route_table_assocation_with_assoc (which returns association ID).
|
||||
"""
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
route_table1 = conn.create_route_table(vpc.id)
|
||||
|
|
@ -267,7 +270,8 @@ def test_route_table_replace_route_table_association():
|
|||
|
||||
# Replace Association
|
||||
association_id2 = conn.replace_route_table_association_with_assoc(
|
||||
association_id1, route_table2.id)
|
||||
association_id1, route_table2.id
|
||||
)
|
||||
|
||||
# Refresh
|
||||
route_table1 = conn.get_all_route_tables(route_table1.id)[0]
|
||||
|
|
@ -284,120 +288,128 @@ def test_route_table_replace_route_table_association():
|
|||
|
||||
# Replace Association is idempotent
|
||||
association_id_idempotent = conn.replace_route_table_association_with_assoc(
|
||||
association_id2, route_table2.id)
|
||||
association_id2, route_table2.id
|
||||
)
|
||||
association_id_idempotent.should.equal(association_id2)
|
||||
|
||||
# Error: Replace association with invalid association ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.replace_route_table_association_with_assoc(
|
||||
"rtbassoc-1234abcd", route_table1.id)
|
||||
cm.exception.code.should.equal('InvalidAssociationID.NotFound')
|
||||
"rtbassoc-1234abcd", route_table1.id
|
||||
)
|
||||
cm.exception.code.should.equal("InvalidAssociationID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
# Error: Replace association with invalid route table ID
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.replace_route_table_association_with_assoc(
|
||||
association_id2, "rtb-1234abcd")
|
||||
cm.exception.code.should.equal('InvalidRouteTableID.NotFound')
|
||||
conn.replace_route_table_association_with_assoc(association_id2, "rtb-1234abcd")
|
||||
cm.exception.code.should.equal("InvalidRouteTableID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_route_table_get_by_tag():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
vpc = conn.create_vpc('10.0.0.0/16')
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
route_table = conn.create_route_table(vpc.id)
|
||||
route_table.add_tag('Name', 'TestRouteTable')
|
||||
route_table.add_tag("Name", "TestRouteTable")
|
||||
|
||||
route_tables = conn.get_all_route_tables(
|
||||
filters={'tag:Name': 'TestRouteTable'})
|
||||
route_tables = conn.get_all_route_tables(filters={"tag:Name": "TestRouteTable"})
|
||||
|
||||
route_tables.should.have.length_of(1)
|
||||
route_tables[0].vpc_id.should.equal(vpc.id)
|
||||
route_tables[0].id.should.equal(route_table.id)
|
||||
route_tables[0].tags.should.have.length_of(1)
|
||||
route_tables[0].tags['Name'].should.equal('TestRouteTable')
|
||||
route_tables[0].tags["Name"].should.equal("TestRouteTable")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_route_table_get_by_tag_boto3():
|
||||
ec2 = boto3.resource('ec2', region_name='eu-central-1')
|
||||
ec2 = boto3.resource("ec2", region_name="eu-central-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
route_table = ec2.create_route_table(VpcId=vpc.id)
|
||||
route_table.create_tags(Tags=[{'Key': 'Name', 'Value': 'TestRouteTable'}])
|
||||
route_table.create_tags(Tags=[{"Key": "Name", "Value": "TestRouteTable"}])
|
||||
|
||||
filters = [{'Name': 'tag:Name', 'Values': ['TestRouteTable']}]
|
||||
filters = [{"Name": "tag:Name", "Values": ["TestRouteTable"]}]
|
||||
route_tables = list(ec2.route_tables.filter(Filters=filters))
|
||||
|
||||
route_tables.should.have.length_of(1)
|
||||
route_tables[0].vpc_id.should.equal(vpc.id)
|
||||
route_tables[0].id.should.equal(route_table.id)
|
||||
route_tables[0].tags.should.have.length_of(1)
|
||||
route_tables[0].tags[0].should.equal(
|
||||
{'Key': 'Name', 'Value': 'TestRouteTable'})
|
||||
route_tables[0].tags[0].should.equal({"Key": "Name", "Value": "TestRouteTable"})
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_routes_additional():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
main_route_table = conn.get_all_route_tables(filters={'vpc-id': vpc.id})[0]
|
||||
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[0]
|
||||
local_route = main_route_table.routes[0]
|
||||
igw = conn.create_internet_gateway()
|
||||
ROUTE_CIDR = "10.0.0.4/24"
|
||||
|
||||
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
|
||||
|
||||
main_route_table = conn.get_all_route_tables(
|
||||
filters={'vpc-id': vpc.id})[0] # Refresh route table
|
||||
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[
|
||||
0
|
||||
] # Refresh route table
|
||||
|
||||
main_route_table.routes.should.have.length_of(2)
|
||||
new_routes = [
|
||||
route for route in main_route_table.routes if route.destination_cidr_block != vpc.cidr_block]
|
||||
route
|
||||
for route in main_route_table.routes
|
||||
if route.destination_cidr_block != vpc.cidr_block
|
||||
]
|
||||
new_routes.should.have.length_of(1)
|
||||
|
||||
new_route = new_routes[0]
|
||||
new_route.gateway_id.should.equal(igw.id)
|
||||
new_route.instance_id.should.be.none
|
||||
new_route.state.should.equal('active')
|
||||
new_route.state.should.equal("active")
|
||||
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
|
||||
|
||||
conn.delete_route(main_route_table.id, ROUTE_CIDR)
|
||||
|
||||
main_route_table = conn.get_all_route_tables(
|
||||
filters={'vpc-id': vpc.id})[0] # Refresh route table
|
||||
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[
|
||||
0
|
||||
] # Refresh route table
|
||||
|
||||
main_route_table.routes.should.have.length_of(1)
|
||||
new_routes = [
|
||||
route for route in main_route_table.routes if route.destination_cidr_block != vpc.cidr_block]
|
||||
route
|
||||
for route in main_route_table.routes
|
||||
if route.destination_cidr_block != vpc.cidr_block
|
||||
]
|
||||
new_routes.should.have.length_of(0)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_route(main_route_table.id, ROUTE_CIDR)
|
||||
cm.exception.code.should.equal('InvalidRoute.NotFound')
|
||||
cm.exception.code.should.equal("InvalidRoute.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_routes_replace():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
main_route_table = conn.get_all_route_tables(
|
||||
filters={'association.main': 'true', 'vpc-id': vpc.id})[0]
|
||||
filters={"association.main": "true", "vpc-id": vpc.id}
|
||||
)[0]
|
||||
local_route = main_route_table.routes[0]
|
||||
ROUTE_CIDR = "10.0.0.4/24"
|
||||
|
||||
# Various route targets
|
||||
igw = conn.create_internet_gateway()
|
||||
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
# Create initial route
|
||||
|
|
@ -407,17 +419,19 @@ def test_routes_replace():
|
|||
def get_target_route():
|
||||
route_table = conn.get_all_route_tables(main_route_table.id)[0]
|
||||
routes = [
|
||||
route for route in route_table.routes if route.destination_cidr_block != vpc.cidr_block]
|
||||
route
|
||||
for route in route_table.routes
|
||||
if route.destination_cidr_block != vpc.cidr_block
|
||||
]
|
||||
routes.should.have.length_of(1)
|
||||
return routes[0]
|
||||
|
||||
conn.replace_route(main_route_table.id, ROUTE_CIDR,
|
||||
instance_id=instance.id)
|
||||
conn.replace_route(main_route_table.id, ROUTE_CIDR, instance_id=instance.id)
|
||||
|
||||
target_route = get_target_route()
|
||||
target_route.gateway_id.should.be.none
|
||||
target_route.instance_id.should.equal(instance.id)
|
||||
target_route.state.should.equal('active')
|
||||
target_route.state.should.equal("active")
|
||||
target_route.destination_cidr_block.should.equal(ROUTE_CIDR)
|
||||
|
||||
conn.replace_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
|
||||
|
|
@ -425,12 +439,12 @@ def test_routes_replace():
|
|||
target_route = get_target_route()
|
||||
target_route.gateway_id.should.equal(igw.id)
|
||||
target_route.instance_id.should.be.none
|
||||
target_route.state.should.equal('active')
|
||||
target_route.state.should.equal("active")
|
||||
target_route.destination_cidr_block.should.equal(ROUTE_CIDR)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.replace_route('rtb-1234abcd', ROUTE_CIDR, gateway_id=igw.id)
|
||||
cm.exception.code.should.equal('InvalidRouteTableID.NotFound')
|
||||
conn.replace_route("rtb-1234abcd", ROUTE_CIDR, gateway_id=igw.id)
|
||||
cm.exception.code.should.equal("InvalidRouteTableID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -438,7 +452,7 @@ def test_routes_replace():
|
|||
@requires_boto_gte("2.19.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_routes_not_supported():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
main_route_table = conn.get_all_route_tables()[0]
|
||||
local_route = main_route_table.routes[0]
|
||||
|
|
@ -447,42 +461,49 @@ def test_routes_not_supported():
|
|||
|
||||
# Create
|
||||
conn.create_route.when.called_with(
|
||||
main_route_table.id, ROUTE_CIDR, interface_id='eni-1234abcd').should.throw(NotImplementedError)
|
||||
main_route_table.id, ROUTE_CIDR, interface_id="eni-1234abcd"
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
# Replace
|
||||
igw = conn.create_internet_gateway()
|
||||
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
|
||||
conn.replace_route.when.called_with(
|
||||
main_route_table.id, ROUTE_CIDR, interface_id='eni-1234abcd').should.throw(NotImplementedError)
|
||||
main_route_table.id, ROUTE_CIDR, interface_id="eni-1234abcd"
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
|
||||
@requires_boto_gte("2.34.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_routes_vpc_peering_connection():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
main_route_table = conn.get_all_route_tables(
|
||||
filters={'association.main': 'true', 'vpc-id': vpc.id})[0]
|
||||
filters={"association.main": "true", "vpc-id": vpc.id}
|
||||
)[0]
|
||||
local_route = main_route_table.routes[0]
|
||||
ROUTE_CIDR = "10.0.0.4/24"
|
||||
|
||||
peer_vpc = conn.create_vpc("11.0.0.0/16")
|
||||
vpc_pcx = conn.create_vpc_peering_connection(vpc.id, peer_vpc.id)
|
||||
|
||||
conn.create_route(main_route_table.id, ROUTE_CIDR,
|
||||
vpc_peering_connection_id=vpc_pcx.id)
|
||||
conn.create_route(
|
||||
main_route_table.id, ROUTE_CIDR, vpc_peering_connection_id=vpc_pcx.id
|
||||
)
|
||||
|
||||
# Refresh route table
|
||||
main_route_table = conn.get_all_route_tables(main_route_table.id)[0]
|
||||
new_routes = [
|
||||
route for route in main_route_table.routes if route.destination_cidr_block != vpc.cidr_block]
|
||||
route
|
||||
for route in main_route_table.routes
|
||||
if route.destination_cidr_block != vpc.cidr_block
|
||||
]
|
||||
new_routes.should.have.length_of(1)
|
||||
|
||||
new_route = new_routes[0]
|
||||
new_route.gateway_id.should.be.none
|
||||
new_route.instance_id.should.be.none
|
||||
new_route.vpc_peering_connection_id.should.equal(vpc_pcx.id)
|
||||
new_route.state.should.equal('blackhole')
|
||||
new_route.state.should.equal("blackhole")
|
||||
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
|
||||
|
||||
|
||||
|
|
@ -490,10 +511,11 @@ def test_routes_vpc_peering_connection():
|
|||
@mock_ec2_deprecated
|
||||
def test_routes_vpn_gateway():
|
||||
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
main_route_table = conn.get_all_route_tables(
|
||||
filters={'association.main': 'true', 'vpc-id': vpc.id})[0]
|
||||
filters={"association.main": "true", "vpc-id": vpc.id}
|
||||
)[0]
|
||||
ROUTE_CIDR = "10.0.0.4/24"
|
||||
|
||||
vpn_gw = conn.create_vpn_gateway(type="ipsec.1")
|
||||
|
|
@ -502,7 +524,10 @@ def test_routes_vpn_gateway():
|
|||
|
||||
main_route_table = conn.get_all_route_tables(main_route_table.id)[0]
|
||||
new_routes = [
|
||||
route for route in main_route_table.routes if route.destination_cidr_block != vpc.cidr_block]
|
||||
route
|
||||
for route in main_route_table.routes
|
||||
if route.destination_cidr_block != vpc.cidr_block
|
||||
]
|
||||
new_routes.should.have.length_of(1)
|
||||
|
||||
new_route = new_routes[0]
|
||||
|
|
@ -514,7 +539,7 @@ def test_routes_vpn_gateway():
|
|||
@mock_ec2_deprecated
|
||||
def test_network_acl_tagging():
|
||||
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
conn = boto.connect_vpc("the_key", "the secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
route_table = conn.create_route_table(vpc.id)
|
||||
|
|
@ -525,17 +550,16 @@ def test_network_acl_tagging():
|
|||
tag.value.should.equal("some value")
|
||||
|
||||
all_route_tables = conn.get_all_route_tables()
|
||||
test_route_table = next(na for na in all_route_tables
|
||||
if na.id == route_table.id)
|
||||
test_route_table = next(na for na in all_route_tables if na.id == route_table.id)
|
||||
test_route_table.tags.should.have.length_of(1)
|
||||
test_route_table.tags["a key"].should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_route_with_invalid_destination_cidr_block_parameter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
|
|
@ -546,9 +570,51 @@ def test_create_route_with_invalid_destination_cidr_block_parameter():
|
|||
vpc.attach_internet_gateway(InternetGatewayId=internet_gateway.id)
|
||||
internet_gateway.reload()
|
||||
|
||||
destination_cidr_block = '1000.1.0.0/20'
|
||||
destination_cidr_block = "1000.1.0.0/20"
|
||||
with assert_raises(ClientError) as ex:
|
||||
route = route_table.create_route(DestinationCidrBlock=destination_cidr_block, GatewayId=internet_gateway.id)
|
||||
route = route_table.create_route(
|
||||
DestinationCidrBlock=destination_cidr_block, GatewayId=internet_gateway.id
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidParameterValue) when calling the CreateRoute "
|
||||
"operation: Value ({}) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.".format(destination_cidr_block))
|
||||
"operation: Value ({}) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.".format(
|
||||
destination_cidr_block
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_route_tables_with_nat_gateway():
|
||||
ec2 = boto3.client("ec2", region_name="us-west-1")
|
||||
vpc_id = ec2.create_vpc(CidrBlock="192.168.0.0/23")["Vpc"]["VpcId"]
|
||||
igw_id = ec2.create_internet_gateway()["InternetGateway"]["InternetGatewayId"]
|
||||
ec2.attach_internet_gateway(VpcId=vpc_id, InternetGatewayId=igw_id)
|
||||
az = ec2.describe_availability_zones()["AvailabilityZones"][0]["ZoneName"]
|
||||
sn_id = ec2.create_subnet(
|
||||
AvailabilityZone=az, CidrBlock="192.168.0.0/24", VpcId=vpc_id
|
||||
)["Subnet"]["SubnetId"]
|
||||
route_table_id = ec2.create_route_table(VpcId=vpc_id)["RouteTable"]["RouteTableId"]
|
||||
ec2.associate_route_table(SubnetId=sn_id, RouteTableId=route_table_id)
|
||||
alloc_id = ec2.allocate_address(Domain="vpc")["AllocationId"]
|
||||
nat_gw_id = ec2.create_nat_gateway(SubnetId=sn_id, AllocationId=alloc_id)[
|
||||
"NatGateway"
|
||||
]["NatGatewayId"]
|
||||
ec2.create_route(
|
||||
DestinationCidrBlock="0.0.0.0/0",
|
||||
NatGatewayId=nat_gw_id,
|
||||
RouteTableId=route_table_id,
|
||||
)
|
||||
|
||||
route_table = ec2.describe_route_tables(
|
||||
Filters=[{"Name": "route-table-id", "Values": [route_table_id]}]
|
||||
)["RouteTables"][0]
|
||||
nat_gw_routes = [
|
||||
route
|
||||
for route in route_table["Routes"]
|
||||
if route["DestinationCidrBlock"] == "0.0.0.0/0"
|
||||
]
|
||||
|
||||
nat_gw_routes.should.have.length_of(1)
|
||||
nat_gw_routes[0]["DestinationCidrBlock"].should.equal("0.0.0.0/0")
|
||||
nat_gw_routes[0]["NatGatewayId"].should.equal(nat_gw_id)
|
||||
nat_gw_routes[0]["State"].should.equal("active")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,26 +1,25 @@
|
|||
from __future__ import unicode_literals
|
||||
import re
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
def test_ec2_server_get():
|
||||
backend = server.create_backend_app("ec2")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get(
|
||||
'/?Action=RunInstances&ImageId=ami-60a54009',
|
||||
headers={"Host": "ec2.us-east-1.amazonaws.com"}
|
||||
)
|
||||
|
||||
groups = re.search("<instanceId>(.*)</instanceId>",
|
||||
res.data.decode('utf-8'))
|
||||
instance_id = groups.groups()[0]
|
||||
|
||||
res = test_client.get('/?Action=DescribeInstances')
|
||||
res.data.decode('utf-8').should.contain(instance_id)
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
def test_ec2_server_get():
|
||||
backend = server.create_backend_app("ec2")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get(
|
||||
"/?Action=RunInstances&ImageId=ami-60a54009",
|
||||
headers={"Host": "ec2.us-east-1.amazonaws.com"},
|
||||
)
|
||||
|
||||
groups = re.search("<instanceId>(.*)</instanceId>", res.data.decode("utf-8"))
|
||||
instance_id = groups.groups()[0]
|
||||
|
||||
res = test_client.get("/?Action=DescribeInstances")
|
||||
res.data.decode("utf-8").should.contain(instance_id)
|
||||
|
|
|
|||
|
|
@ -4,384 +4,376 @@ import boto3
|
|||
import sure # noqa
|
||||
|
||||
from moto import mock_ec2
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
|
||||
def get_subnet_id(conn):
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
|
||||
subnet_id = subnet['SubnetId']
|
||||
VpcId=vpc["VpcId"], CidrBlock="10.0.0.0/16", AvailabilityZone="us-east-1a"
|
||||
)["Subnet"]
|
||||
subnet_id = subnet["SubnetId"]
|
||||
return subnet_id
|
||||
|
||||
|
||||
def spot_config(subnet_id, allocation_strategy="lowestPrice"):
|
||||
return {
|
||||
'ClientToken': 'string',
|
||||
'SpotPrice': '0.12',
|
||||
'TargetCapacity': 6,
|
||||
'IamFleetRole': 'arn:aws:iam::123456789012:role/fleet',
|
||||
'LaunchSpecifications': [{
|
||||
'ImageId': 'ami-123',
|
||||
'KeyName': 'my-key',
|
||||
'SecurityGroups': [
|
||||
{
|
||||
'GroupId': 'sg-123'
|
||||
},
|
||||
],
|
||||
'UserData': 'some user data',
|
||||
'InstanceType': 't2.small',
|
||||
'BlockDeviceMappings': [
|
||||
{
|
||||
'VirtualName': 'string',
|
||||
'DeviceName': 'string',
|
||||
'Ebs': {
|
||||
'SnapshotId': 'string',
|
||||
'VolumeSize': 123,
|
||||
'DeleteOnTermination': True | False,
|
||||
'VolumeType': 'standard',
|
||||
'Iops': 123,
|
||||
'Encrypted': True | False
|
||||
"ClientToken": "string",
|
||||
"SpotPrice": "0.12",
|
||||
"TargetCapacity": 6,
|
||||
"IamFleetRole": "arn:aws:iam::{}:role/fleet".format(ACCOUNT_ID),
|
||||
"LaunchSpecifications": [
|
||||
{
|
||||
"ImageId": "ami-123",
|
||||
"KeyName": "my-key",
|
||||
"SecurityGroups": [{"GroupId": "sg-123"}],
|
||||
"UserData": "some user data",
|
||||
"InstanceType": "t2.small",
|
||||
"BlockDeviceMappings": [
|
||||
{
|
||||
"VirtualName": "string",
|
||||
"DeviceName": "string",
|
||||
"Ebs": {
|
||||
"SnapshotId": "string",
|
||||
"VolumeSize": 123,
|
||||
"DeleteOnTermination": True | False,
|
||||
"VolumeType": "standard",
|
||||
"Iops": 123,
|
||||
"Encrypted": True | False,
|
||||
},
|
||||
'NoDevice': 'string'
|
||||
"NoDevice": "string",
|
||||
}
|
||||
],
|
||||
"Monitoring": {"Enabled": True},
|
||||
"SubnetId": subnet_id,
|
||||
"IamInstanceProfile": {
|
||||
"Arn": "arn:aws:iam::{}:role/fleet".format(ACCOUNT_ID)
|
||||
},
|
||||
],
|
||||
'Monitoring': {
|
||||
'Enabled': True
|
||||
"EbsOptimized": False,
|
||||
"WeightedCapacity": 2.0,
|
||||
"SpotPrice": "0.13",
|
||||
},
|
||||
'SubnetId': subnet_id,
|
||||
'IamInstanceProfile': {
|
||||
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
||||
},
|
||||
'EbsOptimized': False,
|
||||
'WeightedCapacity': 2.0,
|
||||
'SpotPrice': '0.13',
|
||||
}, {
|
||||
'ImageId': 'ami-123',
|
||||
'KeyName': 'my-key',
|
||||
'SecurityGroups': [
|
||||
{
|
||||
'GroupId': 'sg-123'
|
||||
{
|
||||
"ImageId": "ami-123",
|
||||
"KeyName": "my-key",
|
||||
"SecurityGroups": [{"GroupId": "sg-123"}],
|
||||
"UserData": "some user data",
|
||||
"InstanceType": "t2.large",
|
||||
"Monitoring": {"Enabled": True},
|
||||
"SubnetId": subnet_id,
|
||||
"IamInstanceProfile": {
|
||||
"Arn": "arn:aws:iam::{}:role/fleet".format(ACCOUNT_ID)
|
||||
},
|
||||
],
|
||||
'UserData': 'some user data',
|
||||
'InstanceType': 't2.large',
|
||||
'Monitoring': {
|
||||
'Enabled': True
|
||||
"EbsOptimized": False,
|
||||
"WeightedCapacity": 4.0,
|
||||
"SpotPrice": "10.00",
|
||||
},
|
||||
'SubnetId': subnet_id,
|
||||
'IamInstanceProfile': {
|
||||
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
||||
},
|
||||
'EbsOptimized': False,
|
||||
'WeightedCapacity': 4.0,
|
||||
'SpotPrice': '10.00',
|
||||
}],
|
||||
'AllocationStrategy': allocation_strategy,
|
||||
'FulfilledCapacity': 6,
|
||||
],
|
||||
"AllocationStrategy": allocation_strategy,
|
||||
"FulfilledCapacity": 6,
|
||||
}
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_spot_fleet_with_lowest_price():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
len(spot_fleet_requests).should.equal(1)
|
||||
spot_fleet_request = spot_fleet_requests[0]
|
||||
spot_fleet_request['SpotFleetRequestState'].should.equal("active")
|
||||
spot_fleet_config = spot_fleet_request['SpotFleetRequestConfig']
|
||||
spot_fleet_request["SpotFleetRequestState"].should.equal("active")
|
||||
spot_fleet_config = spot_fleet_request["SpotFleetRequestConfig"]
|
||||
|
||||
spot_fleet_config['SpotPrice'].should.equal('0.12')
|
||||
spot_fleet_config['TargetCapacity'].should.equal(6)
|
||||
spot_fleet_config['IamFleetRole'].should.equal(
|
||||
'arn:aws:iam::123456789012:role/fleet')
|
||||
spot_fleet_config['AllocationStrategy'].should.equal('lowestPrice')
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(6.0)
|
||||
spot_fleet_config["SpotPrice"].should.equal("0.12")
|
||||
spot_fleet_config["TargetCapacity"].should.equal(6)
|
||||
spot_fleet_config["IamFleetRole"].should.equal(
|
||||
"arn:aws:iam::{}:role/fleet".format(ACCOUNT_ID)
|
||||
)
|
||||
spot_fleet_config["AllocationStrategy"].should.equal("lowestPrice")
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(6.0)
|
||||
|
||||
len(spot_fleet_config['LaunchSpecifications']).should.equal(2)
|
||||
launch_spec = spot_fleet_config['LaunchSpecifications'][0]
|
||||
len(spot_fleet_config["LaunchSpecifications"]).should.equal(2)
|
||||
launch_spec = spot_fleet_config["LaunchSpecifications"][0]
|
||||
|
||||
launch_spec['EbsOptimized'].should.equal(False)
|
||||
launch_spec['SecurityGroups'].should.equal([{"GroupId": "sg-123"}])
|
||||
launch_spec['IamInstanceProfile'].should.equal(
|
||||
{"Arn": "arn:aws:iam::123456789012:role/fleet"})
|
||||
launch_spec['ImageId'].should.equal("ami-123")
|
||||
launch_spec['InstanceType'].should.equal("t2.small")
|
||||
launch_spec['KeyName'].should.equal("my-key")
|
||||
launch_spec['Monitoring'].should.equal({"Enabled": True})
|
||||
launch_spec['SpotPrice'].should.equal("0.13")
|
||||
launch_spec['SubnetId'].should.equal(subnet_id)
|
||||
launch_spec['UserData'].should.equal("some user data")
|
||||
launch_spec['WeightedCapacity'].should.equal(2.0)
|
||||
launch_spec["EbsOptimized"].should.equal(False)
|
||||
launch_spec["SecurityGroups"].should.equal([{"GroupId": "sg-123"}])
|
||||
launch_spec["IamInstanceProfile"].should.equal(
|
||||
{"Arn": "arn:aws:iam::{}:role/fleet".format(ACCOUNT_ID)}
|
||||
)
|
||||
launch_spec["ImageId"].should.equal("ami-123")
|
||||
launch_spec["InstanceType"].should.equal("t2.small")
|
||||
launch_spec["KeyName"].should.equal("my-key")
|
||||
launch_spec["Monitoring"].should.equal({"Enabled": True})
|
||||
launch_spec["SpotPrice"].should.equal("0.13")
|
||||
launch_spec["SubnetId"].should.equal(subnet_id)
|
||||
launch_spec["UserData"].should.equal("some user data")
|
||||
launch_spec["WeightedCapacity"].should.equal(2.0)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(3)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_diversified_spot_fleet():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
diversified_config = spot_config(
|
||||
subnet_id, allocation_strategy='diversified')
|
||||
diversified_config = spot_config(subnet_id, allocation_strategy="diversified")
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=diversified_config
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_res = conn.request_spot_fleet(SpotFleetRequestConfig=diversified_config)
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(2)
|
||||
instance_types = set([instance['InstanceType'] for instance in instances])
|
||||
instance_types = set([instance["InstanceType"] for instance in instances])
|
||||
instance_types.should.equal(set(["t2.small", "t2.large"]))
|
||||
instances[0]['InstanceId'].should.contain("i-")
|
||||
instances[0]["InstanceId"].should.contain("i-")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_spot_fleet_request_with_tag_spec():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
tag_spec = [
|
||||
{
|
||||
'ResourceType': 'instance',
|
||||
'Tags': [
|
||||
{
|
||||
'Key': 'tag-1',
|
||||
'Value': 'foo',
|
||||
},
|
||||
{
|
||||
'Key': 'tag-2',
|
||||
'Value': 'bar',
|
||||
},
|
||||
]
|
||||
},
|
||||
"ResourceType": "instance",
|
||||
"Tags": [
|
||||
{"Key": "tag-1", "Value": "foo"},
|
||||
{"Key": "tag-2", "Value": "bar"},
|
||||
],
|
||||
}
|
||||
]
|
||||
config = spot_config(subnet_id)
|
||||
config['LaunchSpecifications'][0]['TagSpecifications'] = tag_spec
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=config
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
config["LaunchSpecifications"][0]["TagSpecifications"] = tag_spec
|
||||
spot_fleet_res = conn.request_spot_fleet(SpotFleetRequestConfig=config)
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
||||
spot_fleet_config = spot_fleet_requests[0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['LaunchSpecifications'][0]['TagSpecifications'][0][
|
||||
'ResourceType'].should.equal('instance')
|
||||
for tag in tag_spec[0]['Tags']:
|
||||
spot_fleet_config['LaunchSpecifications'][0]['TagSpecifications'][0]['Tags'].should.contain(tag)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
spot_fleet_config = spot_fleet_requests[0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["LaunchSpecifications"][0]["TagSpecifications"][0][
|
||||
"ResourceType"
|
||||
].should.equal("instance")
|
||||
for tag in tag_spec[0]["Tags"]:
|
||||
spot_fleet_config["LaunchSpecifications"][0]["TagSpecifications"][0][
|
||||
"Tags"
|
||||
].should.contain(tag)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = conn.describe_instances(InstanceIds=[i['InstanceId'] for i in instance_res['ActiveInstances']])
|
||||
for instance in instances['Reservations'][0]['Instances']:
|
||||
for tag in tag_spec[0]['Tags']:
|
||||
instance['Tags'].should.contain(tag)
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = conn.describe_instances(
|
||||
InstanceIds=[i["InstanceId"] for i in instance_res["ActiveInstances"]]
|
||||
)
|
||||
for instance in instances["Reservations"][0]["Instances"]:
|
||||
for tag in tag_spec[0]["Tags"]:
|
||||
instance["Tags"].should.contain(tag)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_cancel_spot_fleet_request():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.cancel_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id], TerminateInstances=True)
|
||||
SpotFleetRequestIds=[spot_fleet_id], TerminateInstances=True
|
||||
)
|
||||
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
len(spot_fleet_requests).should.equal(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_up():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=20)
|
||||
conn.modify_spot_fleet_request(SpotFleetRequestId=spot_fleet_id, TargetCapacity=20)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(10)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(20)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(20.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(20)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(20.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_up_diversified():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(
|
||||
subnet_id, allocation_strategy='diversified'),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id, allocation_strategy="diversified")
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=19)
|
||||
conn.modify_spot_fleet_request(SpotFleetRequestId=spot_fleet_id, TargetCapacity=19)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(7)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(19)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(20.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(19)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(20.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_down_no_terminate():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=1, ExcessCapacityTerminationPolicy="noTermination")
|
||||
SpotFleetRequestId=spot_fleet_id,
|
||||
TargetCapacity=1,
|
||||
ExcessCapacityTerminationPolicy="noTermination",
|
||||
)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(3)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(1)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(6.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(1)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(6.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_down_odd():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=7)
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=5)
|
||||
conn.modify_spot_fleet_request(SpotFleetRequestId=spot_fleet_id, TargetCapacity=7)
|
||||
conn.modify_spot_fleet_request(SpotFleetRequestId=spot_fleet_id, TargetCapacity=5)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(3)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(5)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(6.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(5)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(6.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_down():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=1)
|
||||
conn.modify_spot_fleet_request(SpotFleetRequestId=spot_fleet_id, TargetCapacity=1)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(1)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(1)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(2.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(1)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(2.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_spot_fleet_request_down_no_terminate_after_custom_terminate():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
spot_fleet_res = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||
)
|
||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||
spot_fleet_id = spot_fleet_res["SpotFleetRequestId"]
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
conn.terminate_instances(InstanceIds=[i['InstanceId'] for i in instances[1:]])
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
conn.terminate_instances(InstanceIds=[i["InstanceId"] for i in instances[1:]])
|
||||
|
||||
conn.modify_spot_fleet_request(
|
||||
SpotFleetRequestId=spot_fleet_id, TargetCapacity=1, ExcessCapacityTerminationPolicy="noTermination")
|
||||
SpotFleetRequestId=spot_fleet_id,
|
||||
TargetCapacity=1,
|
||||
ExcessCapacityTerminationPolicy="noTermination",
|
||||
)
|
||||
|
||||
instance_res = conn.describe_spot_fleet_instances(
|
||||
SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res['ActiveInstances']
|
||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||
instances = instance_res["ActiveInstances"]
|
||||
len(instances).should.equal(1)
|
||||
|
||||
spot_fleet_config = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs'][0]['SpotFleetRequestConfig']
|
||||
spot_fleet_config['TargetCapacity'].should.equal(1)
|
||||
spot_fleet_config['FulfilledCapacity'].should.equal(2.0)
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"][0]["SpotFleetRequestConfig"]
|
||||
spot_fleet_config["TargetCapacity"].should.equal(1)
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(2.0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_spot_fleet_without_spot_price():
|
||||
conn = boto3.client("ec2", region_name='us-west-2')
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
# remove prices to force a fallback to ondemand price
|
||||
spot_config_without_price = spot_config(subnet_id)
|
||||
del spot_config_without_price['SpotPrice']
|
||||
for spec in spot_config_without_price['LaunchSpecifications']:
|
||||
del spec['SpotPrice']
|
||||
del spot_config_without_price["SpotPrice"]
|
||||
for spec in spot_config_without_price["LaunchSpecifications"]:
|
||||
del spec["SpotPrice"]
|
||||
|
||||
spot_fleet_id = conn.request_spot_fleet(SpotFleetRequestConfig=spot_config_without_price)['SpotFleetRequestId']
|
||||
spot_fleet_id = conn.request_spot_fleet(
|
||||
SpotFleetRequestConfig=spot_config_without_price
|
||||
)["SpotFleetRequestId"]
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
len(spot_fleet_requests).should.equal(1)
|
||||
spot_fleet_request = spot_fleet_requests[0]
|
||||
spot_fleet_config = spot_fleet_request['SpotFleetRequestConfig']
|
||||
spot_fleet_config = spot_fleet_request["SpotFleetRequestConfig"]
|
||||
|
||||
len(spot_fleet_config['LaunchSpecifications']).should.equal(2)
|
||||
launch_spec1 = spot_fleet_config['LaunchSpecifications'][0]
|
||||
launch_spec2 = spot_fleet_config['LaunchSpecifications'][1]
|
||||
len(spot_fleet_config["LaunchSpecifications"]).should.equal(2)
|
||||
launch_spec1 = spot_fleet_config["LaunchSpecifications"][0]
|
||||
launch_spec2 = spot_fleet_config["LaunchSpecifications"][1]
|
||||
|
||||
# AWS will figure out the price
|
||||
assert 'SpotPrice' not in launch_spec1
|
||||
assert 'SpotPrice' not in launch_spec2
|
||||
assert "SpotPrice" not in launch_spec1
|
||||
assert "SpotPrice" not in launch_spec2
|
||||
|
|
|
|||
|
|
@ -16,14 +16,15 @@ from moto.core.utils import iso_8601_datetime_with_milliseconds
|
|||
|
||||
@mock_ec2
|
||||
def test_request_spot_instances():
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
||||
subnet = conn.create_subnet(
|
||||
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
|
||||
subnet_id = subnet['SubnetId']
|
||||
VpcId=vpc["VpcId"], CidrBlock="10.0.0.0/16", AvailabilityZone="us-east-1a"
|
||||
)["Subnet"]
|
||||
subnet_id = subnet["SubnetId"]
|
||||
|
||||
conn.create_security_group(GroupName='group1', Description='description')
|
||||
conn.create_security_group(GroupName='group2', Description='description')
|
||||
conn.create_security_group(GroupName="group1", Description="description")
|
||||
conn.create_security_group(GroupName="group2", Description="description")
|
||||
|
||||
start_dt = datetime.datetime(2013, 1, 1).replace(tzinfo=pytz.utc)
|
||||
end_dt = datetime.datetime(2013, 1, 2).replace(tzinfo=pytz.utc)
|
||||
|
|
@ -32,78 +33,79 @@ def test_request_spot_instances():
|
|||
|
||||
with assert_raises(ClientError) as ex:
|
||||
request = conn.request_spot_instances(
|
||||
SpotPrice="0.5", InstanceCount=1, Type='one-time',
|
||||
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
|
||||
AvailabilityZoneGroup='my-group',
|
||||
SpotPrice="0.5",
|
||||
InstanceCount=1,
|
||||
Type="one-time",
|
||||
ValidFrom=start,
|
||||
ValidUntil=end,
|
||||
LaunchGroup="the-group",
|
||||
AvailabilityZoneGroup="my-group",
|
||||
LaunchSpecification={
|
||||
"ImageId": 'ami-abcd1234',
|
||||
"ImageId": "ami-abcd1234",
|
||||
"KeyName": "test",
|
||||
"SecurityGroups": ['group1', 'group2'],
|
||||
"SecurityGroups": ["group1", "group2"],
|
||||
"UserData": "some test data",
|
||||
"InstanceType": 'm1.small',
|
||||
"Placement": {
|
||||
"AvailabilityZone": 'us-east-1c',
|
||||
},
|
||||
"InstanceType": "m1.small",
|
||||
"Placement": {"AvailabilityZone": "us-east-1c"},
|
||||
"KernelId": "test-kernel",
|
||||
"RamdiskId": "test-ramdisk",
|
||||
"Monitoring": {
|
||||
"Enabled": True,
|
||||
},
|
||||
"Monitoring": {"Enabled": True},
|
||||
"SubnetId": subnet_id,
|
||||
},
|
||||
DryRun=True,
|
||||
)
|
||||
ex.exception.response['Error']['Code'].should.equal('DryRunOperation')
|
||||
ex.exception.response['ResponseMetadata'][
|
||||
'HTTPStatusCode'].should.equal(400)
|
||||
ex.exception.response['Error']['Message'].should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the RequestSpotInstance operation: Request would have succeeded, but DryRun flag is set')
|
||||
ex.exception.response["Error"]["Code"].should.equal("DryRunOperation")
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"An error occurred (DryRunOperation) when calling the RequestSpotInstance operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
request = conn.request_spot_instances(
|
||||
SpotPrice="0.5", InstanceCount=1, Type='one-time',
|
||||
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
|
||||
AvailabilityZoneGroup='my-group',
|
||||
SpotPrice="0.5",
|
||||
InstanceCount=1,
|
||||
Type="one-time",
|
||||
ValidFrom=start,
|
||||
ValidUntil=end,
|
||||
LaunchGroup="the-group",
|
||||
AvailabilityZoneGroup="my-group",
|
||||
LaunchSpecification={
|
||||
"ImageId": 'ami-abcd1234',
|
||||
"ImageId": "ami-abcd1234",
|
||||
"KeyName": "test",
|
||||
"SecurityGroups": ['group1', 'group2'],
|
||||
"SecurityGroups": ["group1", "group2"],
|
||||
"UserData": "some test data",
|
||||
"InstanceType": 'm1.small',
|
||||
"Placement": {
|
||||
"AvailabilityZone": 'us-east-1c',
|
||||
},
|
||||
"InstanceType": "m1.small",
|
||||
"Placement": {"AvailabilityZone": "us-east-1c"},
|
||||
"KernelId": "test-kernel",
|
||||
"RamdiskId": "test-ramdisk",
|
||||
"Monitoring": {
|
||||
"Enabled": True,
|
||||
},
|
||||
"Monitoring": {"Enabled": True},
|
||||
"SubnetId": subnet_id,
|
||||
},
|
||||
)
|
||||
|
||||
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
|
||||
requests = conn.describe_spot_instance_requests()["SpotInstanceRequests"]
|
||||
requests.should.have.length_of(1)
|
||||
request = requests[0]
|
||||
|
||||
request['State'].should.equal("open")
|
||||
request['SpotPrice'].should.equal("0.5")
|
||||
request['Type'].should.equal('one-time')
|
||||
request['ValidFrom'].should.equal(start_dt)
|
||||
request['ValidUntil'].should.equal(end_dt)
|
||||
request['LaunchGroup'].should.equal("the-group")
|
||||
request['AvailabilityZoneGroup'].should.equal('my-group')
|
||||
request["State"].should.equal("open")
|
||||
request["SpotPrice"].should.equal("0.5")
|
||||
request["Type"].should.equal("one-time")
|
||||
request["ValidFrom"].should.equal(start_dt)
|
||||
request["ValidUntil"].should.equal(end_dt)
|
||||
request["LaunchGroup"].should.equal("the-group")
|
||||
request["AvailabilityZoneGroup"].should.equal("my-group")
|
||||
|
||||
launch_spec = request['LaunchSpecification']
|
||||
security_group_names = [group['GroupName']
|
||||
for group in launch_spec['SecurityGroups']]
|
||||
set(security_group_names).should.equal(set(['group1', 'group2']))
|
||||
launch_spec = request["LaunchSpecification"]
|
||||
security_group_names = [
|
||||
group["GroupName"] for group in launch_spec["SecurityGroups"]
|
||||
]
|
||||
set(security_group_names).should.equal(set(["group1", "group2"]))
|
||||
|
||||
launch_spec['ImageId'].should.equal('ami-abcd1234')
|
||||
launch_spec['KeyName'].should.equal("test")
|
||||
launch_spec['InstanceType'].should.equal('m1.small')
|
||||
launch_spec['KernelId'].should.equal("test-kernel")
|
||||
launch_spec['RamdiskId'].should.equal("test-ramdisk")
|
||||
launch_spec['SubnetId'].should.equal(subnet_id)
|
||||
launch_spec["ImageId"].should.equal("ami-abcd1234")
|
||||
launch_spec["KeyName"].should.equal("test")
|
||||
launch_spec["InstanceType"].should.equal("m1.small")
|
||||
launch_spec["KernelId"].should.equal("test-kernel")
|
||||
launch_spec["RamdiskId"].should.equal("test-ramdisk")
|
||||
launch_spec["SubnetId"].should.equal(subnet_id)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
|
@ -111,58 +113,55 @@ def test_request_spot_instances_default_arguments():
|
|||
"""
|
||||
Test that moto set the correct default arguments
|
||||
"""
|
||||
conn = boto3.client('ec2', 'us-east-1')
|
||||
conn = boto3.client("ec2", "us-east-1")
|
||||
|
||||
request = conn.request_spot_instances(
|
||||
SpotPrice="0.5",
|
||||
LaunchSpecification={
|
||||
"ImageId": 'ami-abcd1234',
|
||||
}
|
||||
SpotPrice="0.5", LaunchSpecification={"ImageId": "ami-abcd1234"}
|
||||
)
|
||||
|
||||
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
|
||||
requests = conn.describe_spot_instance_requests()["SpotInstanceRequests"]
|
||||
requests.should.have.length_of(1)
|
||||
request = requests[0]
|
||||
|
||||
request['State'].should.equal("open")
|
||||
request['SpotPrice'].should.equal("0.5")
|
||||
request['Type'].should.equal('one-time')
|
||||
request.shouldnt.contain('ValidFrom')
|
||||
request.shouldnt.contain('ValidUntil')
|
||||
request.shouldnt.contain('LaunchGroup')
|
||||
request.shouldnt.contain('AvailabilityZoneGroup')
|
||||
request["State"].should.equal("open")
|
||||
request["SpotPrice"].should.equal("0.5")
|
||||
request["Type"].should.equal("one-time")
|
||||
request.shouldnt.contain("ValidFrom")
|
||||
request.shouldnt.contain("ValidUntil")
|
||||
request.shouldnt.contain("LaunchGroup")
|
||||
request.shouldnt.contain("AvailabilityZoneGroup")
|
||||
|
||||
launch_spec = request['LaunchSpecification']
|
||||
launch_spec = request["LaunchSpecification"]
|
||||
|
||||
security_group_names = [group['GroupName']
|
||||
for group in launch_spec['SecurityGroups']]
|
||||
security_group_names = [
|
||||
group["GroupName"] for group in launch_spec["SecurityGroups"]
|
||||
]
|
||||
security_group_names.should.equal(["default"])
|
||||
|
||||
launch_spec['ImageId'].should.equal('ami-abcd1234')
|
||||
request.shouldnt.contain('KeyName')
|
||||
launch_spec['InstanceType'].should.equal('m1.small')
|
||||
request.shouldnt.contain('KernelId')
|
||||
request.shouldnt.contain('RamdiskId')
|
||||
request.shouldnt.contain('SubnetId')
|
||||
launch_spec["ImageId"].should.equal("ami-abcd1234")
|
||||
request.shouldnt.contain("KeyName")
|
||||
launch_spec["InstanceType"].should.equal("m1.small")
|
||||
request.shouldnt.contain("KernelId")
|
||||
request.shouldnt.contain("RamdiskId")
|
||||
request.shouldnt.contain("SubnetId")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_cancel_spot_instance_request():
|
||||
conn = boto.connect_ec2()
|
||||
|
||||
conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
|
||||
requests = conn.get_all_spot_instance_requests()
|
||||
requests.should.have.length_of(1)
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.cancel_spot_instance_requests([requests[0].id], dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.cancel_spot_instance_requests([requests[0].id])
|
||||
|
||||
|
|
@ -177,9 +176,7 @@ def test_request_spot_instances_fulfilled():
|
|||
"""
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
|
||||
request = conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
|
||||
requests = conn.get_all_spot_instance_requests()
|
||||
requests.should.have.length_of(1)
|
||||
|
|
@ -187,7 +184,7 @@ def test_request_spot_instances_fulfilled():
|
|||
|
||||
request.state.should.equal("open")
|
||||
|
||||
get_model('SpotInstanceRequest', 'us-east-1')[0].state = 'active'
|
||||
get_model("SpotInstanceRequest", "us-east-1")[0].state = "active"
|
||||
|
||||
requests = conn.get_all_spot_instance_requests()
|
||||
requests.should.have.length_of(1)
|
||||
|
|
@ -203,18 +200,16 @@ def test_tag_spot_instance_request():
|
|||
"""
|
||||
conn = boto.connect_ec2()
|
||||
|
||||
request = conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
request[0].add_tag('tag1', 'value1')
|
||||
request[0].add_tag('tag2', 'value2')
|
||||
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
request[0].add_tag("tag1", "value1")
|
||||
request[0].add_tag("tag2", "value2")
|
||||
|
||||
requests = conn.get_all_spot_instance_requests()
|
||||
requests.should.have.length_of(1)
|
||||
request = requests[0]
|
||||
|
||||
tag_dict = dict(request.tags)
|
||||
tag_dict.should.equal({'tag1': 'value1', 'tag2': 'value2'})
|
||||
tag_dict.should.equal({"tag1": "value1", "tag2": "value2"})
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
|
|
@ -224,45 +219,38 @@ def test_get_all_spot_instance_requests_filtering():
|
|||
"""
|
||||
conn = boto.connect_ec2()
|
||||
|
||||
request1 = conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
request2 = conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234',
|
||||
)
|
||||
request1[0].add_tag('tag1', 'value1')
|
||||
request1[0].add_tag('tag2', 'value2')
|
||||
request2[0].add_tag('tag1', 'value1')
|
||||
request2[0].add_tag('tag2', 'wrong')
|
||||
request1 = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
request2 = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
request1[0].add_tag("tag1", "value1")
|
||||
request1[0].add_tag("tag2", "value2")
|
||||
request2[0].add_tag("tag1", "value1")
|
||||
request2[0].add_tag("tag2", "wrong")
|
||||
|
||||
requests = conn.get_all_spot_instance_requests(filters={'state': 'active'})
|
||||
requests = conn.get_all_spot_instance_requests(filters={"state": "active"})
|
||||
requests.should.have.length_of(0)
|
||||
|
||||
requests = conn.get_all_spot_instance_requests(filters={'state': 'open'})
|
||||
requests = conn.get_all_spot_instance_requests(filters={"state": "open"})
|
||||
requests.should.have.length_of(3)
|
||||
|
||||
requests = conn.get_all_spot_instance_requests(
|
||||
filters={'tag:tag1': 'value1'})
|
||||
requests = conn.get_all_spot_instance_requests(filters={"tag:tag1": "value1"})
|
||||
requests.should.have.length_of(2)
|
||||
|
||||
requests = conn.get_all_spot_instance_requests(
|
||||
filters={'tag:tag1': 'value1', 'tag:tag2': 'value2'})
|
||||
filters={"tag:tag1": "value1", "tag:tag2": "value2"}
|
||||
)
|
||||
requests.should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_request_spot_instances_setting_instance_id():
|
||||
conn = boto.ec2.connect_to_region("us-east-1")
|
||||
request = conn.request_spot_instances(
|
||||
price=0.5, image_id='ami-abcd1234')
|
||||
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
|
||||
|
||||
req = get_model('SpotInstanceRequest', 'us-east-1')[0]
|
||||
req.state = 'active'
|
||||
req.instance_id = 'i-12345678'
|
||||
req = get_model("SpotInstanceRequest", "us-east-1")[0]
|
||||
req.state = "active"
|
||||
req.instance_id = "i-12345678"
|
||||
|
||||
request = conn.get_all_spot_instance_requests()[0]
|
||||
assert request.state == 'active'
|
||||
assert request.instance_id == 'i-12345678'
|
||||
assert request.state == "active"
|
||||
assert request.instance_id == "i-12345678"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises # noqa
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -10,14 +11,15 @@ from boto.exception import EC2ResponseError
|
|||
from botocore.exceptions import ParamValidationError, ClientError
|
||||
import json
|
||||
import sure # noqa
|
||||
import random
|
||||
|
||||
from moto import mock_cloudformation_deprecated, mock_ec2, mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_subnets():
|
||||
ec2 = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
ec2 = boto.connect_ec2("the_key", "the_secret")
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
|
||||
|
|
@ -31,25 +33,25 @@ def test_subnets():
|
|||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_subnet(subnet.id)
|
||||
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidSubnetID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_subnet_create_vpc_validation():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_subnet("vpc-abcd1234", "10.0.0.0/18")
|
||||
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidVpcID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_subnet_tagging():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
||||
|
||||
|
|
@ -67,31 +69,31 @@ def test_subnet_tagging():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_subnet_should_have_proper_availability_zone_set():
|
||||
conn = boto.vpc.connect_to_region('us-west-1')
|
||||
conn = boto.vpc.connect_to_region("us-west-1")
|
||||
vpcA = conn.create_vpc("10.0.0.0/16")
|
||||
subnetA = conn.create_subnet(
|
||||
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1b')
|
||||
subnetA.availability_zone.should.equal('us-west-1b')
|
||||
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1b")
|
||||
subnetA.availability_zone.should.equal("us-west-1b")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_default_subnet():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
default_vpc = list(ec2.vpcs.all())[0]
|
||||
default_vpc.cidr_block.should.equal('172.31.0.0/16')
|
||||
default_vpc.cidr_block.should.equal("172.31.0.0/16")
|
||||
default_vpc.reload()
|
||||
default_vpc.is_default.should.be.ok
|
||||
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=default_vpc.id, CidrBlock='172.31.48.0/20', AvailabilityZone='us-west-1a')
|
||||
VpcId=default_vpc.id, CidrBlock="172.31.48.0/20", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_non_default_subnet():
|
||||
vpc_cli = boto.vpc.connect_to_region('us-west-1')
|
||||
vpc_cli = boto.vpc.connect_to_region("us-west-1")
|
||||
|
||||
# Create the non default VPC
|
||||
vpc = vpc_cli.create_vpc("10.0.0.0/16")
|
||||
|
|
@ -99,34 +101,36 @@ def test_non_default_subnet():
|
|||
|
||||
subnet = vpc_cli.create_subnet(vpc.id, "10.0.0.0/24")
|
||||
subnet = vpc_cli.get_all_subnets(subnet_ids=[subnet.id])[0]
|
||||
subnet.mapPublicIpOnLaunch.should.equal('false')
|
||||
subnet.mapPublicIpOnLaunch.should.equal("false")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_boto3_non_default_subnet():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the non default VPC
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute_public_ip_on_launch():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
# Get the default VPC
|
||||
vpc = list(ec2.vpcs.all())[0]
|
||||
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock="172.31.48.0/20", AvailabilityZone='us-west-1a')
|
||||
VpcId=vpc.id, CidrBlock="172.31.48.0/20", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
|
||||
# 'map_public_ip_on_launch' is set when calling 'DescribeSubnets' action
|
||||
subnet.reload()
|
||||
|
|
@ -135,26 +139,29 @@ def test_modify_subnet_attribute_public_ip_on_launch():
|
|||
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': False})
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={"Value": False}
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': True})
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={"Value": True}
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.map_public_ip_on_launch.should.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute_assign_ipv6_address_on_creation():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
# Get the default VPC
|
||||
vpc = list(ec2.vpcs.all())[0]
|
||||
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='172.31.112.0/20', AvailabilityZone='us-west-1a')
|
||||
VpcId=vpc.id, CidrBlock="172.31.112.0/20", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
|
||||
# 'map_public_ip_on_launch' is set when calling 'DescribeSubnets' action
|
||||
subnet.reload()
|
||||
|
|
@ -163,41 +170,46 @@ def test_modify_subnet_attribute_assign_ipv6_address_on_creation():
|
|||
subnet.assign_ipv6_address_on_creation.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={'Value': False})
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={"Value": False}
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.assign_ipv6_address_on_creation.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={'Value': True})
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={"Value": True}
|
||||
)
|
||||
subnet.reload()
|
||||
subnet.assign_ipv6_address_on_creation.should.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute_validation():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
|
||||
with assert_raises(ParamValidationError):
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': 'invalid'})
|
||||
SubnetId=subnet.id, MapPublicIpOnLaunch={"Value": "invalid"}
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_subnet_get_by_id():
|
||||
ec2 = boto.ec2.connect_to_region('us-west-1')
|
||||
conn = boto.vpc.connect_to_region('us-west-1')
|
||||
ec2 = boto.ec2.connect_to_region("us-west-1")
|
||||
conn = boto.vpc.connect_to_region("us-west-1")
|
||||
vpcA = conn.create_vpc("10.0.0.0/16")
|
||||
subnetA = conn.create_subnet(
|
||||
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
||||
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1a")
|
||||
vpcB = conn.create_vpc("10.0.0.0/16")
|
||||
subnetB1 = conn.create_subnet(
|
||||
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
||||
vpcB.id, "10.0.0.0/24", availability_zone="us-west-1a"
|
||||
)
|
||||
subnetB2 = conn.create_subnet(
|
||||
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
|
||||
vpcB.id, "10.0.1.0/24", availability_zone="us-west-1b"
|
||||
)
|
||||
|
||||
subnets_by_id = conn.get_all_subnets(subnet_ids=[subnetA.id, subnetB1.id])
|
||||
subnets_by_id.should.have.length_of(2)
|
||||
|
|
@ -206,85 +218,91 @@ def test_subnet_get_by_id():
|
|||
subnetB1.id.should.be.within(subnets_by_id)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_subnets(subnet_ids=['subnet-does_not_exist'])
|
||||
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
|
||||
conn.get_all_subnets(subnet_ids=["subnet-does_not_exist"])
|
||||
cm.exception.code.should.equal("InvalidSubnetID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_subnets_filtering():
|
||||
ec2 = boto.ec2.connect_to_region('us-west-1')
|
||||
conn = boto.vpc.connect_to_region('us-west-1')
|
||||
ec2 = boto.ec2.connect_to_region("us-west-1")
|
||||
conn = boto.vpc.connect_to_region("us-west-1")
|
||||
vpcA = conn.create_vpc("10.0.0.0/16")
|
||||
subnetA = conn.create_subnet(
|
||||
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
||||
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1a")
|
||||
vpcB = conn.create_vpc("10.0.0.0/16")
|
||||
subnetB1 = conn.create_subnet(
|
||||
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
||||
vpcB.id, "10.0.0.0/24", availability_zone="us-west-1a"
|
||||
)
|
||||
subnetB2 = conn.create_subnet(
|
||||
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
|
||||
vpcB.id, "10.0.1.0/24", availability_zone="us-west-1b"
|
||||
)
|
||||
|
||||
all_subnets = conn.get_all_subnets()
|
||||
all_subnets.should.have.length_of(3 + len(ec2.get_all_zones()))
|
||||
|
||||
# Filter by VPC ID
|
||||
subnets_by_vpc = conn.get_all_subnets(filters={'vpc-id': vpcB.id})
|
||||
subnets_by_vpc = conn.get_all_subnets(filters={"vpc-id": vpcB.id})
|
||||
subnets_by_vpc.should.have.length_of(2)
|
||||
set([subnet.id for subnet in subnets_by_vpc]).should.equal(
|
||||
set([subnetB1.id, subnetB2.id]))
|
||||
set([subnetB1.id, subnetB2.id])
|
||||
)
|
||||
|
||||
# Filter by CIDR variations
|
||||
subnets_by_cidr1 = conn.get_all_subnets(filters={'cidr': "10.0.0.0/24"})
|
||||
subnets_by_cidr1 = conn.get_all_subnets(filters={"cidr": "10.0.0.0/24"})
|
||||
subnets_by_cidr1.should.have.length_of(2)
|
||||
set([subnet.id for subnet in subnets_by_cidr1]
|
||||
).should.equal(set([subnetA.id, subnetB1.id]))
|
||||
set([subnet.id for subnet in subnets_by_cidr1]).should.equal(
|
||||
set([subnetA.id, subnetB1.id])
|
||||
)
|
||||
|
||||
subnets_by_cidr2 = conn.get_all_subnets(
|
||||
filters={'cidr-block': "10.0.0.0/24"})
|
||||
subnets_by_cidr2 = conn.get_all_subnets(filters={"cidr-block": "10.0.0.0/24"})
|
||||
subnets_by_cidr2.should.have.length_of(2)
|
||||
set([subnet.id for subnet in subnets_by_cidr2]
|
||||
).should.equal(set([subnetA.id, subnetB1.id]))
|
||||
set([subnet.id for subnet in subnets_by_cidr2]).should.equal(
|
||||
set([subnetA.id, subnetB1.id])
|
||||
)
|
||||
|
||||
subnets_by_cidr3 = conn.get_all_subnets(
|
||||
filters={'cidrBlock': "10.0.0.0/24"})
|
||||
subnets_by_cidr3 = conn.get_all_subnets(filters={"cidrBlock": "10.0.0.0/24"})
|
||||
subnets_by_cidr3.should.have.length_of(2)
|
||||
set([subnet.id for subnet in subnets_by_cidr3]
|
||||
).should.equal(set([subnetA.id, subnetB1.id]))
|
||||
set([subnet.id for subnet in subnets_by_cidr3]).should.equal(
|
||||
set([subnetA.id, subnetB1.id])
|
||||
)
|
||||
|
||||
# Filter by VPC ID and CIDR
|
||||
subnets_by_vpc_and_cidr = conn.get_all_subnets(
|
||||
filters={'vpc-id': vpcB.id, 'cidr': "10.0.0.0/24"})
|
||||
filters={"vpc-id": vpcB.id, "cidr": "10.0.0.0/24"}
|
||||
)
|
||||
subnets_by_vpc_and_cidr.should.have.length_of(1)
|
||||
set([subnet.id for subnet in subnets_by_vpc_and_cidr]
|
||||
).should.equal(set([subnetB1.id]))
|
||||
set([subnet.id for subnet in subnets_by_vpc_and_cidr]).should.equal(
|
||||
set([subnetB1.id])
|
||||
)
|
||||
|
||||
# Filter by subnet ID
|
||||
subnets_by_id = conn.get_all_subnets(filters={'subnet-id': subnetA.id})
|
||||
subnets_by_id = conn.get_all_subnets(filters={"subnet-id": subnetA.id})
|
||||
subnets_by_id.should.have.length_of(1)
|
||||
set([subnet.id for subnet in subnets_by_id]).should.equal(set([subnetA.id]))
|
||||
|
||||
# Filter by availabilityZone
|
||||
subnets_by_az = conn.get_all_subnets(
|
||||
filters={'availabilityZone': 'us-west-1a', 'vpc-id': vpcB.id})
|
||||
filters={"availabilityZone": "us-west-1a", "vpc-id": vpcB.id}
|
||||
)
|
||||
subnets_by_az.should.have.length_of(1)
|
||||
set([subnet.id for subnet in subnets_by_az]
|
||||
).should.equal(set([subnetB1.id]))
|
||||
set([subnet.id for subnet in subnets_by_az]).should.equal(set([subnetB1.id]))
|
||||
|
||||
# Filter by defaultForAz
|
||||
|
||||
subnets_by_az = conn.get_all_subnets(filters={'defaultForAz': "true"})
|
||||
subnets_by_az = conn.get_all_subnets(filters={"defaultForAz": "true"})
|
||||
subnets_by_az.should.have.length_of(len(conn.get_all_zones()))
|
||||
|
||||
# Unsupported filter
|
||||
conn.get_all_subnets.when.called_with(
|
||||
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
|
||||
filters={"not-implemented-filter": "foobar"}
|
||||
).should.throw(NotImplementedError)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
@mock_cloudformation_deprecated
|
||||
def test_subnet_tags_through_cloudformation():
|
||||
vpc_conn = boto.vpc.connect_to_region('us-west-1')
|
||||
vpc_conn = boto.vpc.connect_to_region("us-west-1")
|
||||
vpc = vpc_conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
subnet_template = {
|
||||
|
|
@ -296,151 +314,288 @@ def test_subnet_tags_through_cloudformation():
|
|||
"VpcId": vpc.id,
|
||||
"CidrBlock": "10.0.0.0/24",
|
||||
"AvailabilityZone": "us-west-1b",
|
||||
"Tags": [{
|
||||
"Key": "foo",
|
||||
"Value": "bar",
|
||||
}, {
|
||||
"Key": "blah",
|
||||
"Value": "baz",
|
||||
}]
|
||||
}
|
||||
"Tags": [
|
||||
{"Key": "foo", "Value": "bar"},
|
||||
{"Key": "blah", "Value": "baz"},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
cf_conn = boto.cloudformation.connect_to_region("us-west-1")
|
||||
template_json = json.dumps(subnet_template)
|
||||
cf_conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=template_json,
|
||||
)
|
||||
cf_conn.create_stack("test_stack", template_body=template_json)
|
||||
|
||||
subnet = vpc_conn.get_all_subnets(filters={'cidrBlock': '10.0.0.0/24'})[0]
|
||||
subnet = vpc_conn.get_all_subnets(filters={"cidrBlock": "10.0.0.0/24"})[0]
|
||||
subnet.tags["foo"].should.equal("bar")
|
||||
subnet.tags["blah"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_response_fields():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')['Subnet']
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
|
||||
)["Subnet"]
|
||||
|
||||
subnet.should.have.key('AvailabilityZone')
|
||||
subnet.should.have.key('AvailabilityZoneId')
|
||||
subnet.should.have.key('AvailableIpAddressCount')
|
||||
subnet.should.have.key('CidrBlock')
|
||||
subnet.should.have.key('State')
|
||||
subnet.should.have.key('SubnetId')
|
||||
subnet.should.have.key('VpcId')
|
||||
subnet.shouldnt.have.key('Tags')
|
||||
subnet.should.have.key('DefaultForAz').which.should.equal(False)
|
||||
subnet.should.have.key('MapPublicIpOnLaunch').which.should.equal(False)
|
||||
subnet.should.have.key('OwnerId')
|
||||
subnet.should.have.key('AssignIpv6AddressOnCreation').which.should.equal(False)
|
||||
subnet.should.have.key("AvailabilityZone")
|
||||
subnet.should.have.key("AvailabilityZoneId")
|
||||
subnet.should.have.key("AvailableIpAddressCount")
|
||||
subnet.should.have.key("CidrBlock")
|
||||
subnet.should.have.key("State")
|
||||
subnet.should.have.key("SubnetId")
|
||||
subnet.should.have.key("VpcId")
|
||||
subnet.shouldnt.have.key("Tags")
|
||||
subnet.should.have.key("DefaultForAz").which.should.equal(False)
|
||||
subnet.should.have.key("MapPublicIpOnLaunch").which.should.equal(False)
|
||||
subnet.should.have.key("OwnerId")
|
||||
subnet.should.have.key("AssignIpv6AddressOnCreation").which.should.equal(False)
|
||||
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(region=subnet['AvailabilityZone'][0:-1],
|
||||
owner_id=subnet['OwnerId'],
|
||||
subnet_id=subnet['SubnetId'])
|
||||
subnet.should.have.key('SubnetArn').which.should.equal(subnet_arn)
|
||||
subnet.should.have.key('Ipv6CidrBlockAssociationSet').which.should.equal([])
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(
|
||||
region=subnet["AvailabilityZone"][0:-1],
|
||||
owner_id=subnet["OwnerId"],
|
||||
subnet_id=subnet["SubnetId"],
|
||||
)
|
||||
subnet.should.have.key("SubnetArn").which.should.equal(subnet_arn)
|
||||
subnet.should.have.key("Ipv6CidrBlockAssociationSet").which.should.equal([])
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_subnet_response_fields():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet_object = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
||||
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
|
||||
)
|
||||
|
||||
subnets = client.describe_subnets(SubnetIds=[subnet_object.id])['Subnets']
|
||||
subnets = client.describe_subnets(SubnetIds=[subnet_object.id])["Subnets"]
|
||||
subnets.should.have.length_of(1)
|
||||
subnet = subnets[0]
|
||||
|
||||
subnet.should.have.key('AvailabilityZone')
|
||||
subnet.should.have.key('AvailabilityZoneId')
|
||||
subnet.should.have.key('AvailableIpAddressCount')
|
||||
subnet.should.have.key('CidrBlock')
|
||||
subnet.should.have.key('State')
|
||||
subnet.should.have.key('SubnetId')
|
||||
subnet.should.have.key('VpcId')
|
||||
subnet.shouldnt.have.key('Tags')
|
||||
subnet.should.have.key('DefaultForAz').which.should.equal(False)
|
||||
subnet.should.have.key('MapPublicIpOnLaunch').which.should.equal(False)
|
||||
subnet.should.have.key('OwnerId')
|
||||
subnet.should.have.key('AssignIpv6AddressOnCreation').which.should.equal(False)
|
||||
subnet.should.have.key("AvailabilityZone")
|
||||
subnet.should.have.key("AvailabilityZoneId")
|
||||
subnet.should.have.key("AvailableIpAddressCount")
|
||||
subnet.should.have.key("CidrBlock")
|
||||
subnet.should.have.key("State")
|
||||
subnet.should.have.key("SubnetId")
|
||||
subnet.should.have.key("VpcId")
|
||||
subnet.shouldnt.have.key("Tags")
|
||||
subnet.should.have.key("DefaultForAz").which.should.equal(False)
|
||||
subnet.should.have.key("MapPublicIpOnLaunch").which.should.equal(False)
|
||||
subnet.should.have.key("OwnerId")
|
||||
subnet.should.have.key("AssignIpv6AddressOnCreation").which.should.equal(False)
|
||||
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(region=subnet['AvailabilityZone'][0:-1],
|
||||
owner_id=subnet['OwnerId'],
|
||||
subnet_id=subnet['SubnetId'])
|
||||
subnet.should.have.key('SubnetArn').which.should.equal(subnet_arn)
|
||||
subnet.should.have.key('Ipv6CidrBlockAssociationSet').which.should.equal([])
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(
|
||||
region=subnet["AvailabilityZone"][0:-1],
|
||||
owner_id=subnet["OwnerId"],
|
||||
subnet_id=subnet["SubnetId"],
|
||||
)
|
||||
subnet.should.have.key("SubnetArn").which.should.equal(subnet_arn)
|
||||
subnet.should.have.key("Ipv6CidrBlockAssociationSet").which.should.equal([])
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_availability_zone():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
subnet_availability_zone = 'asfasfas'
|
||||
subnet_availability_zone = "asfasfas"
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone=subnet_availability_zone)
|
||||
VpcId=vpc.id,
|
||||
CidrBlock="10.0.0.0/24",
|
||||
AvailabilityZone=subnet_availability_zone,
|
||||
)
|
||||
assert str(ex.exception).startswith(
|
||||
"An error occurred (InvalidParameterValue) when calling the CreateSubnet "
|
||||
"operation: Value ({}) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ".format(subnet_availability_zone))
|
||||
"operation: Value ({}) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ".format(
|
||||
subnet_availability_zone
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_cidr_range():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet_cidr_block = '10.1.0.0/20'
|
||||
subnet_cidr_block = "10.1.0.0/20"
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidSubnet.Range) when calling the CreateSubnet "
|
||||
"operation: The CIDR '{}' is invalid.".format(subnet_cidr_block))
|
||||
"operation: The CIDR '{}' is invalid.".format(subnet_cidr_block)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_cidr_block_parameter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet_cidr_block = '1000.1.0.0/20'
|
||||
subnet_cidr_block = "1000.1.0.0/20"
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidParameterValue) when calling the CreateSubnet "
|
||||
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(subnet_cidr_block))
|
||||
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(
|
||||
subnet_cidr_block
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnets_with_overlapping_cidr_blocks():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet_cidr_block = '10.0.0.0/24'
|
||||
subnet_cidr_block = "10.0.0.0/24"
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
||||
subnet2 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidSubnet.Conflict) when calling the CreateSubnet "
|
||||
"operation: The CIDR '{}' conflicts with another subnet".format(subnet_cidr_block))
|
||||
"operation: The CIDR '{}' conflicts with another subnet".format(
|
||||
subnet_cidr_block
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_available_ip_addresses_in_subnet():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
cidr_range_addresses = [
|
||||
("10.0.0.0/16", 65531),
|
||||
("10.0.0.0/17", 32763),
|
||||
("10.0.0.0/18", 16379),
|
||||
("10.0.0.0/19", 8187),
|
||||
("10.0.0.0/20", 4091),
|
||||
("10.0.0.0/21", 2043),
|
||||
("10.0.0.0/22", 1019),
|
||||
("10.0.0.0/23", 507),
|
||||
("10.0.0.0/24", 251),
|
||||
("10.0.0.0/25", 123),
|
||||
("10.0.0.0/26", 59),
|
||||
("10.0.0.0/27", 27),
|
||||
("10.0.0.0/28", 11),
|
||||
]
|
||||
for (cidr, expected_count) in cidr_range_addresses:
|
||||
validate_subnet_details(client, vpc, cidr, expected_count)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_available_ip_addresses_in_subnet_with_enis():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
# Verify behaviour for various CIDR ranges (...)
|
||||
# Don't try to assign ENIs to /27 and /28, as there are not a lot of IP addresses to go around
|
||||
cidr_range_addresses = [
|
||||
("10.0.0.0/16", 65531),
|
||||
("10.0.0.0/17", 32763),
|
||||
("10.0.0.0/18", 16379),
|
||||
("10.0.0.0/19", 8187),
|
||||
("10.0.0.0/20", 4091),
|
||||
("10.0.0.0/21", 2043),
|
||||
("10.0.0.0/22", 1019),
|
||||
("10.0.0.0/23", 507),
|
||||
("10.0.0.0/24", 251),
|
||||
("10.0.0.0/25", 123),
|
||||
("10.0.0.0/26", 59),
|
||||
]
|
||||
for (cidr, expected_count) in cidr_range_addresses:
|
||||
validate_subnet_details_after_creating_eni(client, vpc, cidr, expected_count)
|
||||
|
||||
|
||||
def validate_subnet_details(client, vpc, cidr, expected_ip_address_count):
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock=cidr, AvailabilityZone="us-west-1b"
|
||||
)["Subnet"]
|
||||
subnet["AvailableIpAddressCount"].should.equal(expected_ip_address_count)
|
||||
client.delete_subnet(SubnetId=subnet["SubnetId"])
|
||||
|
||||
|
||||
def validate_subnet_details_after_creating_eni(
|
||||
client, vpc, cidr, expected_ip_address_count
|
||||
):
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock=cidr, AvailabilityZone="us-west-1b"
|
||||
)["Subnet"]
|
||||
# Create a random number of Elastic Network Interfaces
|
||||
nr_of_eni_to_create = random.randint(0, 5)
|
||||
ip_addresses_assigned = 0
|
||||
enis_created = []
|
||||
for i in range(0, nr_of_eni_to_create):
|
||||
# Create a random number of IP addresses per ENI
|
||||
nr_of_ip_addresses = random.randint(1, 5)
|
||||
if nr_of_ip_addresses == 1:
|
||||
# Pick the first available IP address (First 4 are reserved by AWS)
|
||||
private_address = "10.0.0." + str(ip_addresses_assigned + 4)
|
||||
eni = client.create_network_interface(
|
||||
SubnetId=subnet["SubnetId"], PrivateIpAddress=private_address
|
||||
)["NetworkInterface"]
|
||||
enis_created.append(eni)
|
||||
ip_addresses_assigned = ip_addresses_assigned + 1
|
||||
else:
|
||||
# Assign a list of IP addresses
|
||||
private_addresses = [
|
||||
"10.0.0." + str(4 + ip_addresses_assigned + i)
|
||||
for i in range(0, nr_of_ip_addresses)
|
||||
]
|
||||
eni = client.create_network_interface(
|
||||
SubnetId=subnet["SubnetId"],
|
||||
PrivateIpAddresses=[
|
||||
{"PrivateIpAddress": address} for address in private_addresses
|
||||
],
|
||||
)["NetworkInterface"]
|
||||
enis_created.append(eni)
|
||||
ip_addresses_assigned = ip_addresses_assigned + nr_of_ip_addresses + 1 #
|
||||
# Verify that the nr of available IP addresses takes these ENIs into account
|
||||
updated_subnet = client.describe_subnets(SubnetIds=[subnet["SubnetId"]])["Subnets"][
|
||||
0
|
||||
]
|
||||
private_addresses = [
|
||||
eni["PrivateIpAddress"] for eni in enis_created if eni["PrivateIpAddress"]
|
||||
]
|
||||
for eni in enis_created:
|
||||
private_addresses.extend(
|
||||
[address["PrivateIpAddress"] for address in eni["PrivateIpAddresses"]]
|
||||
)
|
||||
error_msg = (
|
||||
"Nr of IP addresses for Subnet with CIDR {0} is incorrect. Expected: {1}, Actual: {2}. "
|
||||
"Addresses: {3}"
|
||||
)
|
||||
with sure.ensure(
|
||||
error_msg,
|
||||
cidr,
|
||||
str(expected_ip_address_count),
|
||||
updated_subnet["AvailableIpAddressCount"],
|
||||
str(private_addresses),
|
||||
):
|
||||
updated_subnet["AvailableIpAddressCount"].should.equal(
|
||||
expected_ip_address_count - ip_addresses_assigned
|
||||
)
|
||||
# Clean up, as we have to create a few more subnets that shouldn't interfere with each other
|
||||
for eni in enis_created:
|
||||
client.delete_network_interface(NetworkInterfaceId=eni["NetworkInterfaceId"])
|
||||
client.delete_subnet(SubnetId=subnet["SubnetId"])
|
||||
|
|
|
|||
|
|
@ -16,21 +16,23 @@ from nose.tools import assert_raises
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_add_tag():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
instance.add_tag("a key", "some value", dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
instance.add_tag("a key", "some value")
|
||||
chain = itertools.chain.from_iterable
|
||||
existing_instances = list(
|
||||
chain([res.instances for res in conn.get_all_instances()]))
|
||||
chain([res.instances for res in conn.get_all_instances()])
|
||||
)
|
||||
existing_instances.should.have.length_of(1)
|
||||
existing_instance = existing_instances[0]
|
||||
existing_instance.tags["a key"].should.equal("some value")
|
||||
|
|
@ -38,8 +40,8 @@ def test_add_tag():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_remove_tag():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
instance.add_tag("a key", "some value")
|
||||
|
|
@ -51,10 +53,11 @@ def test_remove_tag():
|
|||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
instance.remove_tag("a key", dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the DeleteTags operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the DeleteTags operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
instance.remove_tag("a key")
|
||||
conn.get_all_tags().should.have.length_of(0)
|
||||
|
|
@ -66,8 +69,8 @@ def test_remove_tag():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
instance.add_tag("a key", "some value")
|
||||
|
|
@ -80,8 +83,8 @@ def test_get_all_tags():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags_with_special_characters():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
instance.add_tag("a key", "some<> value")
|
||||
|
|
@ -94,47 +97,50 @@ def test_get_all_tags_with_special_characters():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_tags():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
tag_dict = {'a key': 'some value',
|
||||
'another key': 'some other value',
|
||||
'blank key': ''}
|
||||
tag_dict = {
|
||||
"a key": "some value",
|
||||
"another key": "some other value",
|
||||
"blank key": "",
|
||||
}
|
||||
|
||||
with assert_raises(EC2ResponseError) as ex:
|
||||
conn.create_tags(instance.id, tag_dict, dry_run=True)
|
||||
ex.exception.error_code.should.equal('DryRunOperation')
|
||||
ex.exception.error_code.should.equal("DryRunOperation")
|
||||
ex.exception.status.should.equal(400)
|
||||
ex.exception.message.should.equal(
|
||||
'An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set')
|
||||
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
|
||||
)
|
||||
|
||||
conn.create_tags(instance.id, tag_dict)
|
||||
tags = conn.get_all_tags()
|
||||
set([key for key in tag_dict]).should.equal(
|
||||
set([tag.name for tag in tags]))
|
||||
set([key for key in tag_dict]).should.equal(set([tag.name for tag in tags]))
|
||||
set([tag_dict[key] for key in tag_dict]).should.equal(
|
||||
set([tag.value for tag in tags]))
|
||||
set([tag.value for tag in tags])
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_tag_limit_exceeded():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
tag_dict = {}
|
||||
for i in range(51):
|
||||
tag_dict['{0:02d}'.format(i + 1)] = ''
|
||||
tag_dict["{0:02d}".format(i + 1)] = ""
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_tags(instance.id, tag_dict)
|
||||
cm.exception.code.should.equal('TagLimitExceeded')
|
||||
cm.exception.code.should.equal("TagLimitExceeded")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
instance.add_tag("a key", "a value")
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_tags(instance.id, tag_dict)
|
||||
cm.exception.code.should.equal('TagLimitExceeded')
|
||||
cm.exception.code.should.equal("TagLimitExceeded")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -147,158 +153,158 @@ def test_tag_limit_exceeded():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_invalid_parameter_tag_null():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
instance.add_tag("a key", None)
|
||||
cm.exception.code.should.equal('InvalidParameterValue')
|
||||
cm.exception.code.should.equal("InvalidParameterValue")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_invalid_id():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_tags('ami-blah', {'key': 'tag'})
|
||||
cm.exception.code.should.equal('InvalidID')
|
||||
conn.create_tags("ami-blah", {"key": "tag"})
|
||||
cm.exception.code.should.equal("InvalidID")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.create_tags('blah-blah', {'key': 'tag'})
|
||||
cm.exception.code.should.equal('InvalidID')
|
||||
conn.create_tags("blah-blah", {"key": "tag"})
|
||||
cm.exception.code.should.equal("InvalidID")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags_resource_id_filter():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
instance.add_tag("an instance key", "some value")
|
||||
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
|
||||
image = conn.get_image(image_id)
|
||||
image.add_tag("an image key", "some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'resource-id': instance.id})
|
||||
tags = conn.get_all_tags(filters={"resource-id": instance.id})
|
||||
tag = tags[0]
|
||||
tags.should.have.length_of(1)
|
||||
tag.res_id.should.equal(instance.id)
|
||||
tag.res_type.should.equal('instance')
|
||||
tag.res_type.should.equal("instance")
|
||||
tag.name.should.equal("an instance key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'resource-id': image_id})
|
||||
tags = conn.get_all_tags(filters={"resource-id": image_id})
|
||||
tag = tags[0]
|
||||
tags.should.have.length_of(1)
|
||||
tag.res_id.should.equal(image_id)
|
||||
tag.res_type.should.equal('image')
|
||||
tag.res_type.should.equal("image")
|
||||
tag.name.should.equal("an image key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags_resource_type_filter():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
instance.add_tag("an instance key", "some value")
|
||||
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
|
||||
image = conn.get_image(image_id)
|
||||
image.add_tag("an image key", "some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'resource-type': 'instance'})
|
||||
tags = conn.get_all_tags(filters={"resource-type": "instance"})
|
||||
tag = tags[0]
|
||||
tags.should.have.length_of(1)
|
||||
tag.res_id.should.equal(instance.id)
|
||||
tag.res_type.should.equal('instance')
|
||||
tag.res_type.should.equal("instance")
|
||||
tag.name.should.equal("an instance key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'resource-type': 'image'})
|
||||
tags = conn.get_all_tags(filters={"resource-type": "image"})
|
||||
tag = tags[0]
|
||||
tags.should.have.length_of(1)
|
||||
tag.res_id.should.equal(image_id)
|
||||
tag.res_type.should.equal('image')
|
||||
tag.res_type.should.equal("image")
|
||||
tag.name.should.equal("an image key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags_key_filter():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
instance.add_tag("an instance key", "some value")
|
||||
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
|
||||
image = conn.get_image(image_id)
|
||||
image.add_tag("an image key", "some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'key': 'an instance key'})
|
||||
tags = conn.get_all_tags(filters={"key": "an instance key"})
|
||||
tag = tags[0]
|
||||
tags.should.have.length_of(1)
|
||||
tag.res_id.should.equal(instance.id)
|
||||
tag.res_type.should.equal('instance')
|
||||
tag.res_type.should.equal("instance")
|
||||
tag.name.should.equal("an instance key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_get_all_tags_value_filter():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance = reservation.instances[0]
|
||||
instance.add_tag("an instance key", "some value")
|
||||
reservation_b = conn.run_instances('ami-1234abcd')
|
||||
reservation_b = conn.run_instances("ami-1234abcd")
|
||||
instance_b = reservation_b.instances[0]
|
||||
instance_b.add_tag("an instance key", "some other value")
|
||||
reservation_c = conn.run_instances('ami-1234abcd')
|
||||
reservation_c = conn.run_instances("ami-1234abcd")
|
||||
instance_c = reservation_c.instances[0]
|
||||
instance_c.add_tag("an instance key", "other value*")
|
||||
reservation_d = conn.run_instances('ami-1234abcd')
|
||||
reservation_d = conn.run_instances("ami-1234abcd")
|
||||
instance_d = reservation_d.instances[0]
|
||||
instance_d.add_tag("an instance key", "other value**")
|
||||
reservation_e = conn.run_instances('ami-1234abcd')
|
||||
reservation_e = conn.run_instances("ami-1234abcd")
|
||||
instance_e = reservation_e.instances[0]
|
||||
instance_e.add_tag("an instance key", "other value*?")
|
||||
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
|
||||
image = conn.get_image(image_id)
|
||||
image.add_tag("an image key", "some value")
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': 'some value'})
|
||||
tags = conn.get_all_tags(filters={"value": "some value"})
|
||||
tags.should.have.length_of(2)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': 'some*value'})
|
||||
tags = conn.get_all_tags(filters={"value": "some*value"})
|
||||
tags.should.have.length_of(3)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': '*some*value'})
|
||||
tags = conn.get_all_tags(filters={"value": "*some*value"})
|
||||
tags.should.have.length_of(3)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': '*some*value*'})
|
||||
tags = conn.get_all_tags(filters={"value": "*some*value*"})
|
||||
tags.should.have.length_of(3)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': '*value\*'})
|
||||
tags = conn.get_all_tags(filters={"value": "*value\*"})
|
||||
tags.should.have.length_of(1)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': '*value\*\*'})
|
||||
tags = conn.get_all_tags(filters={"value": "*value\*\*"})
|
||||
tags.should.have.length_of(1)
|
||||
|
||||
tags = conn.get_all_tags(filters={'value': '*value\*\?'})
|
||||
tags = conn.get_all_tags(filters={"value": "*value\*\?"})
|
||||
tags.should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_retrieved_instances_must_contain_their_tags():
|
||||
tag_key = 'Tag name'
|
||||
tag_value = 'Tag value'
|
||||
tag_key = "Tag name"
|
||||
tag_value = "Tag value"
|
||||
tags_to_be_set = {tag_key: tag_value}
|
||||
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
reservation.should.be.a(Reservation)
|
||||
reservation.instances.should.have.length_of(1)
|
||||
instance = reservation.instances[0]
|
||||
|
|
@ -324,10 +330,10 @@ def test_retrieved_instances_must_contain_their_tags():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_retrieved_volumes_must_contain_their_tags():
|
||||
tag_key = 'Tag name'
|
||||
tag_value = 'Tag value'
|
||||
tag_key = "Tag name"
|
||||
tag_value = "Tag value"
|
||||
tags_to_be_set = {tag_key: tag_value}
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
volume = conn.create_volume(80, "us-east-1a")
|
||||
|
||||
all_volumes = conn.get_all_volumes()
|
||||
|
|
@ -347,11 +353,12 @@ def test_retrieved_volumes_must_contain_their_tags():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_retrieved_snapshots_must_contain_their_tags():
|
||||
tag_key = 'Tag name'
|
||||
tag_value = 'Tag value'
|
||||
tag_key = "Tag name"
|
||||
tag_value = "Tag value"
|
||||
tags_to_be_set = {tag_key: tag_value}
|
||||
conn = boto.connect_ec2(aws_access_key_id='the_key',
|
||||
aws_secret_access_key='the_secret')
|
||||
conn = boto.connect_ec2(
|
||||
aws_access_key_id="the_key", aws_secret_access_key="the_secret"
|
||||
)
|
||||
volume = conn.create_volume(80, "eu-west-1a")
|
||||
snapshot = conn.create_snapshot(volume.id)
|
||||
conn.create_tags([snapshot.id], tags_to_be_set)
|
||||
|
|
@ -370,113 +377,94 @@ def test_retrieved_snapshots_must_contain_their_tags():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_filter_instances_by_wildcard_tags():
|
||||
conn = boto.connect_ec2(aws_access_key_id='the_key',
|
||||
aws_secret_access_key='the_secret')
|
||||
reservation = conn.run_instances('ami-1234abcd')
|
||||
conn = boto.connect_ec2(
|
||||
aws_access_key_id="the_key", aws_secret_access_key="the_secret"
|
||||
)
|
||||
reservation = conn.run_instances("ami-1234abcd")
|
||||
instance_a = reservation.instances[0]
|
||||
instance_a.add_tag("Key1", "Value1")
|
||||
reservation_b = conn.run_instances('ami-1234abcd')
|
||||
reservation_b = conn.run_instances("ami-1234abcd")
|
||||
instance_b = reservation_b.instances[0]
|
||||
instance_b.add_tag("Key1", "Value2")
|
||||
|
||||
reservations = conn.get_all_instances(filters={'tag:Key1': 'Value*'})
|
||||
reservations = conn.get_all_instances(filters={"tag:Key1": "Value*"})
|
||||
reservations.should.have.length_of(2)
|
||||
|
||||
reservations = conn.get_all_instances(filters={'tag-key': 'Key*'})
|
||||
reservations = conn.get_all_instances(filters={"tag-key": "Key*"})
|
||||
reservations.should.have.length_of(2)
|
||||
|
||||
reservations = conn.get_all_instances(filters={'tag-value': 'Value*'})
|
||||
reservations = conn.get_all_instances(filters={"tag-value": "Value*"})
|
||||
reservations.should.have.length_of(2)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_volume_with_tags():
|
||||
client = boto3.client('ec2', 'us-west-2')
|
||||
client = boto3.client("ec2", "us-west-2")
|
||||
response = client.create_volume(
|
||||
AvailabilityZone='us-west-2',
|
||||
Encrypted=False,
|
||||
Size=40,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'volume',
|
||||
'Tags': [
|
||||
{
|
||||
'Key': 'TEST_TAG',
|
||||
'Value': 'TEST_VALUE'
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert response['Tags'][0]['Key'] == 'TEST_TAG'
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_snapshot_with_tags():
|
||||
client = boto3.client('ec2', 'us-west-2')
|
||||
volume_id = client.create_volume(
|
||||
AvailabilityZone='us-west-2',
|
||||
AvailabilityZone="us-west-2",
|
||||
Encrypted=False,
|
||||
Size=40,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'volume',
|
||||
'Tags': [
|
||||
{
|
||||
'Key': 'TEST_TAG',
|
||||
'Value': 'TEST_VALUE'
|
||||
}
|
||||
],
|
||||
"ResourceType": "volume",
|
||||
"Tags": [{"Key": "TEST_TAG", "Value": "TEST_VALUE"}],
|
||||
}
|
||||
]
|
||||
)['VolumeId']
|
||||
],
|
||||
)
|
||||
|
||||
assert response["Tags"][0]["Key"] == "TEST_TAG"
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_snapshot_with_tags():
|
||||
client = boto3.client("ec2", "us-west-2")
|
||||
volume_id = client.create_volume(
|
||||
AvailabilityZone="us-west-2",
|
||||
Encrypted=False,
|
||||
Size=40,
|
||||
TagSpecifications=[
|
||||
{
|
||||
"ResourceType": "volume",
|
||||
"Tags": [{"Key": "TEST_TAG", "Value": "TEST_VALUE"}],
|
||||
}
|
||||
],
|
||||
)["VolumeId"]
|
||||
snapshot = client.create_snapshot(
|
||||
VolumeId=volume_id,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'snapshot',
|
||||
'Tags': [
|
||||
{
|
||||
'Key': 'TEST_SNAPSHOT_TAG',
|
||||
'Value': 'TEST_SNAPSHOT_VALUE'
|
||||
}
|
||||
],
|
||||
"ResourceType": "snapshot",
|
||||
"Tags": [{"Key": "TEST_SNAPSHOT_TAG", "Value": "TEST_SNAPSHOT_VALUE"}],
|
||||
}
|
||||
]
|
||||
],
|
||||
)
|
||||
|
||||
expected_tags = [{
|
||||
'Key': 'TEST_SNAPSHOT_TAG',
|
||||
'Value': 'TEST_SNAPSHOT_VALUE'
|
||||
}]
|
||||
expected_tags = [{"Key": "TEST_SNAPSHOT_TAG", "Value": "TEST_SNAPSHOT_VALUE"}]
|
||||
|
||||
assert snapshot['Tags'] == expected_tags
|
||||
assert snapshot["Tags"] == expected_tags
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_tag_empty_resource():
|
||||
# create ec2 client in us-west-1
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
# create tag with empty resource
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.create_tags(
|
||||
Resources=[],
|
||||
Tags=[{'Key': 'Value'}]
|
||||
)
|
||||
ex.exception.response['Error']['Code'].should.equal('MissingParameter')
|
||||
ex.exception.response['Error']['Message'].should.equal('The request must contain the parameter resourceIdSet')
|
||||
client.create_tags(Resources=[], Tags=[{"Key": "Value"}])
|
||||
ex.exception.response["Error"]["Code"].should.equal("MissingParameter")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"The request must contain the parameter resourceIdSet"
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_delete_tag_empty_resource():
|
||||
# create ec2 client in us-west-1
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
# delete tag with empty resource
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.delete_tags(
|
||||
Resources=[],
|
||||
Tags=[{'Key': 'Value'}]
|
||||
)
|
||||
ex.exception.response['Error']['Code'].should.equal('MissingParameter')
|
||||
ex.exception.response['Error']['Message'].should.equal('The request must contain the parameter resourceIdSet')
|
||||
client.delete_tags(Resources=[], Tags=[{"Key": "Value"}])
|
||||
ex.exception.response["Error"]["Code"].should.equal("MissingParameter")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"The request must contain the parameter resourceIdSet"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ from .helpers import rsa_check_private_key
|
|||
|
||||
def test_random_key_pair():
|
||||
key_pair = utils.random_key_pair()
|
||||
rsa_check_private_key(key_pair['material'])
|
||||
rsa_check_private_key(key_pair["material"])
|
||||
|
||||
# AWS uses MD5 fingerprints, which are 47 characters long, *not* SHA1
|
||||
# fingerprints with 59 characters.
|
||||
assert len(key_pair['fingerprint']) == 47
|
||||
assert len(key_pair["fingerprint"]) == 47
|
||||
|
|
|
|||
|
|
@ -7,54 +7,51 @@ from moto import mock_ec2_deprecated
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_virtual_private_gateways():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
vpn_gateway.should_not.be.none
|
||||
vpn_gateway.id.should.match(r'vgw-\w+')
|
||||
vpn_gateway.type.should.equal('ipsec.1')
|
||||
vpn_gateway.state.should.equal('available')
|
||||
vpn_gateway.availability_zone.should.equal('us-east-1a')
|
||||
vpn_gateway.id.should.match(r"vgw-\w+")
|
||||
vpn_gateway.type.should.equal("ipsec.1")
|
||||
vpn_gateway.state.should.equal("available")
|
||||
vpn_gateway.availability_zone.should.equal("us-east-1a")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_vpn_gateway():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
|
||||
vgws = conn.get_all_vpn_gateways()
|
||||
vgws.should.have.length_of(1)
|
||||
|
||||
gateway = vgws[0]
|
||||
gateway.id.should.match(r'vgw-\w+')
|
||||
gateway.id.should.match(r"vgw-\w+")
|
||||
gateway.id.should.equal(vpn_gateway.id)
|
||||
vpn_gateway.type.should.equal('ipsec.1')
|
||||
vpn_gateway.state.should.equal('available')
|
||||
vpn_gateway.availability_zone.should.equal('us-east-1a')
|
||||
vpn_gateway.type.should.equal("ipsec.1")
|
||||
vpn_gateway.state.should.equal("available")
|
||||
vpn_gateway.availability_zone.should.equal("us-east-1a")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpn_gateway_vpc_attachment():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
|
||||
conn.attach_vpn_gateway(
|
||||
vpn_gateway_id=vpn_gateway.id,
|
||||
vpc_id=vpc.id
|
||||
)
|
||||
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
|
||||
|
||||
gateway = conn.get_all_vpn_gateways()[0]
|
||||
attachments = gateway.attachments
|
||||
attachments.should.have.length_of(1)
|
||||
attachments[0].vpc_id.should.equal(vpc.id)
|
||||
attachments[0].state.should.equal('attached')
|
||||
attachments[0].state.should.equal("attached")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_vpn_gateway():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
|
||||
conn.delete_vpn_gateway(vpn_gateway.id)
|
||||
vgws = conn.get_all_vpn_gateways()
|
||||
|
|
@ -63,8 +60,8 @@ def test_delete_vpn_gateway():
|
|||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpn_gateway_tagging():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
vpn_gateway.add_tag("a key", "some value")
|
||||
|
||||
tag = conn.get_all_tags()[0]
|
||||
|
|
@ -80,25 +77,19 @@ def test_vpn_gateway_tagging():
|
|||
@mock_ec2_deprecated
|
||||
def test_detach_vpn_gateway():
|
||||
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
|
||||
|
||||
conn.attach_vpn_gateway(
|
||||
vpn_gateway_id=vpn_gateway.id,
|
||||
vpc_id=vpc.id
|
||||
)
|
||||
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
|
||||
|
||||
gateway = conn.get_all_vpn_gateways()[0]
|
||||
attachments = gateway.attachments
|
||||
attachments.should.have.length_of(1)
|
||||
attachments[0].vpc_id.should.equal(vpc.id)
|
||||
attachments[0].state.should.equal('attached')
|
||||
attachments[0].state.should.equal("attached")
|
||||
|
||||
conn.detach_vpn_gateway(
|
||||
vpn_gateway_id=vpn_gateway.id,
|
||||
vpc_id=vpc.id
|
||||
)
|
||||
conn.detach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
|
||||
|
||||
gateway = conn.get_all_vpn_gateways()[0]
|
||||
attachments = gateway.attachments
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises
|
||||
from nose.tools import assert_raises
|
||||
|
|
@ -17,12 +18,12 @@ from tests.helpers import requires_boto_gte
|
|||
@requires_boto_gte("2.32.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_peering_connections():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
peer_vpc = conn.create_vpc("11.0.0.0/16")
|
||||
|
||||
vpc_pcx = conn.create_vpc_peering_connection(vpc.id, peer_vpc.id)
|
||||
vpc_pcx._status.code.should.equal('initiating-request')
|
||||
vpc_pcx._status.code.should.equal("initiating-request")
|
||||
|
||||
return vpc_pcx
|
||||
|
||||
|
|
@ -30,39 +31,39 @@ def test_vpc_peering_connections():
|
|||
@requires_boto_gte("2.32.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_peering_connections_get_all():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc_pcx = test_vpc_peering_connections()
|
||||
vpc_pcx._status.code.should.equal('initiating-request')
|
||||
vpc_pcx._status.code.should.equal("initiating-request")
|
||||
|
||||
all_vpc_pcxs = conn.get_all_vpc_peering_connections()
|
||||
all_vpc_pcxs.should.have.length_of(1)
|
||||
all_vpc_pcxs[0]._status.code.should.equal('pending-acceptance')
|
||||
all_vpc_pcxs[0]._status.code.should.equal("pending-acceptance")
|
||||
|
||||
|
||||
@requires_boto_gte("2.32.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_peering_connections_accept():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc_pcx = test_vpc_peering_connections()
|
||||
|
||||
vpc_pcx = conn.accept_vpc_peering_connection(vpc_pcx.id)
|
||||
vpc_pcx._status.code.should.equal('active')
|
||||
vpc_pcx._status.code.should.equal("active")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.reject_vpc_peering_connection(vpc_pcx.id)
|
||||
cm.exception.code.should.equal('InvalidStateTransition')
|
||||
cm.exception.code.should.equal("InvalidStateTransition")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
all_vpc_pcxs = conn.get_all_vpc_peering_connections()
|
||||
all_vpc_pcxs.should.have.length_of(1)
|
||||
all_vpc_pcxs[0]._status.code.should.equal('active')
|
||||
all_vpc_pcxs[0]._status.code.should.equal("active")
|
||||
|
||||
|
||||
@requires_boto_gte("2.32.0")
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_peering_connections_reject():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc_pcx = test_vpc_peering_connections()
|
||||
|
||||
verdict = conn.reject_vpc_peering_connection(vpc_pcx.id)
|
||||
|
|
@ -70,19 +71,19 @@ def test_vpc_peering_connections_reject():
|
|||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.accept_vpc_peering_connection(vpc_pcx.id)
|
||||
cm.exception.code.should.equal('InvalidStateTransition')
|
||||
cm.exception.code.should.equal("InvalidStateTransition")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
all_vpc_pcxs = conn.get_all_vpc_peering_connections()
|
||||
all_vpc_pcxs.should.have.length_of(1)
|
||||
all_vpc_pcxs[0]._status.code.should.equal('rejected')
|
||||
all_vpc_pcxs[0]._status.code.should.equal("rejected")
|
||||
|
||||
|
||||
@requires_boto_gte("2.32.1")
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_peering_connections_delete():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc_pcx = test_vpc_peering_connections()
|
||||
|
||||
verdict = vpc_pcx.delete()
|
||||
|
|
@ -90,11 +91,11 @@ def test_vpc_peering_connections_delete():
|
|||
|
||||
all_vpc_pcxs = conn.get_all_vpc_peering_connections()
|
||||
all_vpc_pcxs.should.have.length_of(1)
|
||||
all_vpc_pcxs[0]._status.code.should.equal('deleted')
|
||||
all_vpc_pcxs[0]._status.code.should.equal("deleted")
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_vpc_peering_connection("pcx-1234abcd")
|
||||
cm.exception.code.should.equal('InvalidVpcPeeringConnectionId.NotFound')
|
||||
cm.exception.code.should.equal("InvalidVpcPeeringConnectionId.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -102,17 +103,15 @@ def test_vpc_peering_connections_delete():
|
|||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
vpc_pcx_usw1.status['Code'].should.equal('initiating-request')
|
||||
vpc_pcx_usw1.status["Code"].should.equal("initiating-request")
|
||||
vpc_pcx_usw1.requester_vpc.id.should.equal(vpc_usw1.id)
|
||||
vpc_pcx_usw1.accepter_vpc.id.should.equal(vpc_apn1.id)
|
||||
# test cross region vpc peering connection exist
|
||||
|
|
@ -125,35 +124,32 @@ def test_vpc_peering_connections_cross_region():
|
|||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_fail():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering wrong region with no vpc
|
||||
with assert_raises(ClientError) as cm:
|
||||
ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-2')
|
||||
cm.exception.response['Error']['Code'].should.equal('InvalidVpcID.NotFound')
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-2"
|
||||
)
|
||||
cm.exception.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_accept():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
# accept peering from ap-northeast-1
|
||||
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
|
||||
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
|
||||
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
|
||||
acp_pcx_apn1 = ec2_apn1.accept_vpc_peering_connection(
|
||||
VpcPeeringConnectionId=vpc_pcx_usw1.id
|
||||
)
|
||||
|
|
@ -163,27 +159,25 @@ def test_vpc_peering_connections_cross_region_accept():
|
|||
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
|
||||
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
|
||||
)
|
||||
acp_pcx_apn1['VpcPeeringConnection']['Status']['Code'].should.equal('active')
|
||||
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('active')
|
||||
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('active')
|
||||
acp_pcx_apn1["VpcPeeringConnection"]["Status"]["Code"].should.equal("active")
|
||||
des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("active")
|
||||
des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("active")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_reject():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
# reject peering from ap-northeast-1
|
||||
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
|
||||
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
|
||||
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
|
||||
rej_pcx_apn1 = ec2_apn1.reject_vpc_peering_connection(
|
||||
VpcPeeringConnectionId=vpc_pcx_usw1.id
|
||||
)
|
||||
|
|
@ -193,27 +187,25 @@ def test_vpc_peering_connections_cross_region_reject():
|
|||
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
|
||||
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
|
||||
)
|
||||
rej_pcx_apn1['Return'].should.equal(True)
|
||||
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('rejected')
|
||||
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('rejected')
|
||||
rej_pcx_apn1["Return"].should.equal(True)
|
||||
des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("rejected")
|
||||
des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("rejected")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_delete():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
# reject peering from ap-northeast-1
|
||||
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
|
||||
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
|
||||
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
|
||||
del_pcx_apn1 = ec2_apn1.delete_vpc_peering_connection(
|
||||
VpcPeeringConnectionId=vpc_pcx_usw1.id
|
||||
)
|
||||
|
|
@ -223,61 +215,57 @@ def test_vpc_peering_connections_cross_region_delete():
|
|||
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
|
||||
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
|
||||
)
|
||||
del_pcx_apn1['Return'].should.equal(True)
|
||||
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('deleted')
|
||||
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('deleted')
|
||||
del_pcx_apn1["Return"].should.equal(True)
|
||||
des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("deleted")
|
||||
des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"].should.equal("deleted")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_accept_wrong_region():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
|
||||
# accept wrong peering from us-west-1 which will raise error
|
||||
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
|
||||
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
|
||||
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
|
||||
with assert_raises(ClientError) as cm:
|
||||
ec2_usw1.accept_vpc_peering_connection(
|
||||
VpcPeeringConnectionId=vpc_pcx_usw1.id
|
||||
)
|
||||
cm.exception.response['Error']['Code'].should.equal('OperationNotPermitted')
|
||||
exp_msg = 'Incorrect region ({0}) specified for this request.VPC ' \
|
||||
'peering connection {1} must be ' \
|
||||
'accepted in region {2}'.format('us-west-1', vpc_pcx_usw1.id, 'ap-northeast-1')
|
||||
cm.exception.response['Error']['Message'].should.equal(exp_msg)
|
||||
ec2_usw1.accept_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_usw1.id)
|
||||
cm.exception.response["Error"]["Code"].should.equal("OperationNotPermitted")
|
||||
exp_msg = (
|
||||
"Incorrect region ({0}) specified for this request.VPC "
|
||||
"peering connection {1} must be "
|
||||
"accepted in region {2}".format("us-west-1", vpc_pcx_usw1.id, "ap-northeast-1")
|
||||
)
|
||||
cm.exception.response["Error"]["Message"].should.equal(exp_msg)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_peering_connections_cross_region_reject_wrong_region():
|
||||
# create vpc in us-west-1 and ap-northeast-1
|
||||
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
|
||||
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
|
||||
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
|
||||
# create peering
|
||||
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
|
||||
VpcId=vpc_usw1.id,
|
||||
PeerVpcId=vpc_apn1.id,
|
||||
PeerRegion='ap-northeast-1',
|
||||
VpcId=vpc_usw1.id, PeerVpcId=vpc_apn1.id, PeerRegion="ap-northeast-1"
|
||||
)
|
||||
# reject wrong peering from us-west-1 which will raise error
|
||||
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
|
||||
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
|
||||
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
|
||||
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
|
||||
with assert_raises(ClientError) as cm:
|
||||
ec2_usw1.reject_vpc_peering_connection(
|
||||
VpcPeeringConnectionId=vpc_pcx_usw1.id
|
||||
)
|
||||
cm.exception.response['Error']['Code'].should.equal('OperationNotPermitted')
|
||||
exp_msg = 'Incorrect region ({0}) specified for this request.VPC ' \
|
||||
'peering connection {1} must be accepted or ' \
|
||||
'rejected in region {2}'.format('us-west-1', vpc_pcx_usw1.id, 'ap-northeast-1')
|
||||
cm.exception.response['Error']['Message'].should.equal(exp_msg)
|
||||
ec2_usw1.reject_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_usw1.id)
|
||||
cm.exception.response["Error"]["Code"].should.equal("OperationNotPermitted")
|
||||
exp_msg = (
|
||||
"Incorrect region ({0}) specified for this request.VPC "
|
||||
"peering connection {1} must be accepted or "
|
||||
"rejected in region {2}".format("us-west-1", vpc_pcx_usw1.id, "ap-northeast-1")
|
||||
)
|
||||
cm.exception.response["Error"]["Message"].should.equal(exp_msg)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
# Ensure 'assert_raises' context manager support for Python 2.6
|
||||
import tests.backport_assert_raises # flake8: noqa
|
||||
import tests.backport_assert_raises # noqa
|
||||
from nose.tools import assert_raises
|
||||
from moto.ec2.exceptions import EC2ClientError
|
||||
from botocore.exceptions import ClientError
|
||||
|
|
@ -12,15 +13,15 @@ import sure # noqa
|
|||
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
SAMPLE_DOMAIN_NAME = u'example.com'
|
||||
SAMPLE_NAME_SERVERS = [u'10.0.0.6', u'10.0.0.7']
|
||||
SAMPLE_DOMAIN_NAME = "example.com"
|
||||
SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"]
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpcs():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
vpc.cidr_block.should.equal('10.0.0.0/16')
|
||||
vpc.cidr_block.should.equal("10.0.0.0/16")
|
||||
|
||||
all_vpcs = conn.get_all_vpcs()
|
||||
all_vpcs.should.have.length_of(2)
|
||||
|
|
@ -32,58 +33,56 @@ def test_vpcs():
|
|||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.delete_vpc("vpc-1234abcd")
|
||||
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
||||
cm.exception.code.should.equal("InvalidVpcID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_defaults():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
conn.get_all_vpcs().should.have.length_of(2)
|
||||
conn.get_all_route_tables().should.have.length_of(2)
|
||||
conn.get_all_security_groups(
|
||||
filters={'vpc-id': [vpc.id]}).should.have.length_of(1)
|
||||
conn.get_all_security_groups(filters={"vpc-id": [vpc.id]}).should.have.length_of(1)
|
||||
|
||||
vpc.delete()
|
||||
|
||||
conn.get_all_vpcs().should.have.length_of(1)
|
||||
conn.get_all_route_tables().should.have.length_of(1)
|
||||
conn.get_all_security_groups(
|
||||
filters={'vpc-id': [vpc.id]}).should.have.length_of(0)
|
||||
conn.get_all_security_groups(filters={"vpc-id": [vpc.id]}).should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_isdefault_filter():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
conn.get_all_vpcs(filters={'isDefault': 'true'}).should.have.length_of(1)
|
||||
conn.get_all_vpcs(filters={"isDefault": "true"}).should.have.length_of(1)
|
||||
vpc.delete()
|
||||
conn.get_all_vpcs(filters={'isDefault': 'true'}).should.have.length_of(1)
|
||||
conn.get_all_vpcs(filters={"isDefault": "true"}).should.have.length_of(1)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_multiple_vpcs_default_filter():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
conn.create_vpc("10.8.0.0/16")
|
||||
conn.create_vpc("10.0.0.0/16")
|
||||
conn.create_vpc("192.168.0.0/16")
|
||||
conn.get_all_vpcs().should.have.length_of(4)
|
||||
vpc = conn.get_all_vpcs(filters={'isDefault': 'true'})
|
||||
vpc = conn.get_all_vpcs(filters={"isDefault": "true"})
|
||||
vpc.should.have.length_of(1)
|
||||
vpc[0].cidr_block.should.equal('172.31.0.0/16')
|
||||
vpc[0].cidr_block.should.equal("172.31.0.0/16")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_state_available_filter():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
conn.create_vpc("10.1.0.0/16")
|
||||
conn.get_all_vpcs(filters={'state': 'available'}).should.have.length_of(3)
|
||||
conn.get_all_vpcs(filters={"state": "available"}).should.have.length_of(3)
|
||||
vpc.delete()
|
||||
conn.get_all_vpcs(filters={'state': 'available'}).should.have.length_of(2)
|
||||
conn.get_all_vpcs(filters={"state": "available"}).should.have.length_of(2)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
|
|
@ -116,8 +115,8 @@ def test_vpc_get_by_id():
|
|||
vpc2.id.should.be.within(vpc_ids)
|
||||
|
||||
with assert_raises(EC2ResponseError) as cm:
|
||||
conn.get_all_vpcs(vpc_ids=['vpc-does_not_exist'])
|
||||
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
||||
conn.get_all_vpcs(vpc_ids=["vpc-does_not_exist"])
|
||||
cm.exception.code.should.equal("InvalidVpcID.NotFound")
|
||||
cm.exception.status.should.equal(400)
|
||||
cm.exception.request_id.should_not.be.none
|
||||
|
||||
|
|
@ -129,7 +128,7 @@ def test_vpc_get_by_cidr_block():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'cidr': '10.0.0.0/16'})
|
||||
vpcs = conn.get_all_vpcs(filters={"cidr": "10.0.0.0/16"})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -139,8 +138,7 @@ def test_vpc_get_by_cidr_block():
|
|||
@mock_ec2_deprecated
|
||||
def test_vpc_get_by_dhcp_options_id():
|
||||
conn = boto.connect_vpc()
|
||||
dhcp_options = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
vpc1 = conn.create_vpc("10.0.0.0/16")
|
||||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
conn.create_vpc("10.0.0.0/24")
|
||||
|
|
@ -148,7 +146,7 @@ def test_vpc_get_by_dhcp_options_id():
|
|||
conn.associate_dhcp_options(dhcp_options.id, vpc1.id)
|
||||
conn.associate_dhcp_options(dhcp_options.id, vpc2.id)
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'dhcp-options-id': dhcp_options.id})
|
||||
vpcs = conn.get_all_vpcs(filters={"dhcp-options-id": dhcp_options.id})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -162,11 +160,11 @@ def test_vpc_get_by_tag():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
vpc3 = conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpc1.add_tag('Name', 'TestVPC')
|
||||
vpc2.add_tag('Name', 'TestVPC')
|
||||
vpc3.add_tag('Name', 'TestVPC2')
|
||||
vpc1.add_tag("Name", "TestVPC")
|
||||
vpc2.add_tag("Name", "TestVPC")
|
||||
vpc3.add_tag("Name", "TestVPC2")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'tag:Name': 'TestVPC'})
|
||||
vpcs = conn.get_all_vpcs(filters={"tag:Name": "TestVPC"})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -180,13 +178,13 @@ def test_vpc_get_by_tag_key_superset():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
vpc3 = conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpc1.add_tag('Name', 'TestVPC')
|
||||
vpc1.add_tag('Key', 'TestVPC2')
|
||||
vpc2.add_tag('Name', 'TestVPC')
|
||||
vpc2.add_tag('Key', 'TestVPC2')
|
||||
vpc3.add_tag('Key', 'TestVPC2')
|
||||
vpc1.add_tag("Name", "TestVPC")
|
||||
vpc1.add_tag("Key", "TestVPC2")
|
||||
vpc2.add_tag("Name", "TestVPC")
|
||||
vpc2.add_tag("Key", "TestVPC2")
|
||||
vpc3.add_tag("Key", "TestVPC2")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'tag-key': 'Name'})
|
||||
vpcs = conn.get_all_vpcs(filters={"tag-key": "Name"})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -200,13 +198,13 @@ def test_vpc_get_by_tag_key_subset():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
vpc3 = conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpc1.add_tag('Name', 'TestVPC')
|
||||
vpc1.add_tag('Key', 'TestVPC2')
|
||||
vpc2.add_tag('Name', 'TestVPC')
|
||||
vpc2.add_tag('Key', 'TestVPC2')
|
||||
vpc3.add_tag('Test', 'TestVPC2')
|
||||
vpc1.add_tag("Name", "TestVPC")
|
||||
vpc1.add_tag("Key", "TestVPC2")
|
||||
vpc2.add_tag("Name", "TestVPC")
|
||||
vpc2.add_tag("Key", "TestVPC2")
|
||||
vpc3.add_tag("Test", "TestVPC2")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'tag-key': ['Name', 'Key']})
|
||||
vpcs = conn.get_all_vpcs(filters={"tag-key": ["Name", "Key"]})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -220,13 +218,13 @@ def test_vpc_get_by_tag_value_superset():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
vpc3 = conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpc1.add_tag('Name', 'TestVPC')
|
||||
vpc1.add_tag('Key', 'TestVPC2')
|
||||
vpc2.add_tag('Name', 'TestVPC')
|
||||
vpc2.add_tag('Key', 'TestVPC2')
|
||||
vpc3.add_tag('Key', 'TestVPC2')
|
||||
vpc1.add_tag("Name", "TestVPC")
|
||||
vpc1.add_tag("Key", "TestVPC2")
|
||||
vpc2.add_tag("Name", "TestVPC")
|
||||
vpc2.add_tag("Key", "TestVPC2")
|
||||
vpc3.add_tag("Key", "TestVPC2")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'tag-value': 'TestVPC'})
|
||||
vpcs = conn.get_all_vpcs(filters={"tag-value": "TestVPC"})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -240,12 +238,12 @@ def test_vpc_get_by_tag_value_subset():
|
|||
vpc2 = conn.create_vpc("10.0.0.0/16")
|
||||
conn.create_vpc("10.0.0.0/24")
|
||||
|
||||
vpc1.add_tag('Name', 'TestVPC')
|
||||
vpc1.add_tag('Key', 'TestVPC2')
|
||||
vpc2.add_tag('Name', 'TestVPC')
|
||||
vpc2.add_tag('Key', 'TestVPC2')
|
||||
vpc1.add_tag("Name", "TestVPC")
|
||||
vpc1.add_tag("Key", "TestVPC2")
|
||||
vpc2.add_tag("Name", "TestVPC")
|
||||
vpc2.add_tag("Key", "TestVPC2")
|
||||
|
||||
vpcs = conn.get_all_vpcs(filters={'tag-value': ['TestVPC', 'TestVPC2']})
|
||||
vpcs = conn.get_all_vpcs(filters={"tag-value": ["TestVPC", "TestVPC2"]})
|
||||
vpcs.should.have.length_of(2)
|
||||
vpc_ids = tuple(map(lambda v: v.id, vpcs))
|
||||
vpc1.id.should.be.within(vpc_ids)
|
||||
|
|
@ -254,117 +252,116 @@ def test_vpc_get_by_tag_value_subset():
|
|||
|
||||
@mock_ec2
|
||||
def test_default_vpc():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the default VPC
|
||||
default_vpc = list(ec2.vpcs.all())[0]
|
||||
default_vpc.cidr_block.should.equal('172.31.0.0/16')
|
||||
default_vpc.instance_tenancy.should.equal('default')
|
||||
default_vpc.cidr_block.should.equal("172.31.0.0/16")
|
||||
default_vpc.instance_tenancy.should.equal("default")
|
||||
default_vpc.reload()
|
||||
default_vpc.is_default.should.be.ok
|
||||
|
||||
# Test default values for VPC attributes
|
||||
response = default_vpc.describe_attribute(Attribute='enableDnsSupport')
|
||||
attr = response.get('EnableDnsSupport')
|
||||
attr.get('Value').should.be.ok
|
||||
response = default_vpc.describe_attribute(Attribute="enableDnsSupport")
|
||||
attr = response.get("EnableDnsSupport")
|
||||
attr.get("Value").should.be.ok
|
||||
|
||||
response = default_vpc.describe_attribute(Attribute='enableDnsHostnames')
|
||||
attr = response.get('EnableDnsHostnames')
|
||||
attr.get('Value').should.be.ok
|
||||
response = default_vpc.describe_attribute(Attribute="enableDnsHostnames")
|
||||
attr = response.get("EnableDnsHostnames")
|
||||
attr.get("Value").should.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_non_default_vpc():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the default VPC - this already exists when backend instantiated!
|
||||
#ec2.create_vpc(CidrBlock='172.31.0.0/16')
|
||||
# ec2.create_vpc(CidrBlock='172.31.0.0/16')
|
||||
|
||||
# Create the non default VPC
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
# Test default instance_tenancy
|
||||
vpc.instance_tenancy.should.equal('default')
|
||||
vpc.instance_tenancy.should.equal("default")
|
||||
|
||||
# Test default values for VPC attributes
|
||||
response = vpc.describe_attribute(Attribute='enableDnsSupport')
|
||||
attr = response.get('EnableDnsSupport')
|
||||
attr.get('Value').should.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsSupport")
|
||||
attr = response.get("EnableDnsSupport")
|
||||
attr.get("Value").should.be.ok
|
||||
|
||||
response = vpc.describe_attribute(Attribute='enableDnsHostnames')
|
||||
attr = response.get('EnableDnsHostnames')
|
||||
attr.get('Value').shouldnt.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsHostnames")
|
||||
attr = response.get("EnableDnsHostnames")
|
||||
attr.get("Value").shouldnt.be.ok
|
||||
|
||||
# Check Primary CIDR Block Associations
|
||||
cidr_block_association_set = next(iter(vpc.cidr_block_association_set), None)
|
||||
cidr_block_association_set['CidrBlockState']['State'].should.equal('associated')
|
||||
cidr_block_association_set['CidrBlock'].should.equal(vpc.cidr_block)
|
||||
cidr_block_association_set['AssociationId'].should.contain('vpc-cidr-assoc')
|
||||
cidr_block_association_set["CidrBlockState"]["State"].should.equal("associated")
|
||||
cidr_block_association_set["CidrBlock"].should.equal(vpc.cidr_block)
|
||||
cidr_block_association_set["AssociationId"].should.contain("vpc-cidr-assoc")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_dedicated_tenancy():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the default VPC
|
||||
ec2.create_vpc(CidrBlock='172.31.0.0/16')
|
||||
ec2.create_vpc(CidrBlock="172.31.0.0/16")
|
||||
|
||||
# Create the non default VPC
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16', InstanceTenancy='dedicated')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16", InstanceTenancy="dedicated")
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
vpc.instance_tenancy.should.equal('dedicated')
|
||||
vpc.instance_tenancy.should.equal("dedicated")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_modify_enable_dns_support():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the default VPC
|
||||
ec2.create_vpc(CidrBlock='172.31.0.0/16')
|
||||
ec2.create_vpc(CidrBlock="172.31.0.0/16")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
# Test default values for VPC attributes
|
||||
response = vpc.describe_attribute(Attribute='enableDnsSupport')
|
||||
attr = response.get('EnableDnsSupport')
|
||||
attr.get('Value').should.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsSupport")
|
||||
attr = response.get("EnableDnsSupport")
|
||||
attr.get("Value").should.be.ok
|
||||
|
||||
vpc.modify_attribute(EnableDnsSupport={'Value': False})
|
||||
vpc.modify_attribute(EnableDnsSupport={"Value": False})
|
||||
|
||||
response = vpc.describe_attribute(Attribute='enableDnsSupport')
|
||||
attr = response.get('EnableDnsSupport')
|
||||
attr.get('Value').shouldnt.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsSupport")
|
||||
attr = response.get("EnableDnsSupport")
|
||||
attr.get("Value").shouldnt.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_modify_enable_dns_hostnames():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create the default VPC
|
||||
ec2.create_vpc(CidrBlock='172.31.0.0/16')
|
||||
ec2.create_vpc(CidrBlock="172.31.0.0/16")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
# Test default values for VPC attributes
|
||||
response = vpc.describe_attribute(Attribute='enableDnsHostnames')
|
||||
attr = response.get('EnableDnsHostnames')
|
||||
attr.get('Value').shouldnt.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsHostnames")
|
||||
attr = response.get("EnableDnsHostnames")
|
||||
attr.get("Value").shouldnt.be.ok
|
||||
|
||||
vpc.modify_attribute(EnableDnsHostnames={'Value': True})
|
||||
vpc.modify_attribute(EnableDnsHostnames={"Value": True})
|
||||
|
||||
response = vpc.describe_attribute(Attribute='enableDnsHostnames')
|
||||
attr = response.get('EnableDnsHostnames')
|
||||
attr.get('Value').should.be.ok
|
||||
response = vpc.describe_attribute(Attribute="enableDnsHostnames")
|
||||
attr = response.get("EnableDnsHostnames")
|
||||
attr.get("Value").should.be.ok
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_vpc_associate_dhcp_options():
|
||||
conn = boto.connect_vpc()
|
||||
dhcp_options = conn.create_dhcp_options(
|
||||
SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
|
||||
conn.associate_dhcp_options(dhcp_options.id, vpc.id)
|
||||
|
|
@ -375,117 +372,206 @@ def test_vpc_associate_dhcp_options():
|
|||
|
||||
@mock_ec2
|
||||
def test_associate_vpc_ipv4_cidr_block():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.10.42.0/24')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.10.42.0/24")
|
||||
|
||||
# Associate/Extend vpc CIDR range up to 5 ciders
|
||||
for i in range(43, 47):
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, CidrBlock='10.10.{}.0/24'.format(i))
|
||||
response['CidrBlockAssociation']['CidrBlockState']['State'].should.equal('associating')
|
||||
response['CidrBlockAssociation']['CidrBlock'].should.equal('10.10.{}.0/24'.format(i))
|
||||
response['CidrBlockAssociation']['AssociationId'].should.contain('vpc-cidr-assoc')
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc.id, CidrBlock="10.10.{}.0/24".format(i)
|
||||
)
|
||||
response["CidrBlockAssociation"]["CidrBlockState"]["State"].should.equal(
|
||||
"associating"
|
||||
)
|
||||
response["CidrBlockAssociation"]["CidrBlock"].should.equal(
|
||||
"10.10.{}.0/24".format(i)
|
||||
)
|
||||
response["CidrBlockAssociation"]["AssociationId"].should.contain(
|
||||
"vpc-cidr-assoc"
|
||||
)
|
||||
|
||||
# Check all associations exist
|
||||
vpc = ec2.Vpc(vpc.id)
|
||||
vpc.cidr_block_association_set.should.have.length_of(5)
|
||||
vpc.cidr_block_association_set[2]['CidrBlockState']['State'].should.equal('associated')
|
||||
vpc.cidr_block_association_set[4]['CidrBlockState']['State'].should.equal('associated')
|
||||
vpc.cidr_block_association_set[2]["CidrBlockState"]["State"].should.equal(
|
||||
"associated"
|
||||
)
|
||||
vpc.cidr_block_association_set[4]["CidrBlockState"]["State"].should.equal(
|
||||
"associated"
|
||||
)
|
||||
|
||||
# Check error on adding 6th association.
|
||||
with assert_raises(ClientError) as ex:
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, CidrBlock='10.10.50.0/22')
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc.id, CidrBlock="10.10.50.0/22"
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (CidrLimitExceeded) when calling the AssociateVpcCidrBlock "
|
||||
"operation: This network '{}' has met its maximum number of allowed CIDRs: 5".format(vpc.id))
|
||||
"operation: This network '{}' has met its maximum number of allowed CIDRs: 5".format(
|
||||
vpc.id
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_disassociate_vpc_ipv4_cidr_block():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock='10.10.42.0/24')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, CidrBlock='10.10.43.0/24')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.10.42.0/24")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, CidrBlock="10.10.43.0/24")
|
||||
|
||||
# Remove an extended cidr block
|
||||
vpc = ec2.Vpc(vpc.id)
|
||||
non_default_assoc_cidr_block = next(iter([x for x in vpc.cidr_block_association_set if vpc.cidr_block != x['CidrBlock']]), None)
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(AssociationId=non_default_assoc_cidr_block['AssociationId'])
|
||||
response['CidrBlockAssociation']['CidrBlockState']['State'].should.equal('disassociating')
|
||||
response['CidrBlockAssociation']['CidrBlock'].should.equal(non_default_assoc_cidr_block['CidrBlock'])
|
||||
response['CidrBlockAssociation']['AssociationId'].should.equal(non_default_assoc_cidr_block['AssociationId'])
|
||||
non_default_assoc_cidr_block = next(
|
||||
iter(
|
||||
[
|
||||
x
|
||||
for x in vpc.cidr_block_association_set
|
||||
if vpc.cidr_block != x["CidrBlock"]
|
||||
]
|
||||
),
|
||||
None,
|
||||
)
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(
|
||||
AssociationId=non_default_assoc_cidr_block["AssociationId"]
|
||||
)
|
||||
response["CidrBlockAssociation"]["CidrBlockState"]["State"].should.equal(
|
||||
"disassociating"
|
||||
)
|
||||
response["CidrBlockAssociation"]["CidrBlock"].should.equal(
|
||||
non_default_assoc_cidr_block["CidrBlock"]
|
||||
)
|
||||
response["CidrBlockAssociation"]["AssociationId"].should.equal(
|
||||
non_default_assoc_cidr_block["AssociationId"]
|
||||
)
|
||||
|
||||
# Error attempting to delete a non-existent CIDR_BLOCK association
|
||||
with assert_raises(ClientError) as ex:
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(AssociationId='vpc-cidr-assoc-BORING123')
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(
|
||||
AssociationId="vpc-cidr-assoc-BORING123"
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidVpcCidrBlockAssociationIdError.NotFound) when calling the "
|
||||
"DisassociateVpcCidrBlock operation: The vpc CIDR block association ID "
|
||||
"'vpc-cidr-assoc-BORING123' does not exist")
|
||||
"'vpc-cidr-assoc-BORING123' does not exist"
|
||||
)
|
||||
|
||||
# Error attempting to delete Primary CIDR BLOCK association
|
||||
vpc_base_cidr_assoc_id = next(iter([x for x in vpc.cidr_block_association_set
|
||||
if vpc.cidr_block == x['CidrBlock']]), {})['AssociationId']
|
||||
vpc_base_cidr_assoc_id = next(
|
||||
iter(
|
||||
[
|
||||
x
|
||||
for x in vpc.cidr_block_association_set
|
||||
if vpc.cidr_block == x["CidrBlock"]
|
||||
]
|
||||
),
|
||||
{},
|
||||
)["AssociationId"]
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(AssociationId=vpc_base_cidr_assoc_id)
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(
|
||||
AssociationId=vpc_base_cidr_assoc_id
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (OperationNotPermitted) when calling the DisassociateVpcCidrBlock operation: "
|
||||
"The vpc CIDR block with association ID {} may not be disassociated. It is the primary "
|
||||
"IPv4 CIDR block of the VPC".format(vpc_base_cidr_assoc_id))
|
||||
"IPv4 CIDR block of the VPC".format(vpc_base_cidr_assoc_id)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_cidr_block_association_filters():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc1 = ec2.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
vpc2 = ec2.create_vpc(CidrBlock='10.91.0.0/16')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc2.id, CidrBlock='10.10.0.0/19')
|
||||
vpc3 = ec2.create_vpc(CidrBlock='10.92.0.0/24')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock='10.92.1.0/24')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock='10.92.2.0/24')
|
||||
vpc3_assoc_response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock='10.92.3.0/24')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc1 = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
vpc2 = ec2.create_vpc(CidrBlock="10.91.0.0/16")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc2.id, CidrBlock="10.10.0.0/19")
|
||||
vpc3 = ec2.create_vpc(CidrBlock="10.92.0.0/24")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock="10.92.1.0/24")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock="10.92.2.0/24")
|
||||
vpc3_assoc_response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc3.id, CidrBlock="10.92.3.0/24"
|
||||
)
|
||||
|
||||
# Test filters for a cidr-block in all VPCs cidr-block-associations
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'cidr-block-association.cidr-block',
|
||||
'Values': ['10.10.0.0/19']}]))
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{
|
||||
"Name": "cidr-block-association.cidr-block",
|
||||
"Values": ["10.10.0.0/19"],
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(1)
|
||||
filtered_vpcs[0].id.should.equal(vpc2.id)
|
||||
|
||||
# Test filter for association id in VPCs
|
||||
association_id = vpc3_assoc_response['CidrBlockAssociation']['AssociationId']
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'cidr-block-association.association-id',
|
||||
'Values': [association_id]}]))
|
||||
association_id = vpc3_assoc_response["CidrBlockAssociation"]["AssociationId"]
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{
|
||||
"Name": "cidr-block-association.association-id",
|
||||
"Values": [association_id],
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(1)
|
||||
filtered_vpcs[0].id.should.equal(vpc3.id)
|
||||
|
||||
# Test filter for association state in VPC - this will never show anything in this test
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'cidr-block-association.association-id',
|
||||
'Values': ['failing']}]))
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{"Name": "cidr-block-association.association-id", "Values": ["failing"]}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpc_associate_ipv6_cidr_block():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Test create VPC with IPV6 cidr range
|
||||
vpc = ec2.create_vpc(CidrBlock='10.10.42.0/24', AmazonProvidedIpv6CidrBlock=True)
|
||||
ipv6_cidr_block_association_set = next(iter(vpc.ipv6_cidr_block_association_set), None)
|
||||
ipv6_cidr_block_association_set['Ipv6CidrBlockState']['State'].should.equal('associated')
|
||||
ipv6_cidr_block_association_set['Ipv6CidrBlock'].should.contain('::/56')
|
||||
ipv6_cidr_block_association_set['AssociationId'].should.contain('vpc-cidr-assoc')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.10.42.0/24", AmazonProvidedIpv6CidrBlock=True)
|
||||
ipv6_cidr_block_association_set = next(
|
||||
iter(vpc.ipv6_cidr_block_association_set), None
|
||||
)
|
||||
ipv6_cidr_block_association_set["Ipv6CidrBlockState"]["State"].should.equal(
|
||||
"associated"
|
||||
)
|
||||
ipv6_cidr_block_association_set["Ipv6CidrBlock"].should.contain("::/56")
|
||||
ipv6_cidr_block_association_set["AssociationId"].should.contain("vpc-cidr-assoc")
|
||||
|
||||
# Test Fail on adding 2nd IPV6 association - AWS only allows 1 at this time!
|
||||
with assert_raises(ClientError) as ex:
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, AmazonProvidedIpv6CidrBlock=True)
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc.id, AmazonProvidedIpv6CidrBlock=True
|
||||
)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (CidrLimitExceeded) when calling the AssociateVpcCidrBlock "
|
||||
"operation: This network '{}' has met its maximum number of allowed CIDRs: 1".format(vpc.id))
|
||||
"operation: This network '{}' has met its maximum number of allowed CIDRs: 1".format(
|
||||
vpc.id
|
||||
)
|
||||
)
|
||||
|
||||
# Test associate ipv6 cidr block after vpc created
|
||||
vpc = ec2.create_vpc(CidrBlock='10.10.50.0/24')
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc.id, AmazonProvidedIpv6CidrBlock=True)
|
||||
response['Ipv6CidrBlockAssociation']['Ipv6CidrBlockState']['State'].should.equal('associating')
|
||||
response['Ipv6CidrBlockAssociation']['Ipv6CidrBlock'].should.contain('::/56')
|
||||
response['Ipv6CidrBlockAssociation']['AssociationId'].should.contain('vpc-cidr-assoc-')
|
||||
vpc = ec2.create_vpc(CidrBlock="10.10.50.0/24")
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc.id, AmazonProvidedIpv6CidrBlock=True
|
||||
)
|
||||
response["Ipv6CidrBlockAssociation"]["Ipv6CidrBlockState"]["State"].should.equal(
|
||||
"associating"
|
||||
)
|
||||
response["Ipv6CidrBlockAssociation"]["Ipv6CidrBlock"].should.contain("::/56")
|
||||
response["Ipv6CidrBlockAssociation"]["AssociationId"].should.contain(
|
||||
"vpc-cidr-assoc-"
|
||||
)
|
||||
|
||||
# Check on describe vpc that has ipv6 cidr block association
|
||||
vpc = ec2.Vpc(vpc.id)
|
||||
|
|
@ -494,72 +580,248 @@ def test_vpc_associate_ipv6_cidr_block():
|
|||
|
||||
@mock_ec2
|
||||
def test_vpc_disassociate_ipv6_cidr_block():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Test create VPC with IPV6 cidr range
|
||||
vpc = ec2.create_vpc(CidrBlock='10.10.42.0/24', AmazonProvidedIpv6CidrBlock=True)
|
||||
vpc = ec2.create_vpc(CidrBlock="10.10.42.0/24", AmazonProvidedIpv6CidrBlock=True)
|
||||
# Test disassociating the only IPV6
|
||||
assoc_id = vpc.ipv6_cidr_block_association_set[0]['AssociationId']
|
||||
assoc_id = vpc.ipv6_cidr_block_association_set[0]["AssociationId"]
|
||||
response = ec2.meta.client.disassociate_vpc_cidr_block(AssociationId=assoc_id)
|
||||
response['Ipv6CidrBlockAssociation']['Ipv6CidrBlockState']['State'].should.equal('disassociating')
|
||||
response['Ipv6CidrBlockAssociation']['Ipv6CidrBlock'].should.contain('::/56')
|
||||
response['Ipv6CidrBlockAssociation']['AssociationId'].should.equal(assoc_id)
|
||||
response["Ipv6CidrBlockAssociation"]["Ipv6CidrBlockState"]["State"].should.equal(
|
||||
"disassociating"
|
||||
)
|
||||
response["Ipv6CidrBlockAssociation"]["Ipv6CidrBlock"].should.contain("::/56")
|
||||
response["Ipv6CidrBlockAssociation"]["AssociationId"].should.equal(assoc_id)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_ipv6_cidr_block_association_filters():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
vpc1 = ec2.create_vpc(CidrBlock='10.90.0.0/16')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
vpc1 = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
|
||||
vpc2 = ec2.create_vpc(CidrBlock='10.91.0.0/16', AmazonProvidedIpv6CidrBlock=True)
|
||||
vpc2_assoc_ipv6_assoc_id = vpc2.ipv6_cidr_block_association_set[0]['AssociationId']
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc2.id, CidrBlock='10.10.0.0/19')
|
||||
vpc2 = ec2.create_vpc(CidrBlock="10.91.0.0/16", AmazonProvidedIpv6CidrBlock=True)
|
||||
vpc2_assoc_ipv6_assoc_id = vpc2.ipv6_cidr_block_association_set[0]["AssociationId"]
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc2.id, CidrBlock="10.10.0.0/19")
|
||||
|
||||
vpc3 = ec2.create_vpc(CidrBlock='10.92.0.0/24')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock='10.92.1.0/24')
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock='10.92.2.0/24')
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, AmazonProvidedIpv6CidrBlock=True)
|
||||
vpc3_ipv6_cidr_block = response['Ipv6CidrBlockAssociation']['Ipv6CidrBlock']
|
||||
vpc3 = ec2.create_vpc(CidrBlock="10.92.0.0/24")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock="10.92.1.0/24")
|
||||
ec2.meta.client.associate_vpc_cidr_block(VpcId=vpc3.id, CidrBlock="10.92.2.0/24")
|
||||
response = ec2.meta.client.associate_vpc_cidr_block(
|
||||
VpcId=vpc3.id, AmazonProvidedIpv6CidrBlock=True
|
||||
)
|
||||
vpc3_ipv6_cidr_block = response["Ipv6CidrBlockAssociation"]["Ipv6CidrBlock"]
|
||||
|
||||
vpc4 = ec2.create_vpc(CidrBlock='10.95.0.0/16') # Here for its looks
|
||||
vpc4 = ec2.create_vpc(CidrBlock="10.95.0.0/16") # Here for its looks
|
||||
|
||||
# Test filters for an ipv6 cidr-block in all VPCs cidr-block-associations
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'ipv6-cidr-block-association.ipv6-cidr-block',
|
||||
'Values': [vpc3_ipv6_cidr_block]}]))
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{
|
||||
"Name": "ipv6-cidr-block-association.ipv6-cidr-block",
|
||||
"Values": [vpc3_ipv6_cidr_block],
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(1)
|
||||
filtered_vpcs[0].id.should.equal(vpc3.id)
|
||||
|
||||
# Test filter for association id in VPCs
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'ipv6-cidr-block-association.association-id',
|
||||
'Values': [vpc2_assoc_ipv6_assoc_id]}]))
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{
|
||||
"Name": "ipv6-cidr-block-association.association-id",
|
||||
"Values": [vpc2_assoc_ipv6_assoc_id],
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(1)
|
||||
filtered_vpcs[0].id.should.equal(vpc2.id)
|
||||
|
||||
# Test filter for association state in VPC - this will never show anything in this test
|
||||
filtered_vpcs = list(ec2.vpcs.filter(Filters=[{'Name': 'ipv6-cidr-block-association.state',
|
||||
'Values': ['associated']}]))
|
||||
filtered_vpcs.should.be.length_of(2) # 2 of 4 VPCs
|
||||
filtered_vpcs = list(
|
||||
ec2.vpcs.filter(
|
||||
Filters=[
|
||||
{"Name": "ipv6-cidr-block-association.state", "Values": ["associated"]}
|
||||
]
|
||||
)
|
||||
)
|
||||
filtered_vpcs.should.be.length_of(2) # 2 of 4 VPCs
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_vpc_with_invalid_cidr_block_parameter():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc_cidr_block = '1000.1.0.0/20'
|
||||
vpc_cidr_block = "1000.1.0.0/20"
|
||||
with assert_raises(ClientError) as ex:
|
||||
vpc = ec2.create_vpc(CidrBlock=vpc_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidParameterValue) when calling the CreateVpc "
|
||||
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(vpc_cidr_block))
|
||||
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(
|
||||
vpc_cidr_block
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_vpc_with_invalid_cidr_range():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc_cidr_block = '10.1.0.0/29'
|
||||
vpc_cidr_block = "10.1.0.0/29"
|
||||
with assert_raises(ClientError) as ex:
|
||||
vpc = ec2.create_vpc(CidrBlock=vpc_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidVpc.Range) when calling the CreateVpc "
|
||||
"operation: The CIDR '{}' is invalid.".format(vpc_cidr_block))
|
||||
"operation: The CIDR '{}' is invalid.".format(vpc_cidr_block)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_enable_vpc_classic_link():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.1.0.0/16")
|
||||
|
||||
response = ec2.meta.client.enable_vpc_classic_link(VpcId=vpc.id)
|
||||
assert response.get("Return").should.be.true
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_enable_vpc_classic_link_failure():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
|
||||
response = ec2.meta.client.enable_vpc_classic_link(VpcId=vpc.id)
|
||||
assert response.get("Return").should.be.false
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_disable_vpc_classic_link():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link(VpcId=vpc.id)
|
||||
response = ec2.meta.client.disable_vpc_classic_link(VpcId=vpc.id)
|
||||
assert response.get("Return").should.be.false
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_enabled():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link(VpcId=vpc.id)
|
||||
response = ec2.meta.client.describe_vpc_classic_link(VpcIds=[vpc.id])
|
||||
assert response.get("Vpcs")[0].get("ClassicLinkEnabled").should.be.true
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_disabled():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
|
||||
response = ec2.meta.client.describe_vpc_classic_link(VpcIds=[vpc.id])
|
||||
assert response.get("Vpcs")[0].get("ClassicLinkEnabled").should.be.false
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_multiple():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc1 = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link(VpcId=vpc2.id)
|
||||
response = ec2.meta.client.describe_vpc_classic_link(VpcIds=[vpc1.id, vpc2.id])
|
||||
expected = [
|
||||
{"VpcId": vpc1.id, "ClassicLinkDnsSupported": False},
|
||||
{"VpcId": vpc2.id, "ClassicLinkDnsSupported": True},
|
||||
]
|
||||
|
||||
# Ensure response is sorted, because they can come in random order
|
||||
assert response.get("Vpcs").sort(key=lambda x: x["VpcId"]) == expected.sort(
|
||||
key=lambda x: x["VpcId"]
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_enable_vpc_classic_link_dns_support():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.1.0.0/16")
|
||||
|
||||
response = ec2.meta.client.enable_vpc_classic_link_dns_support(VpcId=vpc.id)
|
||||
assert response.get("Return").should.be.true
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_disable_vpc_classic_link_dns_support():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link_dns_support(VpcId=vpc.id)
|
||||
response = ec2.meta.client.disable_vpc_classic_link_dns_support(VpcId=vpc.id)
|
||||
assert response.get("Return").should.be.false
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_dns_support_enabled():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link_dns_support(VpcId=vpc.id)
|
||||
response = ec2.meta.client.describe_vpc_classic_link_dns_support(VpcIds=[vpc.id])
|
||||
assert response.get("Vpcs")[0].get("ClassicLinkDnsSupported").should.be.true
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_dns_support_disabled():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
|
||||
response = ec2.meta.client.describe_vpc_classic_link_dns_support(VpcIds=[vpc.id])
|
||||
assert response.get("Vpcs")[0].get("ClassicLinkDnsSupported").should.be.false
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_classic_link_dns_support_multiple():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
# Create VPC
|
||||
vpc1 = ec2.create_vpc(CidrBlock="10.90.0.0/16")
|
||||
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
|
||||
ec2.meta.client.enable_vpc_classic_link_dns_support(VpcId=vpc2.id)
|
||||
response = ec2.meta.client.describe_vpc_classic_link_dns_support(
|
||||
VpcIds=[vpc1.id, vpc2.id]
|
||||
)
|
||||
expected = [
|
||||
{"VpcId": vpc1.id, "ClassicLinkDnsSupported": False},
|
||||
{"VpcId": vpc2.id, "ClassicLinkDnsSupported": True},
|
||||
]
|
||||
|
||||
# Ensure response is sorted, because they can come in random order
|
||||
assert response.get("Vpcs").sort(key=lambda x: x["VpcId"]) == expected.sort(
|
||||
key=lambda x: x["VpcId"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,51 +1,53 @@
|
|||
from __future__ import unicode_literals
|
||||
import boto
|
||||
from nose.tools import assert_raises
|
||||
import sure # noqa
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_vpn_connections():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_connection = conn.create_vpn_connection(
|
||||
'ipsec.1', 'vgw-0123abcd', 'cgw-0123abcd')
|
||||
vpn_connection.should_not.be.none
|
||||
vpn_connection.id.should.match(r'vpn-\w+')
|
||||
vpn_connection.type.should.equal('ipsec.1')
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_vpn_connections():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_connection = conn.create_vpn_connection(
|
||||
'ipsec.1', 'vgw-0123abcd', 'cgw-0123abcd')
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
conn.delete_vpn_connection(vpn_connection.id)
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_vpn_connections_bad_id():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.delete_vpn_connection('vpn-0123abcd')
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_vpn_connections():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(0)
|
||||
conn.create_vpn_connection('ipsec.1', 'vgw-0123abcd', 'cgw-0123abcd')
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
vpn = conn.create_vpn_connection('ipsec.1', 'vgw-1234abcd', 'cgw-1234abcd')
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(2)
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections(vpn.id)
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
from __future__ import unicode_literals
|
||||
import boto
|
||||
from nose.tools import assert_raises
|
||||
import sure # noqa
|
||||
from boto.exception import EC2ResponseError
|
||||
|
||||
from moto import mock_ec2_deprecated
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_create_vpn_connections():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpn_connection = conn.create_vpn_connection(
|
||||
"ipsec.1", "vgw-0123abcd", "cgw-0123abcd"
|
||||
)
|
||||
vpn_connection.should_not.be.none
|
||||
vpn_connection.id.should.match(r"vpn-\w+")
|
||||
vpn_connection.type.should.equal("ipsec.1")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_vpn_connections():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
vpn_connection = conn.create_vpn_connection(
|
||||
"ipsec.1", "vgw-0123abcd", "cgw-0123abcd"
|
||||
)
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
conn.delete_vpn_connection(vpn_connection.id)
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_delete_vpn_connections_bad_id():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
with assert_raises(EC2ResponseError):
|
||||
conn.delete_vpn_connection("vpn-0123abcd")
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_describe_vpn_connections():
|
||||
conn = boto.connect_vpc("the_key", "the_secret")
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(0)
|
||||
conn.create_vpn_connection("ipsec.1", "vgw-0123abcd", "cgw-0123abcd")
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
vpn = conn.create_vpn_connection("ipsec.1", "vgw-1234abcd", "cgw-1234abcd")
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections()
|
||||
list_of_vpn_connections.should.have.length_of(2)
|
||||
list_of_vpn_connections = conn.get_all_vpn_connections(vpn.id)
|
||||
list_of_vpn_connections.should.have.length_of(1)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue