diff --git a/botocore/handlers.py b/botocore/handlers.py index 7c9673cf9d..40dd7ad776 100644 --- a/botocore/handlers.py +++ b/botocore/handlers.py @@ -372,8 +372,11 @@ def parse_get_bucket_location(parsed, http_response, **kwargs): def base64_encode_user_data(params, **kwargs): if 'UserData' in params: + if isinstance(params['UserData'], six.text_type): + # Encode it to bytes if it is text. + params['UserData'] = params['UserData'].encode('utf-8') params['UserData'] = base64.b64encode( - params['UserData'].encode('utf-8')).decode('utf-8') + params['UserData']).decode('utf-8') def fix_route53_ids(params, model, **kwargs): diff --git a/tests/unit/test_ec2_operations.py b/tests/unit/test_ec2_operations.py index 9e1244efa1..ece9054779 100644 --- a/tests/unit/test_ec2_operations.py +++ b/tests/unit/test_ec2_operations.py @@ -86,19 +86,6 @@ def test_request_spot_instances(self): 'LaunchSpecification.BlockDeviceMapping.4.VirtualName': 'ephemeral3'} self.assert_params_serialize_to('ec2.RequestSpotInstances', params, result) - def test_run_instances_userdata(self): - user_data = 'This is a test' - b64_user_data = base64.b64encode(six.b(user_data)).decode('utf-8') - op = self.ec2.get_operation('RunInstances') - params = dict(image_id='img-12345678', - min_count=1, max_count=5, user_data=user_data) - result = {'ImageId': 'img-12345678', - 'MinCount': 1, - 'MaxCount': 5, - 'UserData': b64_user_data} - # TODO: We need to base64 decode this! Needs a customization - #self.assert_params_serialize_to('ec2.RunInstances', params, result) - def test_authorize_security_groups_ingress(self): params = dict( group_name='MyGroup', diff --git a/tests/unit/test_handlers.py b/tests/unit/test_handlers.py index 07cf5b070b..090b06270c 100644 --- a/tests/unit/test_handlers.py +++ b/tests/unit/test_handlers.py @@ -247,6 +247,37 @@ def test_route53_resource_id_missing_input_shape(self): self.assertEqual(params['HostedZoneId'], '/hostedzone/ABC123') + def test_run_instances_userdata(self): + user_data = 'This is a test' + b64_user_data = base64.b64encode(six.b(user_data)).decode('utf-8') + event = self.session.create_event( + 'before-parameter-build', 'ec2', 'RunInstances') + params = dict(ImageId='img-12345678', + MinCount=1, MaxCount=5, UserData=user_data) + self.session.emit(event, params=params) + result = {'ImageId': 'img-12345678', + 'MinCount': 1, + 'MaxCount': 5, + 'UserData': b64_user_data} + self.assertEqual(params, result) + + def test_run_instances_userdata_blob(self): + # Ensure that binary can be passed in as user data. + # This is valid because you can send gzip compressed files as + # user data. + user_data = b'\xc7\xa9This is a test' + b64_user_data = base64.b64encode(user_data).decode('utf-8') + event = self.session.create_event( + 'before-parameter-build', 'ec2', 'RunInstances') + params = dict(ImageId='img-12345678', + MinCount=1, MaxCount=5, UserData=user_data) + self.session.emit(event, params=params) + result = {'ImageId': 'img-12345678', + 'MinCount': 1, + 'MaxCount': 5, + 'UserData': b64_user_data} + self.assertEqual(params, result) + def test_fix_s3_host_initial(self): endpoint = mock.Mock(region_name='us-west-2') request = AWSRequest(