Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions awscli/customizations/ec2instanceconnect/eicefetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,17 @@ def _get_instance_connect_endpoint_by_id(
self, ec2_client, instance_connect_endpoint_id
):
args = {
"Filters": [{"Name": "state", "Values": ["create-complete"]}],
"Filters": [
{
"Name": "state",
"Values": [
"create-complete",
"update-in-progress",
"update-failed",
"update-complete",
],
}
],
"InstanceConnectEndpointIds": [instance_connect_endpoint_id],
}
describe_eice_response = (
Expand All @@ -72,7 +82,15 @@ def _get_instance_connect_endpoint_by_vpc(
## Describe until subnet match and if none match subnet then return the first one based on vpc-id filter
args = {
"Filters": [
{"Name": "state", "Values": ["create-complete"]},
{
"Name": "state",
"Values": [
"create-complete",
"update-in-progress",
"update-failed",
"update-complete",
],
},
{"Name": "vpc-id", "Values": [vpc_id]},
]
}
Expand All @@ -90,9 +108,7 @@ def _get_instance_connect_endpoint_by_vpc(
if page_result:
for eice in page_result:
if eice['SubnetId'] == subnet_id:
logger.debug(
f"Using EICE based on subnet: {instance_connect_endpoints[0]}"
)
logger.debug(f"Using EICE based on subnet: {eice}")
return eice

if instance_connect_endpoints:
Expand Down
45 changes: 41 additions & 4 deletions tests/functional/ec2instanceconnect/test_opentunnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,15 @@ def describe_eice_response_empty_fips_dns(dns_name, fips_dns_name):
def request_params_for_describe_eice():
return {
'Filters': [
{'Name': 'state', 'Values': ['create-complete']},
{
'Name': 'state',
'Values': [
'create-complete',
'update-in-progress',
'update-failed',
'update-complete',
],
},
{'Name': 'vpc-id', 'Values': ['vpc-123']},
]
}
Expand Down Expand Up @@ -434,6 +442,15 @@ def assert_url(dns_name, url):


class TestOpenTunnel:
@pytest.mark.parametrize(
"endpoint_state",
[
"create-complete",
"update-in-progress",
"update-failed",
"update-complete",
],
)
def test_single_connection_mode(
self,
cli_runner,
Expand All @@ -442,10 +459,11 @@ def test_single_connection_mode(
io_patch,
describe_instance_response,
dns_name,
describe_eice_response,
fips_dns_name,
request_params_for_describe_instance,
request_params_for_describe_eice,
datetime_utcnow_patch,
endpoint_state,
):
cli_runner.env["AWS_USE_FIPS_ENDPOINT"] = "false"
cmdline = [
Expand All @@ -456,8 +474,27 @@ def test_single_connection_mode(
"--max-tunnel-duration",
"1",
]

# Create endpoint response with the specified state
describe_eice_response_with_state = f"""
<DescribeInstanceConnectEndpointsResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<instanceConnectEndpointSet>
<item>
<dnsName>{dns_name}</dnsName>
<fipsDnsName>{fips_dns_name}</fipsDnsName>
<instanceConnectEndpointId>eice-123</instanceConnectEndpointId>
<state>{endpoint_state}</state>
<subnetId>subnet-123</subnetId>
<vpcId>vpc-123</vpcId>
</item>
</instanceConnectEndpointSet>
</DescribeInstanceConnectEndpointsResponse>
"""

cli_runner.add_response(HTTPResponse(body=describe_instance_response))
cli_runner.add_response(HTTPResponse(body=describe_eice_response))
cli_runner.add_response(
HTTPResponse(body=describe_eice_response_with_state)
)

test_server_input = b"Test Server Output"
mock_crt_websocket.add_output_from_server(test_server_input)
Expand All @@ -469,7 +506,7 @@ def test_single_connection_mode(
assert 0 == result.rc
assert pop_stdout_content() == test_server_input
assert_stdout_empty()
# Order of the query params on the url mater because of sigv4
# Order of the query params on the url matter because of sigv4
assert (
"eice-123.ec2-instance-connect-endpoint.us-west-2.amazonaws.com/openTunnel?"
"instanceConnectEndpointId=eice-123&remotePort=22&privateIpAddress=10.0.0.0&"
Expand Down
167 changes: 165 additions & 2 deletions tests/functional/ec2instanceconnect/test_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,39 @@ def get_describe_eice_response():
"""


def get_describe_eice_response_with_state(state):
return f"""
<DescribeInstanceConnectEndpointsResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<instanceConnectEndpointSet>
<item>
<dnsName>dns.com</dnsName>
<fipsDnsName>fips.dns.com</fipsDnsName>
<instanceConnectEndpointId>eice-123</instanceConnectEndpointId>
<state>{state}</state>
<subnetId>subnet-123</subnetId>
<vpcId>vpc-123</vpcId>
</item>
</instanceConnectEndpointSet>
</DescribeInstanceConnectEndpointsResponse>
"""


def get_describe_eice_response_create_complete():
return get_describe_eice_response_with_state("create-complete")


def get_describe_eice_response_update_in_progress():
return get_describe_eice_response_with_state("update-in-progress")


def get_describe_eice_response_update_complete():
return get_describe_eice_response_with_state("update-complete")


def get_describe_eice_response_update_failed():
return get_describe_eice_response_with_state("update-failed")


@pytest.fixture
def describe_eice_response():
return get_describe_eice_response()
Expand All @@ -184,15 +217,33 @@ def describe_eice_response():
def get_request_params_for_describe_eice():
return {
'Filters': [
{'Name': 'state', 'Values': ['create-complete']},
{
'Name': 'state',
'Values': [
'create-complete',
'update-in-progress',
'update-failed',
'update-complete',
],
},
{'Name': 'vpc-id', 'Values': ['vpc-123']},
]
}


def get_request_params_for_describe_eice_with_eice_id():
return {
'Filters': [{'Name': 'state', 'Values': ['create-complete']}],
'Filters': [
{
'Name': 'state',
'Values': [
'create-complete',
'update-in-progress',
'update-failed',
'update-complete',
],
}
],
'InstanceConnectEndpointIds': ['eice-12345'],
}

Expand Down Expand Up @@ -568,6 +619,118 @@ class TestSSHCommand:
],
id='Open-Tunnel: use provided ip',
),
pytest.param(
get_describe_private_instance_response(),
get_describe_eice_response_create_complete(),
get_request_params_for_describe_eice(),
[
"ec2-instance-connect",
"ssh",
"--instance-id",
"i-123",
"--private-key-file",
"/tmp/ssh-file",
],
[
'ssh',
'-o',
'ServerAliveInterval=5',
'-p',
'22',
'-i',
'/tmp/ssh-file',
'-o',
'ProxyCommand=aws ec2-instance-connect open-tunnel --instance-id i-123 '
'--private-ip-address 10.0.0.0 --remote-port 22 '
'--instance-connect-endpoint-id eice-123 --instance-connect-endpoint-dns-name dns.com',
'[email protected]',
],
id='Open-Tunnel: connect via eice in create-complete',
),
pytest.param(
get_describe_private_instance_response(),
get_describe_eice_response_update_in_progress(),
get_request_params_for_describe_eice(),
[
"ec2-instance-connect",
"ssh",
"--instance-id",
"i-123",
"--private-key-file",
"/tmp/ssh-file",
],
[
'ssh',
'-o',
'ServerAliveInterval=5',
'-p',
'22',
'-i',
'/tmp/ssh-file',
'-o',
'ProxyCommand=aws ec2-instance-connect open-tunnel --instance-id i-123 '
'--private-ip-address 10.0.0.0 --remote-port 22 '
'--instance-connect-endpoint-id eice-123 --instance-connect-endpoint-dns-name dns.com',
'[email protected]',
],
id='Open-Tunnel: connect via eice in update-in-progress',
),
pytest.param(
get_describe_private_instance_response(),
get_describe_eice_response_update_complete(),
get_request_params_for_describe_eice(),
[
"ec2-instance-connect",
"ssh",
"--instance-id",
"i-123",
"--private-key-file",
"/tmp/ssh-file",
],
[
'ssh',
'-o',
'ServerAliveInterval=5',
'-p',
'22',
'-i',
'/tmp/ssh-file',
'-o',
'ProxyCommand=aws ec2-instance-connect open-tunnel --instance-id i-123 '
'--private-ip-address 10.0.0.0 --remote-port 22 '
'--instance-connect-endpoint-id eice-123 --instance-connect-endpoint-dns-name dns.com',
'[email protected]',
],
id='Open-Tunnel: connect via eice in update-complete',
),
pytest.param(
get_describe_private_instance_response(),
get_describe_eice_response_update_failed(),
get_request_params_for_describe_eice(),
[
"ec2-instance-connect",
"ssh",
"--instance-id",
"i-123",
"--private-key-file",
"/tmp/ssh-file",
],
[
'ssh',
'-o',
'ServerAliveInterval=5',
'-p',
'22',
'-i',
'/tmp/ssh-file',
'-o',
'ProxyCommand=aws ec2-instance-connect open-tunnel --instance-id i-123 '
'--private-ip-address 10.0.0.0 --remote-port 22 '
'--instance-connect-endpoint-id eice-123 --instance-connect-endpoint-dns-name dns.com',
'[email protected]',
],
id='Open-Tunnel: connect via eice in update-failed',
),
pytest.param(
get_describe_public_instance_response(),
None,
Expand Down
Loading