From fb0a4d64c87a2a4e6e7008701d79f7db55e060cc Mon Sep 17 00:00:00 2001 From: Viren Nadkarni Date: Thu, 22 Dec 2022 16:27:19 +0530 Subject: [PATCH] EC2: Implement GetPasswordData (#5798) --- IMPLEMENTATION_COVERAGE.md | 4 ++-- docs/docs/services/ec2.rst | 2 +- moto/ec2/models/__init__.py | 2 ++ moto/ec2/models/windows.py | 11 +++++++++++ moto/ec2/responses/windows.py | 21 ++++++++++++++++++++- tests/test_ec2/test_windows.py | 34 ++++++++++++++++++++++++++-------- 6 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 moto/ec2/models/windows.py diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 183c5bc7a..12c52387b 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2160,7 +2160,7 @@ - [X] get_managed_prefix_list_entries - [ ] get_network_insights_access_scope_analysis_findings - [ ] get_network_insights_access_scope_content -- [ ] get_password_data +- [x] get_password_data - [ ] get_reserved_instances_exchange_quote - [ ] get_serial_console_access_status - [ ] get_spot_placement_scores @@ -6835,4 +6835,4 @@ - workspaces - workspaces-web - xray - \ No newline at end of file + diff --git a/docs/docs/services/ec2.rst b/docs/docs/services/ec2.rst index 25736bddc..91d877815 100644 --- a/docs/docs/services/ec2.rst +++ b/docs/docs/services/ec2.rst @@ -478,7 +478,7 @@ ec2 - [X] get_managed_prefix_list_entries - [ ] get_network_insights_access_scope_analysis_findings - [ ] get_network_insights_access_scope_content -- [ ] get_password_data +- [x] get_password_data - [ ] get_reserved_instances_exchange_quote - [ ] get_serial_console_access_status - [ ] get_spot_placement_scores diff --git a/moto/ec2/models/__init__.py b/moto/ec2/models/__init__.py index bc8b04bde..05c64453a 100644 --- a/moto/ec2/models/__init__.py +++ b/moto/ec2/models/__init__.py @@ -47,6 +47,7 @@ from .vpn_connections import VPNConnectionBackend from .vpcs import VPCBackend from .vpc_peering_connections import VPCPeeringConnectionBackend from .vpc_service_configuration import VPCServiceConfigurationBackend +from .windows import WindowsBackend from ..utils import ( EC2_RESOURCE_TO_PREFIX, is_valid_resource_id, @@ -122,6 +123,7 @@ class EC2Backend( IamInstanceProfileAssociationBackend, CarrierGatewayBackend, FleetsBackend, + WindowsBackend, ): """ moto includes a limited set of AMIs in `moto/ec2/resources/amis.json`. diff --git a/moto/ec2/models/windows.py b/moto/ec2/models/windows.py new file mode 100644 index 000000000..5021bf49b --- /dev/null +++ b/moto/ec2/models/windows.py @@ -0,0 +1,11 @@ +from moto.moto_api._internal import mock_random as random + +from moto.core import BaseModel + + +class WindowsBackend(BaseModel): + def get_password_data(self, instance_id: str) -> str: + instance = self.get_instance(instance_id) + if instance.platform == "windows": + return random.get_random_string(length=128) + return "" diff --git a/moto/ec2/responses/windows.py b/moto/ec2/responses/windows.py index 673fc6ded..5e37f155d 100644 --- a/moto/ec2/responses/windows.py +++ b/moto/ec2/responses/windows.py @@ -1,4 +1,5 @@ from moto.core.responses import BaseResponse +from moto.ec2.utils import utc_date_and_time class Windows(BaseResponse): @@ -14,4 +15,22 @@ class Windows(BaseResponse): ) def get_password_data(self): - raise NotImplementedError("Windows.get_password_data is not yet implemented") + instance_id = self._get_param("InstanceId") + password_data = self.ec2_backend.get_password_data(instance_id) + template = self.response_template(GET_PASSWORD_DATA_RESPONSE) + return template.render( + password_data=password_data, + instance_id=instance_id, + timestamp=utc_date_and_time(), + ) + + +GET_PASSWORD_DATA_RESPONSE = """ + + + 6b9528d5-6818-4bd0-8936-cdedaEXAMPLE + {{ instance_id }} + {{ timestamp }} + {{ password_data }} + +""" diff --git a/tests/test_ec2/test_windows.py b/tests/test_ec2/test_windows.py index bd8afe5ba..0cc9200cb 100644 --- a/tests/test_ec2/test_windows.py +++ b/tests/test_ec2/test_windows.py @@ -1,8 +1,26 @@ -import sure # noqa # pylint: disable=unused-import - -from moto import mock_ec2 - - -@mock_ec2 -def test_windows(): - pass +import boto3 +import sure # noqa # pylint: disable=unused-import + +from moto import mock_ec2 +from tests import EXAMPLE_AMI_WINDOWS, EXAMPLE_AMI_PARAVIRTUAL + + +@mock_ec2 +def test_get_password_data(): + client = boto3.client("ec2", region_name="us-east-1") + + # Ensure non-windows instances return empty password data + instance_id = client.run_instances( + ImageId=EXAMPLE_AMI_PARAVIRTUAL, MinCount=1, MaxCount=1 + )["Instances"][0]["InstanceId"] + resp = client.get_password_data(InstanceId=instance_id) + resp["InstanceId"].should.equal(instance_id) + resp["PasswordData"].should.equal("") + + # Ensure Windows instances + instance_id = client.run_instances( + ImageId=EXAMPLE_AMI_WINDOWS, MinCount=1, MaxCount=1 + )["Instances"][0]["InstanceId"] + resp = client.get_password_data(InstanceId=instance_id) + resp["InstanceId"].should.equal(instance_id) + resp["PasswordData"].should.have.length_of(128)