Repository: getmoto/moto

Issue:
IAM create_policy bug 
According to the the AWS documentation, when we call the create_policy operation, it should create a a policy version with a version identifier of v1 and set v1 as the policy's default version. However, moto set the v1 policy default as False. 

Sample policy that was created:
```
{'Versions': [{'Document': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Action': 'logs:CreateLogGroup', 'Resource': '*'}, {'Effect': 'Allow', 'Action': ['dynamodb:DeleteItem', 'dynamodb:GetItem', 'dynamodb:PutItem'], 'Resource': '*'}]}, 'VersionId': 'v1', 'IsDefaultVersion': False, 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '20f7279f-99ee-11e1-a4c3-27EXAMPLE804', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'amazon.com'}, 'RetryAttempts': 0}}```


Discussion:
I've run into a few issues with creating/updating IAM policies as well.

It seems that if you update a policy multiple times with `SetAsDefault=True` then each of the updated policy versions will have `'IsDefaultVersion': True`.

If you update beyond the maximum number of policies the VersionId for updates 6+ will still be v5.

The CreateDate is always `datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()` regardless of when you create them. This may not necessarily be a bug but it could cause issues when using moto to test code that sorts policy versions by CreateDate.  


```
{
    'IsTruncated': False, 
    'ResponseMetadata': {
        'RetryAttempts': 0, 
        'HTTPStatusCode': 200, 
        'RequestId': '20f7279f-99ee-11e1-a4c3-27EXAMPLE804', 
        'HTTPHeaders': {'server': u'amazon.com'}
    }, 
    'Versions': [
        {'CreateDate': datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()), 'VersionId': 'v3', 'Document': {'Version': '2012-10-17', 'Statement': [{'Action': ['cloudwatch:ListTagsForResource'], 'Resource': '*', 'Effect': 'Allow'}]}, 'IsDefaultVersion': True}, 
        {'CreateDate': datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()), 'VersionId': 'v4', 'Document': {'Version': '2012-10-17', 'Statement': [{'Action': ['cloudwatch:ListTagsForResource'], 'Resource': '*', 'Effect': 'Allow'}]}, 'IsDefaultVersion': True}, 
        {'CreateDate': datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()), 'VersionId': 'v5', 'Document': {'Version': '2012-10-17', 'Statement': [{'Action': ['cloudwatch:ListTagsForResource'], 'Resource': '*', 'Effect': 'Allow'}]}, 'IsDefaultVersion': True}, 
        {'CreateDate': datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()), 'VersionId': 'v5', 'Document': {'Version': '2012-10-17', 'Statement': [{'Action': ['cloudwatch:ListTagsForResource'], 'Resource': '*', 'Effect': 'Allow'}]}, 'IsDefaultVersion': True}, 
        {'CreateDate': datetime.datetime(2012, 5, 9, 15, 45, 35, tzinfo=tzutc()), 'VersionId': 'v5', 'Document': {'Version': '2012-10-17', 'Statement': [{'Action': ['cloudwatch:ListTagsForResource'], 'Resource': '*', 'Effect': 'Allow'}]}, 'IsDefaultVersion': True}
    ]
}
```


Resolving patch:
diff --git a/moto/iam/exceptions.py b/moto/iam/exceptions.py
--- a/moto/iam/exceptions.py
+++ b/moto/iam/exceptions.py
@@ -26,6 +26,14 @@ def __init__(self, message):
             "ReportNotPresent", message)
 
 
+class IAMLimitExceededException(RESTError):
+    code = 400
+
+    def __init__(self, message):
+        super(IAMLimitExceededException, self).__init__(
+            "LimitExceeded", message)
+
+
 class MalformedCertificate(RESTError):
     code = 400
 
diff --git a/moto/iam/models.py b/moto/iam/models.py
--- a/moto/iam/models.py
+++ b/moto/iam/models.py
@@ -14,8 +14,8 @@
 from moto.iam.policy_validation import IAMPolicyDocumentValidator
 
 from .aws_managed_policies import aws_managed_policies_data
