kapicorp / kapitan

Generic templated configuration management for Kubernetes, Terraform and other things
https://kapitan.dev
Apache License 2.0
1.81k stars 199 forks source link

[bug]: reclass should support empty string keynames #1171

Open gburiola opened 5 months ago

gburiola commented 5 months ago

Description of the bug

If you use an empty string '' as a keyname inside the inventory, reclass fails. Example:

$ cat inventory/targets/my_target.yml 
classes: []
parameters:
  target_name: my_target
  '': INFO

That is valid YAML and also used by some application configs. Example: https://docs.ververica.com/vvp/user-guide/application-operations/session-clusters/logging#loggers

Steps to reproduce

### kapitan / reclass error

$ kapitan inventory

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Traceback (most recent call last):
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/storage/memcache_proxy.py", line 41, in get_node
    return self._nodes_cache[name]
KeyError: 'my_target'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/venv/lib/python3.8/site-packages/kapitan/resources.py", line 290, in generate_inventory
    inv = inventory_reclass(args.inventory_path)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/resources.py", line 361, in inventory_reclass
    cached.inv = _reclass.inventory()
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/core.py", line 261, in inventory
    inventory = self._get_inventory(True, '', None)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/core.py", line 187, in _get_inventory
    node_base = self._storage.get_node(nodename, self._settings)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/storage/memcache_proxy.py", line 43, in get_node
    ret = self._real_storage.get_node(name, settings)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/storage/yaml_fs/__init__.py", line 103, in get_node
    entity = YamlData.from_file(path).get_entity(name, pathname, settings)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/storage/yamldata.py", line 98, in get_entity
    parameters = datatypes.Parameters(parameters, settings, self._uri)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/datatypes/parameters.py", line 67, in __init__
    self.merge(mapping)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/datatypes/parameters.py", line 241, in merge
    self._base = self._merge_recurse(self._base, wrapped)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/datatypes/parameters.py", line 210, in _merge_recurse
    return self._merge_dict(cur, new)
  File "/opt/venv/lib/python3.8/site-packages/kapitan/reclass/reclass/datatypes/parameters.py", line 174, in _merge_dict
    if key[0] in self._settings.dict_key_prefixes:
IndexError: string index out of range


### What happened?

error above

### Additional context

_No response_

### Version (kapitan)

v0.31.0 (stable)

### Version (kapitan)

I use kapitan directly (pip, docker)

### Python virtual environment

- [ ] pyenv
- [ ] venv
- [ ] no environment

### OS information

_No response_

### Relevant log output

_No response_