prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  E2504 incorrectly rejects "Iops" property for io2/gp3 volumes
  *cfn-lint version: (`cfn-lint --version`)*
  
  cfn-lint 0.44.6
  
  *Description of issue.*
  
  cfn-lint produces an error "E2504: Iops shouldn't be defined for type io2 for Resource ... LaunchConfiguration/Properties/BlockDeviceMappings/0/Ebs/Iops" when setting Iops on a io2 EBS volume.
  
  The Iops property is required for io2 and optional for gp3. [1]
  
  Cfn-lint treats the Iops property as required for io1 and forbidden for all other volume types, which is very much not correct 
  
  [1] https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-iops
  
  
  
  </issue>
  <code>
  [start of src/cfnlint/rules/resources/ectwo/Ebs.py]
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import re
  6 import six
  7 from cfnlint.rules import CloudFormationLintRule
  8 from cfnlint.rules import RuleMatch
  9 
  10 
  11 class Ebs(CloudFormationLintRule):
  12     """Check if Ec2 Ebs Resource Properties"""
  13     id = 'E2504'
  14     shortdesc = 'Check Ec2 Ebs Properties'
  15     description = 'See if Ec2 Eb2 Properties are valid'
  16     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html'
  17     tags = ['properties', 'ec2', 'ebs']
  18 
  19     def _checkEbs(self, cfn, ebs, path):
  20         matches = []
  21 
  22         if isinstance(ebs, dict):
  23             volume_types_obj = cfn.get_values(ebs, 'VolumeType')
  24             iops_obj = cfn.get_values(ebs, 'Iops')
  25             if volume_types_obj is not None:
  26                 for volume_type_obj in volume_types_obj:
  27                     volume_type = volume_type_obj.get('Value')
  28                     if isinstance(volume_type, six.string_types):
  29                         if volume_type == 'io1':
  30                             if iops_obj is None:
  31                                 pathmessage = path[:] + ['VolumeType']
  32                                 message = 'VolumeType io1 requires Iops to be specified for {0}'
  33                                 matches.append(
  34                                     RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))
  35                         elif volume_type:
  36                             if iops_obj is not None:
  37                                 pathmessage = path[:] + ['Iops']
  38                                 message = 'Iops shouldn\'t be defined for type {0} for {1}'
  39                                 matches.append(
  40                                     RuleMatch(
  41                                         pathmessage,
  42                                         message.format(volume_type, '/'.join(map(str, pathmessage)))))
  43 
  44         return matches
  45 
  46     def match(self, cfn):
  47         """Check Ec2 Ebs Resource Parameters"""
  48 
  49         matches = []
  50 
  51         results = cfn.get_resource_properties(['AWS::EC2::Instance', 'BlockDeviceMappings'])
  52         results.extend(cfn.get_resource_properties(
  53             ['AWS::AutoScaling::LaunchConfiguration', 'BlockDeviceMappings']))
  54         for result in results:
  55             path = result['Path']
  56             if isinstance(result['Value'], list):
  57                 for index, properties in enumerate(result['Value']):
  58                     virtual_name = properties.get('VirtualName')
  59                     ebs = properties.get('Ebs')
  60                     if virtual_name:
  61                         # switch to regex
  62                         if not re.match(r'^ephemeral([0-9]|[1][0-9]|[2][0-3])$', virtual_name):
  63                             pathmessage = path[:] + [index, 'VirtualName']
  64                             message = 'Property VirtualName should be of type ephemeral(n) for {0}'
  65                             matches.append(
  66                                 RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))
  67                     elif ebs:
  68                         matches.extend(self._checkEbs(cfn, ebs, path[:] + [index, 'Ebs']))
  69         return matches
  70
  [end of src/cfnlint/rules/resources/ectwo/Ebs.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/cfnlint/rules/resources/ectwo/Ebs.py b/src/cfnlint/rules/resources/ectwo/Ebs.py
  --- a/src/cfnlint/rules/resources/ectwo/Ebs.py
  +++ b/src/cfnlint/rules/resources/ectwo/Ebs.py
  @@ -9,10 +9,10 @@
   
   
   class Ebs(CloudFormationLintRule):
  -    """Check if Ec2 Ebs Resource Properties"""
  +    """Check Ec2 Ebs Resource Properties"""
       id = 'E2504'
       shortdesc = 'Check Ec2 Ebs Properties'
  -    description = 'See if Ec2 Eb2 Properties are valid'
  +    description = 'See if Ec2 Ebs Properties are valid'
       source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html'
       tags = ['properties', 'ec2', 'ebs']
   
  @@ -26,13 +26,15 @@
                   for volume_type_obj in volume_types_obj:
                       volume_type = volume_type_obj.get('Value')
                       if isinstance(volume_type, six.string_types):
  -                        if volume_type == 'io1':
  +                        if volume_type in ('io1', 'io2'):
                               if iops_obj is None:
                                   pathmessage = path[:] + ['VolumeType']
  -                                message = 'VolumeType io1 requires Iops to be specified for {0}'
  +                                message = 'VolumeType {0} requires Iops to be specified for {1}'
                                   matches.append(
  -                                    RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))
  -                        elif volume_type:
  +                                    RuleMatch(
  +                                        pathmessage,
  +                                        message.format(volume_type, '/'.join(map(str, pathmessage)))))
  +                        elif volume_type in ('gp2', 'st1', 'sc1', 'standard'):
                               if iops_obj is not None:
                                   pathmessage = path[:] + ['Iops']
                                   message = 'Iops shouldn\'t be defined for type {0} for {1}'
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/resources/ectwo/Ebs.py b/src/cfnlint/rules/resources/ectwo/Ebs.py\n--- a/src/cfnlint/rules/resources/ectwo/Ebs.py\n+++ b/src/cfnlint/rules/resources/ectwo/Ebs.py\n@@ -9,10 +9,10 @@\n \n \n class Ebs(CloudFormationLintRule):\n-    \"\"\"Check if Ec2 Ebs Resource Properties\"\"\"\n+    \"\"\"Check Ec2 Ebs Resource Properties\"\"\"\n     id = 'E2504'\n     shortdesc = 'Check Ec2 Ebs Properties'\n-    description = 'See if Ec2 Eb2 Properties are valid'\n+    description = 'See if Ec2 Ebs Properties are valid'\n     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html'\n     tags = ['properties', 'ec2', 'ebs']\n \n@@ -26,13 +26,15 @@\n                 for volume_type_obj in volume_types_obj:\n                     volume_type = volume_type_obj.get('Value')\n                     if isinstance(volume_type, six.string_types):\n-                        if volume_type == 'io1':\n+                        if volume_type in ('io1', 'io2'):\n                             if iops_obj is None:\n                                 pathmessage = path[:] + ['VolumeType']\n-                                message = 'VolumeType io1 requires Iops to be specified for {0}'\n+                                message = 'VolumeType {0} requires Iops to be specified for {1}'\n                                 matches.append(\n-                                    RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))\n-                        elif volume_type:\n+                                    RuleMatch(\n+                                        pathmessage,\n+                                        message.format(volume_type, '/'.join(map(str, pathmessage)))))\n+                        elif volume_type in ('gp2', 'st1', 'sc1', 'standard'):\n                             if iops_obj is not None:\n                                 pathmessage = path[:] + ['Iops']\n                                 message = 'Iops shouldn\\'t be defined for type {0} for {1}'\n", "issue": "E2504 incorrectly rejects \"Iops\" property for io2/gp3 volumes\n*cfn-lint version: (`cfn-lint --version`)*\r\n\r\ncfn-lint 0.44.6\r\n\r\n*Description of issue.*\r\n\r\ncfn-lint produces an error \"E2504: Iops shouldn't be defined for type io2 for Resource ... LaunchConfiguration/Properties/BlockDeviceMappings/0/Ebs/Iops\" when setting Iops on a io2 EBS volume.\r\n\r\nThe Iops property is required for io2 and optional for gp3. [1]\r\n\r\nCfn-lint treats the Iops property as required for io1 and forbidden for all other volume types, which is very much not correct \r\n\r\n[1] https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-iops\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport re\nimport six\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\n\nclass Ebs(CloudFormationLintRule):\n    \"\"\"Check if Ec2 Ebs Resource Properties\"\"\"\n    id = 'E2504'\n    shortdesc = 'Check Ec2 Ebs Properties'\n    description = 'See if Ec2 Eb2 Properties are valid'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html'\n    tags = ['properties', 'ec2', 'ebs']\n\n    def _checkEbs(self, cfn, ebs, path):\n        matches = []\n\n        if isinstance(ebs, dict):\n            volume_types_obj = cfn.get_values(ebs, 'VolumeType')\n            iops_obj = cfn.get_values(ebs, 'Iops')\n            if volume_types_obj is not None:\n                for volume_type_obj in volume_types_obj:\n                    volume_type = volume_type_obj.get('Value')\n                    if isinstance(volume_type, six.string_types):\n                        if volume_type == 'io1':\n                            if iops_obj is None:\n                                pathmessage = path[:] + ['VolumeType']\n                                message = 'VolumeType io1 requires Iops to be specified for {0}'\n                                matches.append(\n                                    RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))\n                        elif volume_type:\n                            if iops_obj is not None:\n                                pathmessage = path[:] + ['Iops']\n                                message = 'Iops shouldn\\'t be defined for type {0} for {1}'\n                                matches.append(\n                                    RuleMatch(\n                                        pathmessage,\n                                        message.format(volume_type, '/'.join(map(str, pathmessage)))))\n\n        return matches\n\n    def match(self, cfn):\n        \"\"\"Check Ec2 Ebs Resource Parameters\"\"\"\n\n        matches = []\n\n        results = cfn.get_resource_properties(['AWS::EC2::Instance', 'BlockDeviceMappings'])\n        results.extend(cfn.get_resource_properties(\n            ['AWS::AutoScaling::LaunchConfiguration', 'BlockDeviceMappings']))\n        for result in results:\n            path = result['Path']\n            if isinstance(result['Value'], list):\n                for index, properties in enumerate(result['Value']):\n                    virtual_name = properties.get('VirtualName')\n                    ebs = properties.get('Ebs')\n                    if virtual_name:\n                        # switch to regex\n                        if not re.match(r'^ephemeral([0-9]|[1][0-9]|[2][0-3])$', virtual_name):\n                            pathmessage = path[:] + [index, 'VirtualName']\n                            message = 'Property VirtualName should be of type ephemeral(n) for {0}'\n                            matches.append(\n                                RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))\n                    elif ebs:\n                        matches.extend(self._checkEbs(cfn, ebs, path[:] + [index, 'Ebs']))\n        return matches\n", "path": "src/cfnlint/rules/resources/ectwo/Ebs.py"}]}