We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support serverless v2 DBInstanceClass
*cfn-lint version: 0.59.0*

*Allowed list of DBInstanceClass does not include "db.serverless"*

Please provide as much information as possible:
* Template linting issues:
  * Please provide a CloudFormation sample that generated the issue.
```
  DbInstance0:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: aurora-postgresql
      DBClusterIdentifier: !Ref MyAuroraCluster
      DBInstanceClass: db.serverless
```
* Feature request:
  * List of allowed db instance class to include `db.serverless`.  Documentation: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Types


Cfn-lint uses the [CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) as the base to do validation. These files are included as part of the application version. Please update to the latest version of `cfn-lint` or update the spec files manually (`cfn-lint -u`)
- Yes this fixes it for me locally, but I need a release with the change because I'm running it via [GitHub actions](https://github.com/ScottBrenner/cfn-lint-action).

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scripts/update_specs_from_pricing.py`
Content:
```
1 #!/usr/bin/env python
2 """
3 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 SPDX-License-Identifier: MIT-0
5 """
6 
7 """
8     Updates our dynamic patches from the pricing API
9     This script requires Boto3 and Credentials to call the Pricing API
10 """
11 
12 
13 import boto3
14 import json
15 import logging
16 LOGGER = logging.getLogger('cfnlint')
17 
18 
19 region_map = {
20     'Any': 'all',
21     'AWS GovCloud (US-East)': 'us-gov-east-1',
22     'AWS GovCloud (US-West)': 'us-gov-west-1',
23     'Africa (Cape Town)': 'af-south-1',
24     'Asia Pacific (Hong Kong)': 'ap-east-1',
25     'Asia Pacific (Jakarta)': 'ap-southeast-3',
26     'Asia Pacific (Mumbai)': 'ap-south-1',
27     'Asia Pacific (Osaka)': 'ap-northeast-3',
28     'Asia Pacific (Seoul)': 'ap-northeast-2',
29     'Asia Pacific (Singapore)': 'ap-southeast-1',
30     'Asia Pacific (Sydney)': 'ap-southeast-2',
31     'Asia Pacific (Tokyo)': 'ap-northeast-1',
32     'Canada (Central)': 'ca-central-1',
33     'China (Beijing)': 'cn-north-1',
34     'China (Ningxia)': 'cn-northwest-1',
35     'EU (Frankfurt)': 'eu-central-1',
36     'EU (Ireland)': 'eu-west-1',
37     'EU (London)': 'eu-west-2',
38     'EU (Milan)': 'eu-south-1',
39     'EU (Paris)': 'eu-west-3',
40     'EU (Stockholm)': 'eu-north-1',
41     'Middle East (Bahrain)': 'me-south-1',
42     'Middle East (UAE)': 'me-central-1',
43     'South America (Sao Paulo)': 'sa-east-1',
44     'US East (N. Virginia)': 'us-east-1',
45     'US East (Ohio)': 'us-east-2',
46     'US West (N. California)': 'us-west-1',
47     'US West (Oregon)': 'us-west-2',
48     'US West (Los Angeles)': 'us-west-2',
49 }
50 
51 session = boto3.session.Session()
52 client = session.client('pricing', region_name='us-east-1')
53 
54 
55 def configure_logging():
56     """Setup Logging"""
57     ch = logging.StreamHandler()
58     ch.setLevel(logging.INFO)
59 
60     LOGGER.setLevel(logging.INFO)
61     log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
62     ch.setFormatter(log_formatter)
63 
64     # make sure all other log handlers are removed before adding it back
65     for handler in LOGGER.handlers:
66         LOGGER.removeHandler(handler)
67     LOGGER.addHandler(ch)
68 
69 
70 def update_outputs(key, values, outputs):
71     """ update outputs with appropriate results """
72     for region in values:
73         element = {
74             "op": "add",
75             "path": "/ValueTypes/%s/AllowedValues" % key,
76             "value": sorted(values[region])
77         }
78         outputs[region].append(element)
79 
80     return outputs
81 
82 
83 def get_paginator(service):
84     LOGGER.info('Get ' + service + ' pricing')
85     return client.get_paginator('get_products').paginate(
86         ServiceCode=service,
87         FormatVersion='aws_v1',
88     )
89 
90 
91 def get_dax_pricing():
92     results = {}
93     for page in get_paginator('AmazonDAX'):
94         for price_item in page.get('PriceList', []):
95             products = json.loads(price_item)
96             product = products.get('product', {})
97             if product:
98                 if product.get('productFamily') in ['DAX']:
99                     if not results.get(region_map[product.get('attributes').get('location')]):
100                         results[region_map[product.get('attributes').get('location')]] = set()
101                     results[region_map[product.get('attributes').get('location')]].add(
102                         product.get('attributes').get('usagetype').split(':')[1]
103                     )
104     return results
105 
106 
107 def get_mq_pricing():
108     remap = {
109         'mq.m5.2xl': 'mq.m5.2xlarge',
110         'mq.m5.4xl': 'mq.m5.4xlarge'
111     }
112     results = {}
113     for page in get_paginator('AmazonMQ'):
114         for price_item in page.get('PriceList', []):
115             products = json.loads(price_item)
116             product = products.get('product', {})
117             if product:
118                 if product.get('productFamily') in ['Broker Instances']:
119                     if not results.get(region_map[product.get('attributes').get('location')]):
120                         results[region_map[product.get('attributes').get('location')]] = set()
121                     usage_type = product.get('attributes').get('usagetype').split(':')[1]
122                     results[region_map[product.get('attributes').get('location')]].add(
123                         remap.get(usage_type, usage_type)
124                     )
125     return results
126 
127 
128 def get_rds_pricing():
129     product_map = {
130         '2': ['mysql'],
131         '3': ['oracle-se1'],
132         '4': ['oracle-se'],
133         '5': ['oracle-ee'],
134         '6': ['oracle-se1'],
135         '8': ['sqlserver-se'],
136         '9': ['sqlserver-ee'],
137         '10': ['sqlserver-ex'],
138         '11': ['sqlserver-web'],
139         '12': ['sqlserver-se'],
140         '14': ['postgres'],
141         '15': ['sqlserver-ee'],
142         '16': ['aurora-mysql', 'aurora'],
143         '18': ['mariadb'],
144         '19': ['oracle-se2'],
145         '20': ['oracle-se2'],
146         '21': ['aurora-postgresql'],
147     }
148 
149     license_map = {
150         'License included': 'license-included',
151         'Bring your own license': 'bring-your-own-license',
152         'No license required': 'general-public-license'
153     }
154 
155     rds_specs = {}
156 
157     results = {}
158     for page in get_paginator('AmazonRDS'):
159         for price_item in page.get('PriceList', []):
160             products = json.loads(price_item)
161             product = products.get('product', {})
162             if product:
163                 if product.get('productFamily') in ['Database Instance']:
164                     # Get overall instance types
165                     if not results.get(region_map[product.get('attributes').get('location')]):
166                         results[region_map[product.get('attributes').get('location')]] = set()
167                     results[region_map[product.get('attributes').get('location')]].add(
168                         product.get('attributes').get('instanceType')
169                     )
170                     # Rds Instance Size spec
171                     product_names = product_map.get(product.get('attributes').get('engineCode'), [])
172                     product_region = region_map.get(product.get('attributes').get('location'))
173                     license_name = license_map.get(product.get('attributes').get('licenseModel'))
174                     instance_type = product.get('attributes').get('instanceType')
175                     for product_name in product_names:
176                         if not rds_specs.get(license_name):
177                             rds_specs[license_name] = {}
178                         if not rds_specs.get(license_name).get(product_name):
179                             rds_specs[license_name][product_name] = {}
180                         if not rds_specs.get(license_name).get(product_name).get(product_region):
181                             rds_specs[license_name][product_name][product_region] = set()
182 
183                         rds_specs[license_name][product_name][product_region].add(instance_type)
184 
185     for license_name, license_values in rds_specs.items():
186         for product_name, product_values in license_values.items():
187             for product_region, instance_types in product_values.items():
188                 rds_specs[license_name][product_name][product_region] = list(sorted(instance_types))
189 
190     LOGGER.info('Updating RDS Spec files')
191     filename = 'src/cfnlint/data/AdditionalSpecs/RdsProperties.json'
192     with open(filename, 'w+', encoding='utf-8') as f:
193         json.dump(rds_specs, f, indent=1, sort_keys=True, separators=(',', ': '))
194     return results
195 
196 
197 def get_results(service, product_families):
198     results = {}
199     for page in get_paginator(service):
200         for price_item in page.get('PriceList', []):
201             products = json.loads(price_item)
202             product = products.get('product', {})
203             if product:
204                 if product.get('productFamily') in product_families and product.get('attributes').get('locationType') == "AWS Region":
205                     if product.get('attributes').get('location') not in region_map:
206                         LOGGER.warning('Region "%s" not found', product.get('attributes').get('location'))
207                         continue
208                     if not results.get(region_map[product.get('attributes').get('location')]):
209                         results[region_map[product.get('attributes').get('location')]] = set()
210                     results[region_map[product.get('attributes').get('location')]].add(
211                         product.get('attributes').get('instanceType')
212                     )
213     return results
214 
215 
216 def main():
217     """ main function """
218     configure_logging()
219 
220     outputs = {}
221     for region in region_map.values():
222         outputs[region] = []
223 
224     outputs = update_outputs('Ec2InstanceType', get_results('AmazonEC2', ['Compute Instance', 'Compute Instance (bare metal)']), outputs)
225     outputs = update_outputs('AWS::AmazonMQ::Broker.HostInstanceType', get_mq_pricing(), outputs)
226     outputs = update_outputs('AWS::RDS::DBInstance.DBInstanceClass', get_rds_pricing(), outputs)
227     outputs = update_outputs('RedshiftInstanceType', get_results('AmazonRedshift', ['Compute Instance']), outputs)
228     outputs = update_outputs('DAXInstanceType', get_dax_pricing(), outputs)
229     outputs = update_outputs('DocumentDBInstanceClass', get_results('AmazonDocDB', ['Database Instance']), outputs)
230     outputs = update_outputs('NeptuneInstanceClass', get_results('AmazonNeptune', ['Database Instance']), outputs)
231     outputs = update_outputs('ElastiCacheInstanceType', get_results('AmazonElastiCache', ['Cache Instance']), outputs)
232     outputs = update_outputs('ElasticsearchInstanceType', get_results('AmazonES', ['Elastic Search Instance']), outputs)
233     outputs = update_outputs('EMRInstanceType', get_results('ElasticMapReduce', ['Elastic Map Reduce Instance']), outputs)
234     outputs = update_outputs('BlockchainInstanceType', get_results('AmazonManagedBlockchain', ['Blockchain Instance']), outputs)
235     outputs = update_outputs('AWS::GameLift::Fleet.EC2InstanceType', get_results('AmazonGameLift', ['GameLift EC2 Instance']), outputs)
236     outputs = update_outputs('AppStreamInstanceType', get_results('AmazonAppStream', ['Streaming Instance']), outputs)
237 
238     LOGGER.info('Updating spec files')
239     for region, patches in outputs.items():
240         filename = 'src/cfnlint/data/ExtendedSpecs/%s/05_pricing_property_values.json' % region
241         with open(filename, 'w+', encoding='utf-8') as f:
242             json.dump(patches, f, indent=1, sort_keys=True, separators=(',', ': '))
243 
244 
245 if __name__ == '__main__':
246     try:
247         main()
248     except (ValueError, TypeError):
249         LOGGER.error(ValueError)
250
```
--- 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()

```