-from .exceptions import IAMNotFoundException, IAMConflictException, IAMReportNotPresentException, MalformedCertificate, \
-    DuplicateTags, TagKeyTooBig, InvalidTagCharacters, TooManyTags, TagValueTooBig
+from .exceptions import IAMNotFoundException, IAMConflictException, IAMReportNotPresentException, IAMLimitExceededException, \
+    MalformedCertificate, DuplicateTags, TagKeyTooBig, InvalidTagCharacters, TooManyTags, TagValueTooBig
 from .utils import random_access_key, random_alphanumeric, random_resource_id, random_policy_id
 
 ACCOUNT_ID = 123456789012
@@ -67,6 +67,13 @@ def __init__(self,
         self.create_date = create_date if create_date is not None else datetime.utcnow()
         self.update_date = update_date if update_date is not None else datetime.utcnow()
 
+    def update_default_version(self, new_default_version_id):
+        for version in self.versions:
+            if version.version_id == self.default_version_id:
+                version.is_default = False
+                break
+        self.default_version_id = new_default_version_id
+
     @property
     def created_iso_8601(self):
         return iso_8601_datetime_with_milliseconds(self.create_date)
@@ -770,13 +777,15 @@ def create_policy_version(self, policy_arn, policy_document, set_as_default):
         policy = self.get_policy(policy_arn)
         if not policy:
             raise IAMNotFoundException("Policy not found")
-
+        if len(policy.versions) >= 5:
+            raise IAMLimitExceededException("A managed policy can have up to 5 versions. Before you create a new version, you must delete an existing version.")
+        set_as_default = (set_as_default == "true")  # convert it to python bool
         version = PolicyVersion(policy_arn, policy_document, set_as_default)
         policy.versions.append(version)
         version.version_id = 'v{0}'.format(policy.next_version_num)
         policy.next_version_num += 1
         if set_as_default:
-            policy.default_version_id = version.version_id
+            policy.update_default_version(version.version_id)
         return version
 
     def get_policy_version(self, policy_arn, version_id):
@@ -799,8 +808,8 @@ def delete_policy_version(self, policy_arn, version_id):
         if not policy:
             raise IAMNotFoundException("Policy not found")
         if version_id == policy.default_version_id:
-            raise IAMConflictException(
-                "Cannot delete the default version of a policy")
+            raise IAMConflictException(code="DeleteConflict",
+                                       message="Cannot delete the default version of a policy.")
         for i, v in enumerate(policy.versions):
             if v.version_id == version_id:
                 del policy.versions[i]
diff --git a/moto/iam/responses.py b/moto/iam/responses.py
--- a/moto/iam/responses.py
+++ b/moto/iam/responses.py
@@ -1144,7 +1144,7 @@ def untag_role(self):
     <PolicyVersion>
       <Document>{{ policy_version.document }}</Document>
       <VersionId>{{ policy_version.version_id }}</VersionId>
-      <IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
+      <IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
       <CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
     </PolicyVersion>
   </CreatePolicyVersionResult>
@@ -1158,7 +1158,7 @@ def untag_role(self):
     <PolicyVersion>
       <Document>{{ policy_version.document }}</Document>
       <VersionId>{{ policy_version.version_id }}</VersionId>
-      <IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
+      <IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
       <CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
     </PolicyVersion>
   </GetPolicyVersionResult>
@@ -1175,7 +1175,7 @@ def untag_role(self):
       <member>
         <Document>{{ policy_version.document }}</Document>
         <VersionId>{{ policy_version.version_id }}</VersionId>
-        <IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
+        <IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
         <CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
       </member>
       {% endfor %}
@@ -1786,7 +1786,7 @@ def untag_role(self):
         {% for policy_version in policy.versions %}
           <member>
             <Document>{{ policy_version.document }}</Document>
-            <IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
+            <IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
             <VersionId>{{ policy_version.version_id }}</VersionId>
             <CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
           </member>


Test patch:
diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py
--- a/tests/test_iam/test_iam.py
+++ b/tests/test_iam/test_iam.py
@@ -345,6 +345,7 @@ def test_create_policy_versions():
         SetAsDefault=True)
     version.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
     version.get('PolicyVersion').get('VersionId').should.equal("v2")
