prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  E3503 does not match CloudFormation - requires ValidationDomain when CF does not want it
  *cfn-lint version: (`cfn-lint --version`)*
  
  cfn-lint 0.33.2
  
  *Description of issue.*
  
  I created an ACM certificate resource, and there were problems configuring the `DomainValidationOptions` block. If using DNS validation, the only properties needed are `DomainName` and `HostedZoneId`. However, cfn-lint was demanding a third property named `ValidationDomain`. When submitting the stack for deployment to CF, it triggered an immediate rollback because CF views `HostedZoneId` and `ValidationDomain` as mutually exclusive.
  
  Adding an ignore rule to skip the E3503 error allowed me to proceed without issues. This rule should be adjusted to match what CF enforces.
  
  **Sample:**
  
  ```yaml
  Resources:
    Certificate:
      Type: AWS::CertificateManager::Certificate
      Metadata:
        cfn-lint:
          config:
            ignore_checks:
              - E3503
      Properties:
        DomainName: "*.aws.domain.com"
        ValidationMethod: DNS
        DomainValidationOptions:
          - DomainName: aws.domain.com
            HostedZoneId: !ImportValue SubdomainHostedZoneId
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py`
  Content:
  ```
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import six
  6 from cfnlint.rules import CloudFormationLintRule
  7 from cfnlint.rules import RuleMatch
  8 
  9 
  10 class DomainValidationOptions(CloudFormationLintRule):
  11     """Check if a certificate's domain validation options are set up correctly"""
  12     id = 'E3503'
  13     shortdesc = 'ValidationDomain is superdomain of DomainName'
  14     description = 'In ValidationDomainOptions, the ValidationDomain must be a superdomain of the DomainName being validated'
  15     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-certificatemanager-certificate-domainvalidationoption.html#cfn-certificatemanager-certificate-domainvalidationoption-validationdomain'
  16     tags = ['certificate', 'certificatemanager', 'domainvalidationoptions', 'validationdomain']
  17 
  18     def __init__(self):
  19         """ Init """
  20         super(DomainValidationOptions, self).__init__()
  21         self.resource_property_types = ['AWS::CertificateManager::Certificate']
  22 
  23     def check_value(self, value, path, **kwargs):
  24         """ Check value inside the list of DomainValidationOptions"""
  25         matches = []
  26         cfn = kwargs.get('cfn')
  27         if isinstance(value, dict):
  28             property_sets = cfn.get_object_without_conditions(value)
  29             for property_set in property_sets:
  30                 properties = property_set.get('Object')
  31                 scenario = property_set.get('Scenario')
  32                 domain_name = properties.get('DomainName', '')
  33                 validation_domain = properties.get('ValidationDomain', '')
  34                 if isinstance(domain_name, six.string_types) and isinstance(validation_domain, six.string_types):
  35                     if domain_name == validation_domain:
  36                         continue
  37 
  38                     if not domain_name.endswith('.' + validation_domain):
  39                         message = 'ValidationDomain must be a superdomain of DomainName at {}'
  40                         if scenario is None:
  41                             matches.append(
  42                                 RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)))))
  43                         else:
  44                             scenario_text = ' and '.join(
  45                                 ['when condition "%s" is %s' % (k, v) for (k, v) in scenario.items()])
  46                             matches.append(
  47                                 RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)) + ' ' + scenario_text)))
  48         return matches
  49 
  50     def match_resource_properties(self, properties, _, path, cfn):
  51         matches = []
  52         matches.extend(cfn.check_value(
  53             properties, 'DomainValidationOptions', path[:],
  54             check_value=self.check_value,
  55             cfn=cfn,
  56         ))
  57 
  58         return matches
  59
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py b/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py
  --- a/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py
  +++ b/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py
  @@ -29,8 +29,8 @@
               for property_set in property_sets:
                   properties = property_set.get('Object')
                   scenario = property_set.get('Scenario')
  -                domain_name = properties.get('DomainName', '')
  -                validation_domain = properties.get('ValidationDomain', '')
  +                domain_name = properties.get('DomainName', None)
  +                validation_domain = properties.get('ValidationDomain', None)
                   if isinstance(domain_name, six.string_types) and isinstance(validation_domain, six.string_types):
                       if domain_name == validation_domain:
                           continue
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py b/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py\n--- a/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py\n+++ b/src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py\n@@ -29,8 +29,8 @@\n             for property_set in property_sets:\n                 properties = property_set.get('Object')\n                 scenario = property_set.get('Scenario')\n-                domain_name = properties.get('DomainName', '')\n-                validation_domain = properties.get('ValidationDomain', '')\n+                domain_name = properties.get('DomainName', None)\n+                validation_domain = properties.get('ValidationDomain', None)\n                 if isinstance(domain_name, six.string_types) and isinstance(validation_domain, six.string_types):\n                     if domain_name == validation_domain:\n                         continue\n", "issue": "E3503 does not match CloudFormation - requires ValidationDomain when CF does not want it\n*cfn-lint version: (`cfn-lint --version`)*\r\n\r\ncfn-lint 0.33.2\r\n\r\n*Description of issue.*\r\n\r\nI created an ACM certificate resource, and there were problems configuring the `DomainValidationOptions` block. If using DNS validation, the only properties needed are `DomainName` and `HostedZoneId`. However, cfn-lint was demanding a third property named `ValidationDomain`. When submitting the stack for deployment to CF, it triggered an immediate rollback because CF views `HostedZoneId` and `ValidationDomain` as mutually exclusive.\r\n\r\nAdding an ignore rule to skip the E3503 error allowed me to proceed without issues. This rule should be adjusted to match what CF enforces.\r\n\r\n**Sample:**\r\n\r\n```yaml\r\nResources:\r\n  Certificate:\r\n    Type: AWS::CertificateManager::Certificate\r\n    Metadata:\r\n      cfn-lint:\r\n        config:\r\n          ignore_checks:\r\n            - E3503\r\n    Properties:\r\n      DomainName: \"*.aws.domain.com\"\r\n      ValidationMethod: DNS\r\n      DomainValidationOptions:\r\n        - DomainName: aws.domain.com\r\n          HostedZoneId: !ImportValue SubdomainHostedZoneId\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 six\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\n\nclass DomainValidationOptions(CloudFormationLintRule):\n    \"\"\"Check if a certificate's domain validation options are set up correctly\"\"\"\n    id = 'E3503'\n    shortdesc = 'ValidationDomain is superdomain of DomainName'\n    description = 'In ValidationDomainOptions, the ValidationDomain must be a superdomain of the DomainName being validated'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-certificatemanager-certificate-domainvalidationoption.html#cfn-certificatemanager-certificate-domainvalidationoption-validationdomain'\n    tags = ['certificate', 'certificatemanager', 'domainvalidationoptions', 'validationdomain']\n\n    def __init__(self):\n        \"\"\" Init \"\"\"\n        super(DomainValidationOptions, self).__init__()\n        self.resource_property_types = ['AWS::CertificateManager::Certificate']\n\n    def check_value(self, value, path, **kwargs):\n        \"\"\" Check value inside the list of DomainValidationOptions\"\"\"\n        matches = []\n        cfn = kwargs.get('cfn')\n        if isinstance(value, dict):\n            property_sets = cfn.get_object_without_conditions(value)\n            for property_set in property_sets:\n                properties = property_set.get('Object')\n                scenario = property_set.get('Scenario')\n                domain_name = properties.get('DomainName', '')\n                validation_domain = properties.get('ValidationDomain', '')\n                if isinstance(domain_name, six.string_types) and isinstance(validation_domain, six.string_types):\n                    if domain_name == validation_domain:\n                        continue\n\n                    if not domain_name.endswith('.' + validation_domain):\n                        message = 'ValidationDomain must be a superdomain of DomainName at {}'\n                        if scenario is None:\n                            matches.append(\n                                RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)))))\n                        else:\n                            scenario_text = ' and '.join(\n                                ['when condition \"%s\" is %s' % (k, v) for (k, v) in scenario.items()])\n                            matches.append(\n                                RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)) + ' ' + scenario_text)))\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        matches = []\n        matches.extend(cfn.check_value(\n            properties, 'DomainValidationOptions', path[:],\n            check_value=self.check_value,\n            cfn=cfn,\n        ))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport six\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\n\nclass DomainValidationOptions(CloudFormationLintRule):\n    \"\"\"Check if a certificate's domain validation options are set up correctly\"\"\"\n    id = 'E3503'\n    shortdesc = 'ValidationDomain is superdomain of DomainName'\n    description = 'In ValidationDomainOptions, the ValidationDomain must be a superdomain of the DomainName being validated'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-certificatemanager-certificate-domainvalidationoption.html#cfn-certificatemanager-certificate-domainvalidationoption-validationdomain'\n    tags = ['certificate', 'certificatemanager', 'domainvalidationoptions', 'validationdomain']\n\n    def __init__(self):\n        \"\"\" Init \"\"\"\n        super(DomainValidationOptions, self).__init__()\n        self.resource_property_types = ['AWS::CertificateManager::Certificate']\n\n    def check_value(self, value, path, **kwargs):\n        \"\"\" Check value inside the list of DomainValidationOptions\"\"\"\n        matches = []\n        cfn = kwargs.get('cfn')\n        if isinstance(value, dict):\n            property_sets = cfn.get_object_without_conditions(value)\n            for property_set in property_sets:\n                properties = property_set.get('Object')\n                scenario = property_set.get('Scenario')\n                domain_name = properties.get('DomainName', None)\n                validation_domain = properties.get('ValidationDomain', None)\n                if isinstance(domain_name, six.string_types) and isinstance(validation_domain, six.string_types):\n                    if domain_name == validation_domain:\n                        continue\n\n                    if not domain_name.endswith('.' + validation_domain):\n                        message = 'ValidationDomain must be a superdomain of DomainName at {}'\n                        if scenario is None:\n                            matches.append(\n                                RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)))))\n                        else:\n                            scenario_text = ' and '.join(\n                                ['when condition \"%s\" is %s' % (k, v) for (k, v) in scenario.items()])\n                            matches.append(\n                                RuleMatch(path[:] + ['DomainName'], message.format('/'.join(map(str, path)) + ' ' + scenario_text)))\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        matches = []\n        matches.extend(cfn.check_value(\n            properties, 'DomainValidationOptions', path[:],\n            check_value=self.check_value,\n            cfn=cfn,\n        ))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/certificatemanager/DomainValidationOptions.py"}]}