diff --git a/moto/ec2/responses.py b/moto/ec2/responses.py
index aa6d630ed..4e6b0eef6 100644
--- a/moto/ec2/responses.py
+++ b/moto/ec2/responses.py
@@ -5,7 +5,7 @@ from urlparse import parse_qs
from jinja2 import Template
from .models import ec2_backend
-from .utils import instance_ids_from_querystring
+from .utils import instance_ids_from_querystring, camelcase_to_underscores
def instances(uri, body, headers):
@@ -33,11 +33,26 @@ def instances(uri, body, headers):
instances = ec2_backend.start_instances(instance_ids)
template = Template(EC2_START_INSTANCES)
return template.render(instances=instances)
- # elif action == 'DescribeInstanceAttribute':
- # attribute = querystring.get("Attribute")[0]
- # instance_id = instance_ids[0]
- # instance = ec2_backend.get_instance(instance_id)
- # import pdb;pdb.set_trace()
+ elif action == 'DescribeInstanceAttribute':
+ # TODO this and modify below should raise IncorrectInstanceState if instance not in stopped state
+ attribute = querystring.get("Attribute")[0]
+ normalized_attribute = camelcase_to_underscores(attribute)
+ instance_id = instance_ids[0]
+ instance = ec2_backend.get_instance(instance_id)
+ value = getattr(instance, normalized_attribute)
+ template = Template(EC2_DESCRIBE_INSTANCE_ATTRIBUTE)
+ return template.render(instance=instance, attribute=attribute, value=value)
+ elif action == 'ModifyInstanceAttribute':
+ for key, value in querystring.iteritems():
+ if '.Value' in key:
+ break
+
+ value = querystring.get(key)[0]
+ normalized_attribute = camelcase_to_underscores(key.split(".")[0])
+ instance_id = instance_ids[0]
+ instance = ec2_backend.get_instance(instance_id)
+ setattr(instance, normalized_attribute, value)
+ return EC2_MODIFY_INSTANCE_ATTRIBUTE
else:
import pdb;pdb.set_trace()
@@ -284,7 +299,12 @@ EC2_START_INSTANCES = """
EC2_DESCRIBE_INSTANCE_ATTRIBUTE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{{ instance.id }}
-
- aki-f70657b2
-
+ <{{ attribute }}>
+ {{ value }}
+ {{ attribute }}>
"""
+
+EC2_MODIFY_INSTANCE_ATTRIBUTE = """
+ 59dbff89-35bd-4eac-99ed-be587EXAMPLE
+ true
+"""
diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py
index 15f5c71c9..93dba95ad 100644
--- a/moto/ec2/utils.py
+++ b/moto/ec2/utils.py
@@ -23,3 +23,15 @@ def instance_ids_from_querystring(querystring_dict):
if 'InstanceId' in key:
instance_ids.append(value[0])
return instance_ids
+
+
+def camelcase_to_underscores(argument):
+ ''' Converts a camelcase param like theNewAttribute to the equivalent
+ python underscore variable like the_new_attribute'''
+ result = ''
+ for index, char in enumerate(argument):
+ if char.istitle() and index:
+ # Only add underscore is char is capital and not first letter
+ result += "_"
+ result += char.lower()
+ return result
diff --git a/tests/test_ec2/test_ec2.py b/tests/test_ec2/test_ec2.py
index c9d6670db..8408a498d 100644
--- a/tests/test_ec2/test_ec2.py
+++ b/tests/test_ec2/test_ec2.py
@@ -1,5 +1,5 @@
import boto
-from boto.ec2.instance import Reservation
+from boto.ec2.instance import Reservation, InstanceAttribute
from sure import expect
from moto import mock_ec2
@@ -44,9 +44,28 @@ def test_instance_start_and_stop():
started_instances = conn.start_instances(instances[0].id)
started_instances[0].state.should.equal('pending')
-# @mock_ec2
-# def test_instance_attributes():
-# conn = boto.connect_ec2('the_key', 'the_secret')
-# reservation = conn.run_instances('')
-# instance = reservation.instances[0]
-# instance_type_value = instance.get_attribute("instanceType")
+
+@mock_ec2
+def test_instance_attribute_instance_type():
+ conn = boto.connect_ec2('the_key', 'the_secret')
+ reservation = conn.run_instances('')
+ instance = reservation.instances[0]
+
+ instance.modify_attribute("instanceType", "m1.small")
+
+ instance_attribute = instance.get_attribute("instanceType")
+ instance_attribute.should.be.a(InstanceAttribute)
+ instance_attribute.get('instanceType').should.equal("m1.small")
+
+
+@mock_ec2
+def test_instance_attribute_user_data():
+ conn = boto.connect_ec2('the_key', 'the_secret')
+ reservation = conn.run_instances('')
+ instance = reservation.instances[0]
+
+ instance.modify_attribute("userData", "this is my user data")
+
+ instance_attribute = instance.get_attribute("userData")
+ instance_attribute.should.be.a(InstanceAttribute)
+ instance_attribute.get("userData").should.equal("this is my user data")