prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Update metadata to include property keys
  Within the CloudFormation metadata object for auto scaling launch configurations, it'd be nice to be able to rely on the validators within the template to sanity check the allowed keys within the 'config' dictionary: 
  
  ```
  "Resources": {
    "MyInstance": {
      "Type": "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "config" : {
            "packages" : {
              :
            },
            "groups" : {
              :
            },
            "users" : {
              :
            },
            "sources" : {
              :
            },
            "files" : {
              :
            },
            "commands" : {
              :
            },
            "services" : {
              :
            }
          }
        }
      },
      "Properties": {
        :
      }
    }
  }
  ```
  
  Currently the implementation of troposphere.cloudformation.InitConfig only contains one key which is 'files'
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `troposphere/cloudformation.py`
  Content:
  ```
  1 # Copyright (c) 2013, Mark Peek <mark@peek.org>
  2 # All rights reserved.
  3 #
  4 # See LICENSE file for full license.
  5 
  6 from . import AWSHelperFn, AWSObject, AWSProperty, Ref
  7 from .validators import integer
  8 
  9 
  10 class Stack(AWSObject):
  11     type = "AWS::CloudFormation::Stack"
  12 
  13     props = {
  14         'TemplateURL': (basestring, True),
  15         'TimeoutInMinutes': (integer, False),
  16         'Parameters': (dict, False),
  17     }
  18 
  19 
  20 class WaitCondition(AWSObject):
  21     type = "AWS::CloudFormation::WaitCondition"
  22 
  23     props = {
  24         'Count': (integer, False),
  25         'Handle': (Ref, True),
  26         'Timeout': (integer, True),
  27     }
  28 
  29 
  30 class WaitConditionHandle(AWSObject):
  31     type = "AWS::CloudFormation::WaitConditionHandle"
  32 
  33     props = {}
  34 
  35 
  36 class InitFileContext(AWSHelperFn):
  37     def __init__(self, data):
  38         self.data = data
  39 
  40     def JSONrepr(self):
  41         return self.data
  42 
  43 
  44 class InitFile(AWSProperty):
  45     props = {
  46         'content': (basestring, True),
  47         'mode': (basestring, False),
  48         'owner': (basestring, False),
  49         'group': (basestring, False),
  50         'context': (InitFileContext, False)
  51     }
  52 
  53 
  54 class InitFiles(AWSHelperFn):
  55     def __init__(self, data):
  56         self.validate(data)
  57         self.data = data
  58 
  59     def validate(self, data):
  60         for k in data:
  61             if not isinstance(data[k], InitFile):
  62                 raise ValueError("File '" + k + "' must be of type InitFile")
  63 
  64     def JSONrepr(self):
  65         return self.data
  66 
  67 
  68 class InitConfig(AWSProperty):
  69     props = {
  70         'files': (dict, False)
  71     }
  72 
  73 
  74 class Init(AWSHelperFn):
  75     def __init__(self, data):
  76         self.validate(data)
  77         self.data = {"AWS::CloudFormation::Init": data}
  78 
  79     def validate(self, data):
  80         if 'config' not in data:
  81             raise ValueError('config property is required')
  82         if not isinstance(data['config'], InitConfig):
  83             raise ValueError(
  84                 'config property must be of type autoscaling.InitConfig'
  85             )
  86 
  87     def JSONrepr(self):
  88         return self.data
  89
  ```
  --- 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/troposphere/cloudformation.py b/troposphere/cloudformation.py
  --- a/troposphere/cloudformation.py
  +++ b/troposphere/cloudformation.py
  @@ -67,7 +67,13 @@
   
   class InitConfig(AWSProperty):
       props = {
  -        'files': (dict, False)
  +        'groups': (dict, False),
  +        'users': (dict, False),
  +        'sources': (dict, False),
  +        'packages': (dict, False),
  +        'files': (dict, False),
  +        'commands': (dict, False),
  +        'services': (dict, False)
       }
  
