Skip to content

Commit

Permalink
feat: Implement kluctl.io/ignore-diff annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
codablock committed Dec 21, 2021
1 parent 42da7ca commit efe654f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
9 changes: 9 additions & 0 deletions docs/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ fields will be overwritten in case of field manager conflicts.

If more than one field needs to be specified, add `-xxx` to the annotation key, where `xxx` is an arbitrary number.

### kluctl.io/ignore-diff
If set to "true", the whole resource will be ignored while calculating diffs.

### kluctl.io/ignore-diff-field
Specifies a [JSON Path](https://goessner.net/articles/JsonPath/) for fields that should be ignored while calculating
diffs.

If more than one field needs to be specified, add `-xxx` to the annotation key, where `xxx` is an arbitrary number.

## Hooks related
See [hooks](./hooks.md) for more details.

Expand Down
4 changes: 2 additions & 2 deletions kluctl/deployment/deployment_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ def do_diff(self, k8s_cluster, applied_objects, ignore_tags, ignore_labels, igno
if ref not in applied_objects:
continue
diff_objects[ref] = applied_objects.get(ref)
normalized_diff_objects[ref] = normalize_object(k8s_cluster, diff_objects[ref], ignore_for_diffs)
normalized_diff_objects[ref] = normalize_object(k8s_cluster, diff_objects[ref], ignore_for_diffs, diff_objects[ref])
if ref in self.remote_objects:
normalized_remote_objects[ref] = normalize_object(k8s_cluster, self.remote_objects[ref], ignore_for_diffs)
normalized_remote_objects[ref] = normalize_object(k8s_cluster, self.remote_objects[ref], ignore_for_diffs, diff_objects[ref])

logger.info("Diffing remote/old objects against applied/new objects")
new_objects = []
Expand Down
21 changes: 19 additions & 2 deletions kluctl/diff/normalize.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import re

from kluctl.utils.dict_utils import copy_dict, get_dict_value, del_dict_value, \
set_dict_default_value
set_dict_default_value, list_matching_dict_pathes
from kluctl.utils.k8s_object_utils import split_api_version
from kluctl.utils.utils import parse_bool

IGNORE_DIFF_FIELD_ANNOTATION_REGEX = re.compile(r"^kluctl.io/ignore-diff-field(-\d*)?$")

def normalize_env(container):
env = container.get("env")
Expand Down Expand Up @@ -78,7 +82,7 @@ def normalize_misc(o):
del_dict_value(o, 'status')

# Performs some deterministic sorting and other normalizations to avoid ugly diffs due to order changes
def normalize_object(k8s_cluster, o, ignore_for_diffs):
def normalize_object(k8s_cluster, o, ignore_for_diffs, local_object):
group, version = split_api_version(o["apiVersion"])
kind = o['kind']
ns = get_dict_value(o, "metadata.namespace")
Expand Down Expand Up @@ -118,5 +122,18 @@ def check_match(v, m):
for p in field_path:
del_dict_value(o, p)

ignore_all = parse_bool(get_dict_value(local_object, 'metadata.annotations["kluctl.io/ignore-diff"]', "false"))
if ignore_all:
# Return empty object so that diffs will always be empty
return {}

del_fields = set()
for k, v in get_dict_value(local_object, "metadata.annotations", {}).items():
if IGNORE_DIFF_FIELD_ANNOTATION_REGEX.fullmatch(k):
for x in list_matching_dict_pathes(o, v):
del_fields.add(x)
for p in del_fields:
del_dict_value(o, p)

return o

0 comments on commit efe654f

Please sign in to comment.