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()

```

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':

{"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"}]}