verification_info: {"golden_diff": "diff --git a/troposphere/cloudformation.py b/troposphere/cloudformation.py\n--- a/troposphere/cloudformation.py\n+++ b/troposphere/cloudformation.py\n@@ -67,7 +67,13 @@\n \n class InitConfig(AWSProperty):\n     props = {\n-        'files': (dict, False)\n+        'groups': (dict, False),\n+        'users': (dict, False),\n+        'sources': (dict, False),\n+        'packages': (dict, False),\n+        'files': (dict, False),\n+        'commands': (dict, False),\n+        'services': (dict, False)\n     }\n", "issue": "Update metadata to include property keys\nWithin the CloudFormation metadata object for auto scaling launch configurations, it'd be nice to be able to rely on the validators within the template to sanity check the allowed keys within the 'config' dictionary: \n\n```\n\"Resources\": {\n  \"MyInstance\": {\n    \"Type\": \"AWS::EC2::Instance\",\n    \"Metadata\" : {\n      \"AWS::CloudFormation::Init\" : {\n        \"config\" : {\n          \"packages\" : {\n            :\n          },\n          \"groups\" : {\n            :\n          },\n          \"users\" : {\n            :\n          },\n          \"sources\" : {\n            :\n          },\n          \"files\" : {\n            :\n          },\n          \"commands\" : {\n            :\n          },\n          \"services\" : {\n            :\n          }\n        }\n      }\n    },\n    \"Properties\": {\n      :\n    }\n  }\n}\n```\n\nCurrently the implementation of troposphere.cloudformation.InitConfig only contains one key which is 'files'\n\n", "before_files": [{"content": "# Copyright (c) 2013, Mark Peek <mark@peek.org>\n# All rights reserved.\n#\n# See LICENSE file for full license.\n\nfrom . import AWSHelperFn, AWSObject, AWSProperty, Ref\nfrom .validators import integer\n\n\nclass Stack(AWSObject):\n    type = \"AWS::CloudFormation::Stack\"\n\n    props = {\n        'TemplateURL': (basestring, True),\n        'TimeoutInMinutes': (integer, False),\n        'Parameters': (dict, False),\n    }\n\n\nclass WaitCondition(AWSObject):\n    type = \"AWS::CloudFormation::WaitCondition\"\n\n    props = {\n        'Count': (integer, False),\n        'Handle': (Ref, True),\n        'Timeout': (integer, True),\n    }\n\n\nclass WaitConditionHandle(AWSObject):\n    type = \"AWS::CloudFormation::WaitConditionHandle\"\n\n    props = {}\n\n\nclass InitFileContext(AWSHelperFn):\n    def __init__(self, data):\n        self.data = data\n\n    def JSONrepr(self):\n        return self.data\n\n\nclass InitFile(AWSProperty):\n    props = {\n        'content': (basestring, True),\n        'mode': (basestring, False),\n        'owner': (basestring, False),\n        'group': (basestring, False),\n        'context': (InitFileContext, False)\n    }\n\n\nclass InitFiles(AWSHelperFn):\n    def __init__(self, data):\n        self.validate(data)\n        self.data = data\n\n    def validate(self, data):\n        for k in data:\n            if not isinstance(data[k], InitFile):\n                raise ValueError(\"File '\" + k + \"' must be of type InitFile\")\n\n    def JSONrepr(self):\n        return self.data\n\n\nclass InitConfig(AWSProperty):\n    props = {\n        'files': (dict, False)\n    }\n\n\nclass Init(AWSHelperFn):\n    def __init__(self, data):\n        self.validate(data)\n        self.data = {\"AWS::CloudFormation::Init\": data}\n\n    def validate(self, data):\n        if 'config' not in data:\n            raise ValueError('config property is required')\n        if not isinstance(data['config'], InitConfig):\n            raise ValueError(\n                'config property must be of type autoscaling.InitConfig'\n            )\n\n    def JSONrepr(self):\n        return self.data\n", "path": "troposphere/cloudformation.py"}], "after_files": [{"content": "# Copyright (c) 2013, Mark Peek <mark@peek.org>\n# All rights reserved.\n#\n# See LICENSE file for full license.\n\nfrom . import AWSHelperFn, AWSObject, AWSProperty, Ref\nfrom .validators import integer\n\n\nclass Stack(AWSObject):\n    type = \"AWS::CloudFormation::Stack\"\n\n    props = {\n        'TemplateURL': (basestring, True),\n        'TimeoutInMinutes': (integer, False),\n        'Parameters': (dict, False),\n    }\n\n\nclass WaitCondition(AWSObject):\n    type = \"AWS::CloudFormation::WaitCondition\"\n\n    props = {\n        'Count': (integer, False),\n        'Handle': (Ref, True),\n        'Timeout': (integer, True),\n    }\n\n\nclass WaitConditionHandle(AWSObject):\n    type = \"AWS::CloudFormation::WaitConditionHandle\"\n\n    props = {}\n\n\nclass InitFileContext(AWSHelperFn):\n    def __init__(self, data):\n        self.data = data\n\n    def JSONrepr(self):\n        return self.data\n\n\nclass InitFile(AWSProperty):\n    props = {\n        'content': (basestring, True),\n        'mode': (basestring, False),\n        'owner': (basestring, False),\n        'group': (basestring, False),\n        'context': (InitFileContext, False)\n    }\n\n\nclass InitFiles(AWSHelperFn):\n    def __init__(self, data):\n        self.validate(data)\n        self.data = data\n\n    def validate(self, data):\n        for k in data:\n            if not isinstance(data[k], InitFile):\n                raise ValueError(\"File '\" + k + \"' must be of type InitFile\")\n\n    def JSONrepr(self):\n        return self.data\n\n\nclass InitConfig(AWSProperty):\n    props = {\n        'groups': (dict, False),\n        'users': (dict, False),\n        'sources': (dict, False),\n        'packages': (dict, False),\n        'files': (dict, False),\n        'commands': (dict, False),\n        'services': (dict, False)\n    }\n\n\nclass Init(AWSHelperFn):\n    def __init__(self, data):\n        self.validate(data)\n        self.data = {\"AWS::CloudFormation::Init\": data}\n\n    def validate(self, data):\n        if 'config' not in data:\n            raise ValueError('config property is required')\n        if not isinstance(data['config'], InitConfig):\n            raise ValueError(\n                'config property must be of type autoscaling.InitConfig'\n            )\n\n    def JSONrepr(self):\n        return self.data\n", "path": "troposphere/cloudformation.py"}]}