prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Support the `value` parameter for `constant_keyword` fields
  The [`constant_keyword` data type](https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html#constant-keyword-field-type) accepts the `value` parameter. On a `constant_keyword` field if the `value` parameter is specified, that value is used for all documents in the index. Otherwise, it is set based on the first document that gets indexed.
  
  If a user wishes to use the ECS tooling to manage their ES index templates, they may also wish to control the value of `value` via their custom field definitions.
  
  Example definition:
  
  ```yaml
    - name: acme
      title: acme
      group: 2
      short: Fields describing acme-related needs.
      description: >
        Acme-related needs
      fields:
        - name: stream
          description: stream
          level: extended
          type: constant_keyword
          value: widgets
  ```
  
  --- 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/generators/es_template.py`
  Content:
  ```
  1 import json
  2 import sys
  3 import copy
  4 
  5 from os.path import join
  6 from generators import ecs_helpers
  7 
  8 
  9 def generate(ecs_flat, ecs_version, out_dir, template_settings_file, mapping_settings_file):
  10     field_mappings = {}
  11     for flat_name in sorted(ecs_flat):
  12         field = ecs_flat[flat_name]
  13         nestings = flat_name.split('.')
  14         dict_add_nested(field_mappings, nestings, entry_for(field))
  15 
  16     if mapping_settings_file:
  17         with open(mapping_settings_file) as f:
  18             mappings_section = json.load(f)
  19     else:
  20         mappings_section = default_mapping_settings(ecs_version)
  21 
  22     mappings_section['properties'] = field_mappings
  23 
  24     generate_template_version(6, mappings_section, out_dir, template_settings_file)
  25     generate_template_version(7, mappings_section, out_dir, template_settings_file)
  26 
  27 # Field mappings
  28 
  29 
  30 def dict_add_nested(dct, nestings, value):
  31     current_nesting = nestings[0]
  32     rest_nestings = nestings[1:]
  33     if len(rest_nestings) > 0:
  34         dct.setdefault(current_nesting, {})
  35         dct[current_nesting].setdefault('properties', {})
  36 
  37         dict_add_nested(
  38             dct[current_nesting]['properties'],
  39             rest_nestings,
  40             value)
  41 
  42     else:
  43         if current_nesting in dct and 'type' in value and 'object' == value['type']:
  44             return
  45         dct[current_nesting] = value
  46 
  47 
  48 def entry_for(field):
  49     field_entry = {'type': field['type']}
  50     try:
  51         if field['type'] == 'object' or field['type'] == 'nested':
  52             if 'enabled' in field and not field['enabled']:
  53                 ecs_helpers.dict_copy_existing_keys(field, field_entry, ['enabled'])
  54         # the index field is only valid for field types that are not object and nested
  55         elif 'index' in field and not field['index']:
  56             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['index', 'doc_values'])
  57 
  58         if field['type'] == 'keyword':
  59             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above'])
  60         elif field['type'] == 'text':
  61             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms'])
  62         elif field['type'] == 'alias':
  63             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['path'])
  64         elif field['type'] == 'scaled_float':
  65             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['scaling_factor'])
  66 
  67         if 'multi_fields' in field:
  68             field_entry['fields'] = {}
  69             for mf in field['multi_fields']:
  70                 mf_type = mf['type']
  71                 mf_entry = {'type': mf_type}
  72                 if mf_type == 'keyword':
  73                     ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['normalizer', 'ignore_above'])
  74                 elif mf_type == 'text':
  75                     ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['norms'])
  76                 field_entry['fields'][mf['name']] = mf_entry
  77 
  78     except KeyError as ex:
  79         print("Exception {} occurred for field {}".format(ex, field))
  80         raise ex
  81     return field_entry
  82 
  83 # Generated files
  84 
  85 
  86 def generate_template_version(elasticsearch_version, mappings_section, out_dir, template_settings_file):
  87     ecs_helpers.make_dirs(join(out_dir, 'elasticsearch', str(elasticsearch_version)))
  88     if template_settings_file:
  89         with open(template_settings_file) as f:
  90             template = json.load(f)
  91     else:
  92         template = default_template_settings()
  93     if elasticsearch_version == 6:
  94         template['mappings'] = {'_doc': mappings_section}
  95     else:
  96         template['mappings'] = mappings_section
  97 
  98     filename = join(out_dir, "elasticsearch/{}/template.json".format(elasticsearch_version))
  99     save_json(filename, template)
  100 
  101 
  102 def save_json(file, data):
  103     open_mode = "wb"
  104     if sys.version_info >= (3, 0):
  105         open_mode = "w"
  106     with open(file, open_mode) as jsonfile:
  107         jsonfile.write(json.dumps(data, indent=2, sort_keys=True))
  108 
  109 
  110 def default_template_settings():
  111     return {
  112         "index_patterns": ["try-ecs-*"],
  113         "order": 1,
  114         "settings": {
  115             "index": {
  116                 "mapping": {
  117                     "total_fields": {
  118                         "limit": 10000
  119                     }
  120                 },
  121                 "refresh_interval": "5s"
  122             }
  123         },
  124         "mappings": {}
  125     }
  126 
  127 
  128 def default_mapping_settings(ecs_version):
  129     return {
  130         "_meta": {"version": ecs_version},
  131         "date_detection": False,
  132         "dynamic_templates": [
  133             {
  134                 "strings_as_keyword": {
  135                     "mapping": {
  136                         "ignore_above": 1024,
  137                         "type": "keyword"
  138                     },
  139                     "match_mapping_type": "string"
  140                 }
  141             }
  142         ],
  143         "properties": {}
  144     }
  145
  ```
  --- 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/scripts/generators/es_template.py b/scripts/generators/es_template.py
  --- a/scripts/generators/es_template.py
  +++ b/scripts/generators/es_template.py
  @@ -57,6 +57,8 @@
   
           if field['type'] == 'keyword':
               ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above'])
  +        elif field['type'] == 'constant_keyword':
  +            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['value'])
           elif field['type'] == 'text':
               ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms'])
           elif field['type'] == 'alias':
  
verification_info: {"golden_diff": "diff --git a/scripts/generators/es_template.py b/scripts/generators/es_template.py\n--- a/scripts/generators/es_template.py\n+++ b/scripts/generators/es_template.py\n@@ -57,6 +57,8 @@\n \n         if field['type'] == 'keyword':\n             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above'])\n+        elif field['type'] == 'constant_keyword':\n+            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['value'])\n         elif field['type'] == 'text':\n             ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms'])\n         elif field['type'] == 'alias':\n", "issue": "Support the `value` parameter for `constant_keyword` fields\nThe [`constant_keyword` data type](https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html#constant-keyword-field-type) accepts the `value` parameter. On a `constant_keyword` field if the `value` parameter is specified, that value is used for all documents in the index. Otherwise, it is set based on the first document that gets indexed.\r\n\r\nIf a user wishes to use the ECS tooling to manage their ES index templates, they may also wish to control the value of `value` via their custom field definitions.\r\n\r\nExample definition:\r\n\r\n```yaml\r\n  - name: acme\r\n    title: acme\r\n    group: 2\r\n    short: Fields describing acme-related needs.\r\n    description: >\r\n      Acme-related needs\r\n    fields:\r\n      - name: stream\r\n        description: stream\r\n        level: extended\r\n        type: constant_keyword\r\n        value: widgets\r\n```\n", "before_files": [{"content": "import json\nimport sys\nimport copy\n\nfrom os.path import join\nfrom generators import ecs_helpers\n\n\ndef generate(ecs_flat, ecs_version, out_dir, template_settings_file, mapping_settings_file):\n    field_mappings = {}\n    for flat_name in sorted(ecs_flat):\n        field = ecs_flat[flat_name]\n        nestings = flat_name.split('.')\n        dict_add_nested(field_mappings, nestings, entry_for(field))\n\n    if mapping_settings_file:\n        with open(mapping_settings_file) as f:\n            mappings_section = json.load(f)\n    else:\n        mappings_section = default_mapping_settings(ecs_version)\n\n    mappings_section['properties'] = field_mappings\n\n    generate_template_version(6, mappings_section, out_dir, template_settings_file)\n    generate_template_version(7, mappings_section, out_dir, template_settings_file)\n\n# Field mappings\n\n\ndef dict_add_nested(dct, nestings, value):\n    current_nesting = nestings[0]\n    rest_nestings = nestings[1:]\n    if len(rest_nestings) > 0:\n        dct.setdefault(current_nesting, {})\n        dct[current_nesting].setdefault('properties', {})\n\n        dict_add_nested(\n            dct[current_nesting]['properties'],\n            rest_nestings,\n            value)\n\n    else:\n        if current_nesting in dct and 'type' in value and 'object' == value['type']:\n            return\n        dct[current_nesting] = value\n\n\ndef entry_for(field):\n    field_entry = {'type': field['type']}\n    try:\n        if field['type'] == 'object' or field['type'] == 'nested':\n            if 'enabled' in field and not field['enabled']:\n                ecs_helpers.dict_copy_existing_keys(field, field_entry, ['enabled'])\n        # the index field is only valid for field types that are not object and nested\n        elif 'index' in field and not field['index']:\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['index', 'doc_values'])\n\n        if field['type'] == 'keyword':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above'])\n        elif field['type'] == 'text':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms'])\n        elif field['type'] == 'alias':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['path'])\n        elif field['type'] == 'scaled_float':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['scaling_factor'])\n\n        if 'multi_fields' in field:\n            field_entry['fields'] = {}\n            for mf in field['multi_fields']:\n                mf_type = mf['type']\n                mf_entry = {'type': mf_type}\n                if mf_type == 'keyword':\n                    ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['normalizer', 'ignore_above'])\n                elif mf_type == 'text':\n                    ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['norms'])\n                field_entry['fields'][mf['name']] = mf_entry\n\n    except KeyError as ex:\n        print(\"Exception {} occurred for field {}\".format(ex, field))\n        raise ex\n    return field_entry\n\n# Generated files\n\n\ndef generate_template_version(elasticsearch_version, mappings_section, out_dir, template_settings_file):\n    ecs_helpers.make_dirs(join(out_dir, 'elasticsearch', str(elasticsearch_version)))\n    if template_settings_file:\n        with open(template_settings_file) as f:\n            template = json.load(f)\n    else:\n        template = default_template_settings()\n    if elasticsearch_version == 6:\n        template['mappings'] = {'_doc': mappings_section}\n    else:\n        template['mappings'] = mappings_section\n\n    filename = join(out_dir, \"elasticsearch/{}/template.json\".format(elasticsearch_version))\n    save_json(filename, template)\n\n\ndef save_json(file, data):\n    open_mode = \"wb\"\n    if sys.version_info >= (3, 0):\n        open_mode = \"w\"\n    with open(file, open_mode) as jsonfile:\n        jsonfile.write(json.dumps(data, indent=2, sort_keys=True))\n\n\ndef default_template_settings():\n    return {\n        \"index_patterns\": [\"try-ecs-*\"],\n        \"order\": 1,\n        \"settings\": {\n            \"index\": {\n                \"mapping\": {\n                    \"total_fields\": {\n                        \"limit\": 10000\n                    }\n                },\n                \"refresh_interval\": \"5s\"\n            }\n        },\n        \"mappings\": {}\n    }\n\n\ndef default_mapping_settings(ecs_version):\n    return {\n        \"_meta\": {\"version\": ecs_version},\n        \"date_detection\": False,\n        \"dynamic_templates\": [\n            {\n                \"strings_as_keyword\": {\n                    \"mapping\": {\n                        \"ignore_above\": 1024,\n                        \"type\": \"keyword\"\n                    },\n                    \"match_mapping_type\": \"string\"\n                }\n            }\n        ],\n        \"properties\": {}\n    }\n", "path": "scripts/generators/es_template.py"}], "after_files": [{"content": "import json\nimport sys\nimport copy\n\nfrom os.path import join\nfrom generators import ecs_helpers\n\n\ndef generate(ecs_flat, ecs_version, out_dir, template_settings_file, mapping_settings_file):\n    field_mappings = {}\n    for flat_name in sorted(ecs_flat):\n        field = ecs_flat[flat_name]\n        nestings = flat_name.split('.')\n        dict_add_nested(field_mappings, nestings, entry_for(field))\n\n    if mapping_settings_file:\n        with open(mapping_settings_file) as f:\n            mappings_section = json.load(f)\n    else:\n        mappings_section = default_mapping_settings(ecs_version)\n\n    mappings_section['properties'] = field_mappings\n\n    generate_template_version(6, mappings_section, out_dir, template_settings_file)\n    generate_template_version(7, mappings_section, out_dir, template_settings_file)\n\n# Field mappings\n\n\ndef dict_add_nested(dct, nestings, value):\n    current_nesting = nestings[0]\n    rest_nestings = nestings[1:]\n    if len(rest_nestings) > 0:\n        dct.setdefault(current_nesting, {})\n        dct[current_nesting].setdefault('properties', {})\n\n        dict_add_nested(\n            dct[current_nesting]['properties'],\n            rest_nestings,\n            value)\n\n    else:\n        if current_nesting in dct and 'type' in value and 'object' == value['type']:\n            return\n        dct[current_nesting] = value\n\n\ndef entry_for(field):\n    field_entry = {'type': field['type']}\n    try:\n        if field['type'] == 'object' or field['type'] == 'nested':\n            if 'enabled' in field and not field['enabled']:\n                ecs_helpers.dict_copy_existing_keys(field, field_entry, ['enabled'])\n        # the index field is only valid for field types that are not object and nested\n        elif 'index' in field and not field['index']:\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['index', 'doc_values'])\n\n        if field['type'] == 'keyword':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above'])\n        elif field['type'] == 'constant_keyword':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['value'])\n        elif field['type'] == 'text':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms'])\n        elif field['type'] == 'alias':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['path'])\n        elif field['type'] == 'scaled_float':\n            ecs_helpers.dict_copy_existing_keys(field, field_entry, ['scaling_factor'])\n\n        if 'multi_fields' in field:\n            field_entry['fields'] = {}\n            for mf in field['multi_fields']:\n                mf_type = mf['type']\n                mf_entry = {'type': mf_type}\n                if mf_type == 'keyword':\n                    ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['normalizer', 'ignore_above'])\n                elif mf_type == 'text':\n                    ecs_helpers.dict_copy_existing_keys(mf, mf_entry, ['norms'])\n                field_entry['fields'][mf['name']] = mf_entry\n\n    except KeyError as ex:\n        print(\"Exception {} occurred for field {}\".format(ex, field))\n        raise ex\n    return field_entry\n\n# Generated files\n\n\ndef generate_template_version(elasticsearch_version, mappings_section, out_dir, template_settings_file):\n    ecs_helpers.make_dirs(join(out_dir, 'elasticsearch', str(elasticsearch_version)))\n    if template_settings_file:\n        with open(template_settings_file) as f:\n            template = json.load(f)\n    else:\n        template = default_template_settings()\n    if elasticsearch_version == 6:\n        template['mappings'] = {'_doc': mappings_section}\n    else:\n        template['mappings'] = mappings_section\n\n    filename = join(out_dir, \"elasticsearch/{}/template.json\".format(elasticsearch_version))\n    save_json(filename, template)\n\n\ndef save_json(file, data):\n    open_mode = \"wb\"\n    if sys.version_info >= (3, 0):\n        open_mode = \"w\"\n    with open(file, open_mode) as jsonfile:\n        jsonfile.write(json.dumps(data, indent=2, sort_keys=True))\n\n\ndef default_template_settings():\n    return {\n        \"index_patterns\": [\"try-ecs-*\"],\n        \"order\": 1,\n        \"settings\": {\n            \"index\": {\n                \"mapping\": {\n                    \"total_fields\": {\n                        \"limit\": 10000\n                    }\n                },\n                \"refresh_interval\": \"5s\"\n            }\n        },\n        \"mappings\": {}\n    }\n\n\ndef default_mapping_settings(ecs_version):\n    return {\n        \"_meta\": {\"version\": ecs_version},\n        \"date_detection\": False,\n        \"dynamic_templates\": [\n            {\n                \"strings_as_keyword\": {\n                    \"mapping\": {\n                        \"ignore_above\": 1024,\n                        \"type\": \"keyword\"\n                    },\n                    \"match_mapping_type\": \"string\"\n                }\n            }\n        ],\n        \"properties\": {}\n    }\n", "path": "scripts/generators/es_template.py"}]}