Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

Force annotations to end strictly with alphanumeric characters #353

Merged
merged 1 commit into from Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions kopf/storage/progress.py
Expand Up @@ -232,13 +232,14 @@ def make_key(self, key: Union[str, handlers.HandlerId], max_length: int = 63) ->

# K8s has a limitation of 63 chars per annotation/label key.
# Force it to 63 chars by replacing the tail with a consistent hash (with full alphabet).
# Force it to end with alnums instead of altchars or trailing chars (K8s requirement).
prefix = f'{self.prefix}/' if self.prefix else ''
if len(safe_key) <= max_length - len(prefix):
suffix = ''
else:
digest = hashlib.blake2b(safe_key.encode('utf-8'), digest_size=4).digest()
alnums = base64.b64encode(digest, altchars=b'-.').replace(b'=', b'-').decode('ascii')
suffix = f'-{alnums}'
alnums = base64.b64encode(digest, altchars=b'-.').decode('ascii')
suffix = f'-{alnums}'.rstrip('=-.')

full_key = f'{prefix}{safe_key[:max_length - len(prefix) - len(suffix)]}{suffix}'
return full_key
Expand Down
16 changes: 8 additions & 8 deletions tests/persistence/test_annotations_hashing.py
Expand Up @@ -32,19 +32,19 @@
# The suffix itself (if appended) takes 9, so it is 30 left. The same math for no prefix.
['my-operator.example.com', 'x', 'my-operator.example.com/x'],
['my-operator.example.com', 'x' * 39, 'my-operator.example.com/' + 'x' * 39],
['my-operator.example.com', 'x' * 40, 'my-operator.example.com/' + 'x' * 30 + '-tEokcg--'],
['my-operator.example.com', 'y' * 40, 'my-operator.example.com/' + 'y' * 30 + '-VZlvhw--'],
['my-operator.example.com', 'z' * 40, 'my-operator.example.com/' + 'z' * 30 + '-LlPQyA--'],
['my-operator.example.com', 'x' * 40, 'my-operator.example.com/' + 'x' * 30 + 'xx-tEokcg'],
['my-operator.example.com', 'y' * 40, 'my-operator.example.com/' + 'y' * 30 + 'yy-VZlvhw'],
['my-operator.example.com', 'z' * 40, 'my-operator.example.com/' + 'z' * 30 + 'zz-LlPQyA'],
[None, 'x', 'x'],
[None, 'x' * 63, 'x' * 63],
[None, 'x' * 64, 'x' * 54 + '-SItAqA--'],
[None, 'y' * 64, 'y' * 54 + '-0d251g--'],
[None, 'z' * 64, 'z' * 54 + '-E7wvIA--'],
[None, 'x' * 64, 'x' * 54 + 'xx-SItAqA'], # base64: SItAqA==
[None, 'y' * 64, 'y' * 54 + 'yy-0d251g'], # base64: 0d251g==
[None, 'z' * 64, 'z' * 54 + 'zz-E7wvIA'], # base64: E7wvIA==

# For special chars in base64 encoding ("+" and "/"), which are not compatible with K8s.
# The numbers are found empirically so that both "/" and "+" are found in the base64'ed digest.
['my-operator.example.com', 'fn' * 323, 'my-operator.example.com/' + 'fn' * 15 + '-Az-r.g--'],
[None, 'fn' * 323, 'fn' * 27 + '-Az-r.g--'],
['my-operator.example.com', 'fn' * 323, 'my-operator.example.com/' + 'fn' * 15 + 'fn-Az-r.g'],
[None, 'fn' * 323, 'fn' * 27 + 'fn-Az-r.g'], # base64: Az-r.g==

])

Expand Down