Skip to content

Commit

Permalink
Strip attributes in List resources
Browse files Browse the repository at this point in the history
  • Loading branch information
allenporter committed Nov 10, 2024
1 parent 5455173 commit 5d03073
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 8 deletions.
25 changes: 17 additions & 8 deletions flux_local/tool/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,21 @@ 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")):
for item in items:
strip_attrs(item["metadata"], strip_attributes)


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

Expand Down Expand Up @@ -208,14 +223,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
214 changes: 214 additions & 0 deletions tests/tool/test_visitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
"""Tests for the visitor module."""

import base64
from pathlib import Path
from typing import Any
import yaml

import pytest

from flux_local.exceptions import HelmException
from flux_local.manifest import (
HelmRelease,
ValuesReference,
Secret,
ConfigMap,
Kustomization,
HelmChart,
SubstituteReference,
)
from flux_local.git_repo import ResourceSelector, PathSelector, build_manifest
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_corner_cases() -> 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
"""

0 comments on commit 5d03073

Please sign in to comment.