+    version.get('PolicyVersion').get('IsDefaultVersion').should.be.ok
     conn.delete_policy_version(
         PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
         VersionId="v1")
@@ -352,6 +353,47 @@ def test_create_policy_versions():
         PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
         PolicyDocument=MOCK_POLICY)
     version.get('PolicyVersion').get('VersionId').should.equal("v3")
+    version.get('PolicyVersion').get('IsDefaultVersion').shouldnt.be.ok
+
+
+@mock_iam
+def test_create_many_policy_versions():
+    conn = boto3.client('iam', region_name='us-east-1')
+    conn.create_policy(
+        PolicyName="TestCreateManyPolicyVersions",
+        PolicyDocument=MOCK_POLICY)
+    for _ in range(0, 4):
+        conn.create_policy_version(
+            PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
+            PolicyDocument=MOCK_POLICY)
+    with assert_raises(ClientError):
+        conn.create_policy_version(
+            PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
+            PolicyDocument=MOCK_POLICY)
+
+
+@mock_iam
+def test_set_default_policy_version():
+    conn = boto3.client('iam', region_name='us-east-1')
+    conn.create_policy(
+        PolicyName="TestSetDefaultPolicyVersion",
+        PolicyDocument=MOCK_POLICY)
+    conn.create_policy_version(
+        PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
+        PolicyDocument=MOCK_POLICY_2,
+        SetAsDefault=True)
+    conn.create_policy_version(
+        PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
+        PolicyDocument=MOCK_POLICY_3,
+        SetAsDefault=True)
+    versions = conn.list_policy_versions(
+        PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion")
+    versions.get('Versions')[0].get('Document').should.equal(json.loads(MOCK_POLICY))
+    versions.get('Versions')[0].get('IsDefaultVersion').shouldnt.be.ok
+    versions.get('Versions')[1].get('Document').should.equal(json.loads(MOCK_POLICY_2))
+    versions.get('Versions')[1].get('IsDefaultVersion').shouldnt.be.ok
+    versions.get('Versions')[2].get('Document').should.equal(json.loads(MOCK_POLICY_3))
+    versions.get('Versions')[2].get('IsDefaultVersion').should.be.ok
 
 
 @mock_iam
@@ -393,6 +435,7 @@ def test_get_policy_version():
         PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
         VersionId=version.get('PolicyVersion').get('VersionId'))
     retrieved.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
+    retrieved.get('PolicyVersion').get('IsDefaultVersion').shouldnt.be.ok
 
 
 @mock_iam
@@ -439,6 +482,7 @@ def test_list_policy_versions():
     versions = conn.list_policy_versions(
         PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
     versions.get('Versions')[0].get('VersionId').should.equal('v1')
+    versions.get('Versions')[0].get('IsDefaultVersion').should.be.ok
 
     conn.create_policy_version(
         PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
@@ -448,9 +492,10 @@ def test_list_policy_versions():
         PolicyDocument=MOCK_POLICY_3)
     versions = conn.list_policy_versions(
         PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
-    print(versions.get('Versions'))
     versions.get('Versions')[1].get('Document').should.equal(json.loads(MOCK_POLICY_2))
+    versions.get('Versions')[1].get('IsDefaultVersion').shouldnt.be.ok
     versions.get('Versions')[2].get('Document').should.equal(json.loads(MOCK_POLICY_3))
+    versions.get('Versions')[2].get('IsDefaultVersion').shouldnt.be.ok
 
 
 @mock_iam
@@ -474,6 +519,21 @@ def test_delete_policy_version():
     len(versions.get('Versions')).should.equal(1)
 
 
+@mock_iam
+def test_delete_default_policy_version():
+    conn = boto3.client('iam', region_name='us-east-1')
+    conn.create_policy(
+        PolicyName="TestDeletePolicyVersion",
+        PolicyDocument=MOCK_POLICY)
+    conn.create_policy_version(
+        PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
+        PolicyDocument=MOCK_POLICY_2)
+    with assert_raises(ClientError):
+        conn.delete_policy_version(
+            PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
+            VersionId='v1')
+
+
 @mock_iam_deprecated()
 def test_create_user():
     conn = boto.connect_iam()