diff --git a/scripts/update_specs_from_pricing.py b/scripts/update_specs_from_pricing.py
--- a/scripts/update_specs_from_pricing.py
+++ b/scripts/update_specs_from_pricing.py
@@ -178,7 +178,7 @@
                         if not rds_specs.get(license_name).get(product_name):
                             rds_specs[license_name][product_name] = {}
                         if not rds_specs.get(license_name).get(product_name).get(product_region):
-                            rds_specs[license_name][product_name][product_region] = set()
+                            rds_specs[license_name][product_name][product_region] = set(['db.serverless'])
 
                         rds_specs[license_name][product_name][product_region].add(instance_type)

{"golden_diff": "diff --git a/scripts/update_specs_from_pricing.py b/scripts/update_specs_from_pricing.py\n--- a/scripts/update_specs_from_pricing.py\n+++ b/scripts/update_specs_from_pricing.py\n@@ -178,7 +178,7 @@\n                         if not rds_specs.get(license_name).get(product_name):\n                             rds_specs[license_name][product_name] = {}\n                         if not rds_specs.get(license_name).get(product_name).get(product_region):\n-                            rds_specs[license_name][product_name][product_region] = set()\n+                            rds_specs[license_name][product_name][product_region] = set(['db.serverless'])\n \n                         rds_specs[license_name][product_name][product_region].add(instance_type)\n", "issue": "Support serverless v2 DBInstanceClass\n*cfn-lint version: 0.59.0*\r\n\r\n*Allowed list of DBInstanceClass does not include \"db.serverless\"*\r\n\r\nPlease provide as much information as possible:\r\n* Template linting issues:\r\n  * Please provide a CloudFormation sample that generated the issue.\r\n```\r\n  DbInstance0:\r\n    Type: AWS::RDS::DBInstance\r\n    Properties:\r\n      Engine: aurora-postgresql\r\n      DBClusterIdentifier: !Ref MyAuroraCluster\r\n      DBInstanceClass: db.serverless\r\n```\r\n* Feature request:\r\n  * List of allowed db instance class to include `db.serverless`.  Documentation: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Types\r\n\r\n\r\nCfn-lint uses the [CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) as the base to do validation. These files are included as part of the application version. Please update to the latest version of `cfn-lint` or update the spec files manually (`cfn-lint -u`)\r\n- Yes this fixes it for me locally, but I need a release with the change because I'm running it via [GitHub actions](https://github.com/ScottBrenner/cfn-lint-action).\n", "before_files": [{"content": "#!/usr/bin/env python\n\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\n\n\"\"\"\n    Updates our dynamic patches from the pricing API\n    This script requires Boto3 and Credentials to call the Pricing API\n\"\"\"\n\n\nimport boto3\nimport json\nimport logging\nLOGGER = logging.getLogger('cfnlint')\n\n\nregion_map = {\n    'Any': 'all',\n    'AWS GovCloud (US-East)': 'us-gov-east-1',\n    'AWS GovCloud (US-West)': 'us-gov-west-1',\n    'Africa (Cape Town)': 'af-south-1',\n    'Asia Pacific (Hong Kong)': 'ap-east-1',\n    'Asia Pacific (Jakarta)': 'ap-southeast-3',\n    'Asia Pacific (Mumbai)': 'ap-south-1',\n    'Asia Pacific (Osaka)': 'ap-northeast-3',\n    'Asia Pacific (Seoul)': 'ap-northeast-2',\n    'Asia Pacific (Singapore)': 'ap-southeast-1',\n    'Asia Pacific (Sydney)': 'ap-southeast-2',\n    'Asia Pacific (Tokyo)': 'ap-northeast-1',\n    'Canada (Central)': 'ca-central-1',\n    'China (Beijing)': 'cn-north-1',\n    'China (Ningxia)': 'cn-northwest-1',\n    'EU (Frankfurt)': 'eu-central-1',\n    'EU (Ireland)': 'eu-west-1',\n    'EU (London)': 'eu-west-2',\n    'EU (Milan)': 'eu-south-1',\n    'EU (Paris)': 'eu-west-3',\n    'EU (Stockholm)': 'eu-north-1',\n    'Middle East (Bahrain)': 'me-south-1',\n    'Middle East (UAE)': 'me-central-1',\n    'South America (Sao Paulo)': 'sa-east-1',\n    'US East (N. Virginia)': 'us-east-1',\n    'US East (Ohio)': 'us-east-2',\n    'US West (N. California)': 'us-west-1',\n    'US West (Oregon)': 'us-west-2',\n    'US West (Los Angeles)': 'us-west-2',\n}\n\nsession = boto3.session.Session()\nclient = session.client('pricing', region_name='us-east-1')\n\n\ndef configure_logging():\n    \"\"\"Setup Logging\"\"\"\n    ch = logging.StreamHandler()\n    ch.setLevel(logging.INFO)\n\n    LOGGER.setLevel(logging.INFO)\n    log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n    ch.setFormatter(log_formatter)\n\n    # make sure all other log handlers are removed before adding it back\n    for handler in LOGGER.handlers:\n        LOGGER.removeHandler(handler)\n    LOGGER.addHandler(ch)\n\n\ndef update_outputs(key, values, outputs):\n    \"\"\" update outputs with appropriate results \"\"\"\n    for region in values:\n        element = {\n            \"op\": \"add\",\n            \"path\": \"/ValueTypes/%s/AllowedValues\" % key,\n            \"value\": sorted(values[region])\n        }\n        outputs[region].append(element)\n\n    return outputs\n\n\ndef get_paginator(service):\n    LOGGER.info('Get ' + service + ' pricing')\n    return client.get_paginator('get_products').paginate(\n        ServiceCode=service,\n        FormatVersion='aws_v1',\n    )\n\n\ndef get_dax_pricing():\n    results = {}\n    for page in get_paginator('AmazonDAX'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['DAX']:\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('usagetype').split(':')[1]\n                    )\n    return results\n\n\ndef get_mq_pricing():\n    remap = {\n        'mq.m5.2xl': 'mq.m5.2xlarge',\n        'mq.m5.4xl': 'mq.m5.4xlarge'\n    }\n    results = {}\n    for page in get_paginator('AmazonMQ'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['Broker Instances']:\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    usage_type = product.get('attributes').get('usagetype').split(':')[1]\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        remap.get(usage_type, usage_type)\n                    )\n    return results\n\n\ndef get_rds_pricing():\n    product_map = {\n        '2': ['mysql'],\n        '3': ['oracle-se1'],\n        '4': ['oracle-se'],\n        '5': ['oracle-ee'],\n        '6': ['oracle-se1'],\n        '8': ['sqlserver-se'],\n        '9': ['sqlserver-ee'],\n        '10': ['sqlserver-ex'],\n        '11': ['sqlserver-web'],\n        '12': ['sqlserver-se'],\n        '14': ['postgres'],\n        '15': ['sqlserver-ee'],\n        '16': ['aurora-mysql', 'aurora'],\n        '18': ['mariadb'],\n        '19': ['oracle-se2'],\n        '20': ['oracle-se2'],\n        '21': ['aurora-postgresql'],\n    }\n\n    license_map = {\n        'License included': 'license-included',\n        'Bring your own license': 'bring-your-own-license',\n        'No license required': 'general-public-license'\n    }\n\n    rds_specs = {}\n\n    results = {}\n    for page in get_paginator('AmazonRDS'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['Database Instance']:\n                    # Get overall instance types\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('instanceType')\n                    )\n                    # Rds Instance Size spec\n                    product_names = product_map.get(product.get('attributes').get('engineCode'), [])\n                    product_region = region_map.get(product.get('attributes').get('location'))\n                    license_name = license_map.get(product.get('attributes').get('licenseModel'))\n                    instance_type = product.get('attributes').get('instanceType')\n                    for product_name in product_names:\n                        if not rds_specs.get(license_name):\n                            rds_specs[license_name] = {}\n                        if not rds_specs.get(license_name).get(product_name):\n                            rds_specs[license_name][product_name] = {}\n                        if not rds_specs.get(license_name).get(product_name).get(product_region):\n                            rds_specs[license_name][product_name][product_region] = set()\n\n                        rds_specs[license_name][product_name][product_region].add(instance_type)\n\n    for license_name, license_values in rds_specs.items():\n        for product_name, product_values in license_values.items():\n            for product_region, instance_types in product_values.items():\n                rds_specs[license_name][product_name][product_region] = list(sorted(instance_types))\n\n    LOGGER.info('Updating RDS Spec files')\n    filename = 'src/cfnlint/data/AdditionalSpecs/RdsProperties.json'\n    with open(filename, 'w+', encoding='utf-8') as f:\n        json.dump(rds_specs, f, indent=1, sort_keys=True, separators=(',', ': '))\n    return results\n\n\ndef get_results(service, product_families):\n    results = {}\n    for page in get_paginator(service):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in product_families and product.get('attributes').get('locationType') == \"AWS Region\":\n                    if product.get('attributes').get('location') not in region_map:\n                        LOGGER.warning('Region \"%s\" not found', product.get('attributes').get('location'))\n                        continue\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('instanceType')\n                    )\n    return results\n\n\ndef main():\n    \"\"\" main function \"\"\"\n    configure_logging()\n\n    outputs = {}\n    for region in region_map.values():\n        outputs[region] = []\n\n    outputs = update_outputs('Ec2InstanceType', get_results('AmazonEC2', ['Compute Instance', 'Compute Instance (bare metal)']), outputs)\n    outputs = update_outputs('AWS::AmazonMQ::Broker.HostInstanceType', get_mq_pricing(), outputs)\n    outputs = update_outputs('AWS::RDS::DBInstance.DBInstanceClass', get_rds_pricing(), outputs)\n    outputs = update_outputs('RedshiftInstanceType', get_results('AmazonRedshift', ['Compute Instance']), outputs)\n    outputs = update_outputs('DAXInstanceType', get_dax_pricing(), outputs)\n    outputs = update_outputs('DocumentDBInstanceClass', get_results('AmazonDocDB', ['Database Instance']), outputs)\n    outputs = update_outputs('NeptuneInstanceClass', get_results('AmazonNeptune', ['Database Instance']), outputs)\n    outputs = update_outputs('ElastiCacheInstanceType', get_results('AmazonElastiCache', ['Cache Instance']), outputs)\n    outputs = update_outputs('ElasticsearchInstanceType', get_results('AmazonES', ['Elastic Search Instance']), outputs)\n    outputs = update_outputs('EMRInstanceType', get_results('ElasticMapReduce', ['Elastic Map Reduce Instance']), outputs)\n    outputs = update_outputs('BlockchainInstanceType', get_results('AmazonManagedBlockchain', ['Blockchain Instance']), outputs)\n    outputs = update_outputs('AWS::GameLift::Fleet.EC2InstanceType', get_results('AmazonGameLift', ['GameLift EC2 Instance']), outputs)\n    outputs = update_outputs('AppStreamInstanceType', get_results('AmazonAppStream', ['Streaming Instance']), outputs)\n\n    LOGGER.info('Updating spec files')\n    for region, patches in outputs.items():\n        filename = 'src/cfnlint/data/ExtendedSpecs/%s/05_pricing_property_values.json' % region\n        with open(filename, 'w+', encoding='utf-8') as f:\n            json.dump(patches, f, indent=1, sort_keys=True, separators=(',', ': '))\n\n\nif __name__ == '__main__':\n    try:\n        main()\n    except (ValueError, TypeError):\n        LOGGER.error(ValueError)\n", "path": "scripts/update_specs_from_pricing.py"}], "after_files": [{"content": "#!/usr/bin/env python\n\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\n\n\"\"\"\n    Updates our dynamic patches from the pricing API\n    This script requires Boto3 and Credentials to call the Pricing API\n\"\"\"\n\n\nimport boto3\nimport json\nimport logging\nLOGGER = logging.getLogger('cfnlint')\n\n\nregion_map = {\n    'Any': 'all',\n    'AWS GovCloud (US-East)': 'us-gov-east-1',\n    'AWS GovCloud (US-West)': 'us-gov-west-1',\n    'Africa (Cape Town)': 'af-south-1',\n    'Asia Pacific (Hong Kong)': 'ap-east-1',\n    'Asia Pacific (Jakarta)': 'ap-southeast-3',\n    'Asia Pacific (Mumbai)': 'ap-south-1',\n    'Asia Pacific (Osaka)': 'ap-northeast-3',\n    'Asia Pacific (Seoul)': 'ap-northeast-2',\n    'Asia Pacific (Singapore)': 'ap-southeast-1',\n    'Asia Pacific (Sydney)': 'ap-southeast-2',\n    'Asia Pacific (Tokyo)': 'ap-northeast-1',\n    'Canada (Central)': 'ca-central-1',\n    'China (Beijing)': 'cn-north-1',\n    'China (Ningxia)': 'cn-northwest-1',\n    'EU (Frankfurt)': 'eu-central-1',\n    'EU (Ireland)': 'eu-west-1',\n    'EU (London)': 'eu-west-2',\n    'EU (Milan)': 'eu-south-1',\n    'EU (Paris)': 'eu-west-3',\n    'EU (Stockholm)': 'eu-north-1',\n    'Middle East (Bahrain)': 'me-south-1',\n    'Middle East (UAE)': 'me-central-1',\n    'South America (Sao Paulo)': 'sa-east-1',\n    'US East (N. Virginia)': 'us-east-1',\n    'US East (Ohio)': 'us-east-2',\n    'US West (N. California)': 'us-west-1',\n    'US West (Oregon)': 'us-west-2',\n    'US West (Los Angeles)': 'us-west-2',\n}\n\nsession = boto3.session.Session()\nclient = session.client('pricing', region_name='us-east-1')\n\n\ndef configure_logging():\n    \"\"\"Setup Logging\"\"\"\n    ch = logging.StreamHandler()\n    ch.setLevel(logging.INFO)\n\n    LOGGER.setLevel(logging.INFO)\n    log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n    ch.setFormatter(log_formatter)\n\n    # make sure all other log handlers are removed before adding it back\n    for handler in LOGGER.handlers:\n        LOGGER.removeHandler(handler)\n    LOGGER.addHandler(ch)\n\n\ndef update_outputs(key, values, outputs):\n    \"\"\" update outputs with appropriate results \"\"\"\n    for region in values:\n        element = {\n            \"op\": \"add\",\n            \"path\": \"/ValueTypes/%s/AllowedValues\" % key,\n            \"value\": sorted(values[region])\n        }\n        outputs[region].append(element)\n\n    return outputs\n\n\ndef get_paginator(service):\n    LOGGER.info('Get ' + service + ' pricing')\n    return client.get_paginator('get_products').paginate(\n        ServiceCode=service,\n        FormatVersion='aws_v1',\n    )\n\n\ndef get_dax_pricing():\n    results = {}\n    for page in get_paginator('AmazonDAX'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['DAX']:\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('usagetype').split(':')[1]\n                    )\n    return results\n\n\ndef get_mq_pricing():\n    remap = {\n        'mq.m5.2xl': 'mq.m5.2xlarge',\n        'mq.m5.4xl': 'mq.m5.4xlarge'\n    }\n    results = {}\n    for page in get_paginator('AmazonMQ'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['Broker Instances']:\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    usage_type = product.get('attributes').get('usagetype').split(':')[1]\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        remap.get(usage_type, usage_type)\n                    )\n    return results\n\n\ndef get_rds_pricing():\n    product_map = {\n        '2': ['mysql'],\n        '3': ['oracle-se1'],\n        '4': ['oracle-se'],\n        '5': ['oracle-ee'],\n        '6': ['oracle-se1'],\n        '8': ['sqlserver-se'],\n        '9': ['sqlserver-ee'],\n        '10': ['sqlserver-ex'],\n        '11': ['sqlserver-web'],\n        '12': ['sqlserver-se'],\n        '14': ['postgres'],\n        '15': ['sqlserver-ee'],\n        '16': ['aurora-mysql', 'aurora'],\n        '18': ['mariadb'],\n        '19': ['oracle-se2'],\n        '20': ['oracle-se2'],\n        '21': ['aurora-postgresql'],\n    }\n\n    license_map = {\n        'License included': 'license-included',\n        'Bring your own license': 'bring-your-own-license',\n        'No license required': 'general-public-license'\n    }\n\n    rds_specs = {}\n\n    results = {}\n    for page in get_paginator('AmazonRDS'):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in ['Database Instance']:\n                    # Get overall instance types\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('instanceType')\n                    )\n                    # Rds Instance Size spec\n                    product_names = product_map.get(product.get('attributes').get('engineCode'), [])\n                    product_region = region_map.get(product.get('attributes').get('location'))\n                    license_name = license_map.get(product.get('attributes').get('licenseModel'))\n                    instance_type = product.get('attributes').get('instanceType')\n                    for product_name in product_names:\n                        if not rds_specs.get(license_name):\n                            rds_specs[license_name] = {}\n                        if not rds_specs.get(license_name).get(product_name):\n                            rds_specs[license_name][product_name] = {}\n                        if not rds_specs.get(license_name).get(product_name).get(product_region):\n                            rds_specs[license_name][product_name][product_region] = set(['db.serverless'])\n\n                        rds_specs[license_name][product_name][product_region].add(instance_type)\n\n    for license_name, license_values in rds_specs.items():\n        for product_name, product_values in license_values.items():\n            for product_region, instance_types in product_values.items():\n                rds_specs[license_name][product_name][product_region] = list(sorted(instance_types))\n\n    LOGGER.info('Updating RDS Spec files')\n    filename = 'src/cfnlint/data/AdditionalSpecs/RdsProperties.json'\n    with open(filename, 'w+', encoding='utf-8') as f:\n        json.dump(rds_specs, f, indent=1, sort_keys=True, separators=(',', ': '))\n    return results\n\n\ndef get_results(service, product_families):\n    results = {}\n    for page in get_paginator(service):\n        for price_item in page.get('PriceList', []):\n            products = json.loads(price_item)\n            product = products.get('product', {})\n            if product:\n                if product.get('productFamily') in product_families and product.get('attributes').get('locationType') == \"AWS Region\":\n                    if product.get('attributes').get('location') not in region_map:\n                        LOGGER.warning('Region \"%s\" not found', product.get('attributes').get('location'))\n                        continue\n                    if not results.get(region_map[product.get('attributes').get('location')]):\n                        results[region_map[product.get('attributes').get('location')]] = set()\n                    results[region_map[product.get('attributes').get('location')]].add(\n                        product.get('attributes').get('instanceType')\n                    )\n    return results\n\n\ndef main():\n    \"\"\" main function \"\"\"\n    configure_logging()\n\n    outputs = {}\n    for region in region_map.values():\n        outputs[region] = []\n\n    outputs = update_outputs('Ec2InstanceType', get_results('AmazonEC2', ['Compute Instance', 'Compute Instance (bare metal)']), outputs)\n    outputs = update_outputs('AWS::AmazonMQ::Broker.HostInstanceType', get_mq_pricing(), outputs)\n    outputs = update_outputs('AWS::RDS::DBInstance.DBInstanceClass', get_rds_pricing(), outputs)\n    outputs = update_outputs('RedshiftInstanceType', get_results('AmazonRedshift', ['Compute Instance']), outputs)\n    outputs = update_outputs('DAXInstanceType', get_dax_pricing(), outputs)\n    outputs = update_outputs('DocumentDBInstanceClass', get_results('AmazonDocDB', ['Database Instance']), outputs)\n    outputs = update_outputs('NeptuneInstanceClass', get_results('AmazonNeptune', ['Database Instance']), outputs)\n    outputs = update_outputs('ElastiCacheInstanceType', get_results('AmazonElastiCache', ['Cache Instance']), outputs)\n    outputs = update_outputs('ElasticsearchInstanceType', get_results('AmazonES', ['Elastic Search Instance']), outputs)\n    outputs = update_outputs('EMRInstanceType', get_results('ElasticMapReduce', ['Elastic Map Reduce Instance']), outputs)\n    outputs = update_outputs('BlockchainInstanceType', get_results('AmazonManagedBlockchain', ['Blockchain Instance']), outputs)\n    outputs = update_outputs('AWS::GameLift::Fleet.EC2InstanceType', get_results('AmazonGameLift', ['GameLift EC2 Instance']), outputs)\n    outputs = update_outputs('AppStreamInstanceType', get_results('AmazonAppStream', ['Streaming Instance']), outputs)\n\n    LOGGER.info('Updating spec files')\n    for region, patches in outputs.items():\n        filename = 'src/cfnlint/data/ExtendedSpecs/%s/05_pricing_property_values.json' % region\n        with open(filename, 'w+', encoding='utf-8') as f:\n            json.dump(patches, f, indent=1, sort_keys=True, separators=(',', ': '))\n\n\nif __name__ == '__main__':\n    try:\n        main()\n    except (ValueError, TypeError):\n        LOGGER.error(ValueError)\n", "path": "scripts/update_specs_from_pricing.py"}]}