Skip to content

Commit

Permalink
Strip attributes in List resources (#802)
Browse files Browse the repository at this point in the history
  • Loading branch information
allenporter authored Nov 10, 2024
1 parent 5455173 commit 9ec19ec
Show file tree
Hide file tree
Showing 2 changed files with 269 additions and 8 deletions.
27 changes: 19 additions & 8 deletions flux_local/tool/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,23 @@ def update_manifest(self, manifest: Manifest) -> None:
helm_release.images.sort()


def strip_resource_attributes(resource: dict[str, Any], strip_attributes: list[str]) -> None:
"""Strip any annotations from kustomize that contribute to diff noise when objects are re-ordered in the output."""
strip_attrs(resource["metadata"], strip_attributes)
# Remove common noisy labels in commonly used templates
if (
(spec := resource.get("spec"))
and (templ := spec.get("template"))
and (meta := templ.get("metadata"))
):
strip_attrs(meta, strip_attributes)
if resource["kind"] == "List" and (items := resource.get("items")) and isinstance(items, list):
for item in items:
if not (item_meta := item.get("metadata")):
continue
strip_attrs(item_meta, strip_attributes)


class ObjectOutput(ResourceOutput):
"""Resource visitor that builds outputs for objects within the kustomization."""

Expand Down Expand Up @@ -208,14 +225,8 @@ async def call_async(
)
continue
# Remove common noisy labels
strip_attrs(metadata, self.strip_attributes)
# Remove common noisy labels in commonly used templates
if (
(spec := resource.get("spec"))
and (templ := spec.get("template"))
and (meta := templ.get("metadata"))
):
strip_attrs(meta, self.strip_attributes)
strip_resource_attributes(resource, self.strip_attributes)

resource_key = ResourceKey(
kind=kind,
kustomization_path=str(kustomization_path),
Expand Down
250 changes: 250 additions & 0 deletions tests/tool/test_visitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
"""Tests for the visitor module."""

from typing import Any
import yaml

import pytest


from flux_local.tool.visitor import strip_resource_attributes

STRIP_ATTRIBUTES = [
"app.kubernetes.io/version",
"chart",
]


@pytest.mark.parametrize(
("metadata", "expected_metadata"),
[
(
{
"labels": {
"app.kubernetes.io/version": "1.0.0",
"app.kubernetes.io/managed-by": "Helm",
}
},
{
"labels": {
"app.kubernetes.io/managed-by": "Helm",
},
},
),
(
{
"annotations": {
"app.kubernetes.io/version": "1.0.0",
"app.kubernetes.io/managed-by": "Helm",
}
},
{
"annotations": {
"app.kubernetes.io/managed-by": "Helm",
},
},
),
(
{},
{},
),
],
)
def test_strip_resource_attributes(
metadata: dict[str, Any], expected_metadata: dict[str, Any]
) -> None:
"""Test the strip_resource_attributes function."""
resource = {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-configmap",
"namespace": "default",
**metadata,
},
"data": {
"key1": "value1",
"key2": "value2",
},
}
strip_resource_attributes(resource, STRIP_ATTRIBUTES)
assert resource == {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-configmap",
"namespace": "default",
**expected_metadata,
},
"data": {
"key1": "value1",
"key2": "value2",
},
}


def test_strip_deployment_metadata() -> None:
"""Test the strip_resource_attributes function."""
resource = yaml.load(
"""apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
app.kubernetes.io/version: 1.0.0
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
""",
Loader=yaml.Loader,
)

strip_resource_attributes(resource, STRIP_ATTRIBUTES)
assert (
yaml.dump(resource, sort_keys=False)
== """apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
"""
)


def test_strip_list_metadata() -> None:
"""Test the stripping metadata from a list resource."""
resource = yaml.load(
"""apiVersion: v1
items:
- apiVersion: stable.example.com/v1
kind: CronTab
metadata:
annotations:
app: my-cron-tab
app.kubernetes.io/version: 1.0.0
creationTimestamp: '2021-06-20T07:35:27Z'
generation: 1
name: my-new-cron-object
namespace: default
resourceVersion: '1326'
uid: 9aab1d66-628e-41bb-a422-57b8b3b1f5a9
spec:
cronSpec: '* * * * */5'
image: my-awesome-cron-image
kind: List
metadata:
resourceVersion: ''
selfLink: ''
""",
Loader=yaml.Loader,
)

strip_resource_attributes(resource, STRIP_ATTRIBUTES)
assert (
yaml.dump(resource, sort_keys=False)
== """apiVersion: v1
items:
- apiVersion: stable.example.com/v1
kind: CronTab
metadata:
annotations:
app: my-cron-tab
creationTimestamp: '2021-06-20T07:35:27Z'
generation: 1
name: my-new-cron-object
namespace: default
resourceVersion: '1326'
uid: 9aab1d66-628e-41bb-a422-57b8b3b1f5a9
spec:
cronSpec: '* * * * */5'
image: my-awesome-cron-image
kind: List
metadata:
resourceVersion: ''
selfLink: ''
"""
)


def test_strip_list_null_items() -> None:
"""Test corner cases of handling metadata."""
resource = yaml.load(
"""apiVersion: v1
kind: List
metadata:
resourceVersion: ''
selfLink: ''
items:
""",
Loader=yaml.Loader,
)

strip_resource_attributes(resource, STRIP_ATTRIBUTES)
assert (
yaml.dump(resource, sort_keys=False)
== """apiVersion: v1
kind: List
metadata:
resourceVersion: ''
selfLink: ''
items: null
"""
)


def test_strip_list_item_without_metdata() -> None:
"""Test corner cases of handling metadata."""
resource = yaml.load(
"""apiVersion: v1
kind: List
metadata:
resourceVersion: ''
selfLink: ''
items:
- kind: CronTab
""",
Loader=yaml.Loader,
)

strip_resource_attributes(resource, STRIP_ATTRIBUTES)
assert (
yaml.dump(resource, sort_keys=False)
== """apiVersion: v1
kind: List
metadata:
resourceVersion: ''
selfLink: ''
items:
- kind: CronTab
"""
)

0 comments on commit 9ec19ec

Please sign in to comment.