kubernetes.core icon indicating copy to clipboard operation
kubernetes.core copied to clipboard

The name of 2 ConfigMaps with different `binaryData` field value is always the same whereas `append_hash` is set to `true`

Open mickael-ange opened this issue 1 year ago • 0 comments

SUMMARY

The name of 2 ConfigMaps with different binaryData field value is always the same whereas append_hash is set to true.

I'm expecting to have a different generated hash when the binaryData changes, like it does with the data field.

This behavior is preventing me to detect ConfigMap changes which also prevents me to trigger the rollout of the workload (Deployment, Statefulset, DeamonSet, etc.) using it. Indeed I set a label in my workload with the generated name of the configmap. Therefore if the configmap content changes, the configmap name changes, then the workload label changes and eventually my workload is rolled out and use the expected configmap.


Possible fix:

Assuming that this behavior is not expected then we could fix it as follows.

I have traced back the code and found out that the reason of this behavior is caused by the generate_hash function.

If I add the binaryData key in the marshall function then the expected behavior is restored.

def generate_hash(resource):
..
    if resource["kind"] == "ConfigMap":
        # marshalled = marshal(sorted_dict(resource), ["data", "kind", key])
        marshalled = marshal(sorted_dict(resource), ["data", "binaryData", "kind", key])
        del resource[key]
        return encode(marshalled)

If my assumption is correct, the same problem exists with Secret's stringData field.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

kubernetes.core.k8s plugins/module_utils/hashes.py

ANSIBLE VERSION
$ ansible --version
ansible [core 2.14.6]
  config file = /home/mickael/git/emq-devops/ansible/ansible.cfg
  configured module search path = ['/home/mickael/git/emq-devops/ansible/modules']
  ansible python module location = /home/mickael/git/emq-devops/ansible/.venv/lib/python3.10/site-packages/ansible
  ansible collection location = /home/mickael/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/mickael/git/emq-devops/ansible/.venv/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/home/mickael/git/emq-devops/ansible/.venv/bin/python3.10)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
$ ansible-galaxy collection list kubernetes.core

# /home/mickael/git/emq-devops/ansible/.venv/lib/python3.10/site-packages/ansible_collections
Collection      Version
--------------- -------
kubernetes.core 2.4.0  
OS / ENVIRONMENT

Ubuntu 22.04 LTS

STEPS TO REPRODUCE

For example, the 2 following ConfigMap definitions have the same generated ConfigMap name (e.g. test-tgz-mh2dhghg86) whereas they don't contain the same dataBinary.

- name: Configmap using binaryData with one file
  kubernetes.core.k8s:
    state: present
    apply: true
    append_hash: true
    definition:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: test-tgz
        namespace: default
      binaryData:
        test.tgz: SDRzSUFBQUFBQUFBQSszU1BRcURRQkRGOGFsemlqMkJ6R1kvUEk4RUMxRWJuWURIZHdNSjJBU3hFQkgrditZVjg0cFhqTFd6VmJhWQpuRWlMbk9NbmZaMTBtMTlaZkV3aGhycEVFdlhQcUVHY25qbnE1ejFiTXprblkvZnFtM2I0Mjl1NzM1U3o4Z0NQcTFjQUFBQUFBQUFBCkFBQUFBQUFBQUk1YUFiejFUS3dBS0FBQQo=
  register: configmap_using_binarydata_with_one_file

- name: Configmap using binaryData with two files
  kubernetes.core.k8s:
    state: present
    apply: true
    append_hash: true
    definition:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: test-tgz
        namespace: default
      binaryData:
        test.tgz: SDRzSUFBQUFBQUFBQSszU1BRcURRQkRGOGFsemlqMkJ6R1kvUEk4RUMxRWJuWURIZHdNSjJBU3hFQkgrditZVjg0cFhqTFd6VmJhWQpuRWlMbk9NbmZaMTBtMTlaZkV3aGhycEVFdlhQcUVHY25qbnE1ejFiTXprblkvZnFtM2I0Mjl1NzM1U3o4Z0NQcTFjQUFBQUFBQUFBCkFBQUFBQUFBQUk1YUFiejFUS3dBS0FBQQo=
        test2.tgz: SDRzSUFBQUFBQUFBQSszU1BRcURRQkRGOGFsemlqMkJ6R1kvUEk4RUMxRWJuWURIZHdNSjJBU3hFQkgrditZVjg0cFhqTFd6VmJhWQpuRWlMbk9NbmZaMTBtMTlaZkV3aGhycEVFdlhQcUVHY25qbnE1ejFiTXprblkvZnFtM2I0Mjl1NzM1U3o4Z0NQcTFjQUFBQUFBQUFBCkFBQUFBQUFBQUk1YUFiejFUS3dBS0FBQQo=
  register: configmap_using_binarydata_with_two_files

- name: Ensure generated resource names are different (this test fails)
  ansible.builtin.assert:
    that:
      - configmap_using_binarydata_with_one_file.result.metadata.name != configmap_using_binarydata_with_two_files.result.metadata.name

EXPECTED RESULTS

I'm expecting to have a different generated ConfigMap name when the binaryData changes, like it does with the data field.

ACTUAL RESULTS

2 ConfigMaps with different binaryData have the same generated name even if append_hash is set to true.

mickael-ange avatar Dec 07 '23 17:12 mickael-ange