-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add container images from Kustomziations to the cluster manifest (#443)
``` # flux-local get cluster --path tests/testdata/cluster8/ -o yaml --enable-images --all-namespaces --- clusters: - path: tests/testdata/cluster8 kustomizations: - name: apps namespace: flux-system path: tests/testdata/cluster8/apps helm_repos: [] helm_releases: [] cluster_policies: [] images: - alpine - name: flux-system namespace: flux-system path: tests/testdata/cluster8/cluster helm_repos: [] helm_releases: [] cluster_policies: [] images: [] ``` Issue #434
- Loading branch information
1 parent
9fd95a7
commit b77ba60
Showing
14 changed files
with
331 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
"""Helper functions for working with container images.""" | ||
|
||
import logging | ||
from typing import Any | ||
|
||
from . import git_repo, manifest | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
# Object types that may have container images. | ||
KINDS = [ | ||
"Pod", | ||
"Deployment", | ||
"StatefulSet", | ||
"ReplicaSet", | ||
"DaemonSet", | ||
"CronJob", | ||
"Job", | ||
"ReplicationController", | ||
] | ||
IMAGE_KEY = "image" | ||
|
||
|
||
def _extract_images(doc: dict[str, Any]) -> set[str]: | ||
"""Extract the image from a Kubernetes object.""" | ||
images: set[str] = set({}) | ||
for key, value in doc.items(): | ||
if key == IMAGE_KEY: | ||
images.add(value) | ||
elif isinstance(value, dict): | ||
images.update(_extract_images(value)) | ||
elif isinstance(value, list): | ||
for item in value: | ||
if isinstance(item, dict): | ||
images.update(_extract_images(item)) | ||
return images | ||
|
||
|
||
class ImageVisitor: | ||
"""Helper that visits container image related objects. | ||
This tracks the container images used by the kustomizations and HelmReleases | ||
so they can be dumped for further verification. | ||
""" | ||
|
||
def __init__(self) -> None: | ||
"""Initialize ImageVisitor.""" | ||
self.images: dict[str, set[str]] = {} | ||
|
||
def repo_visitor(self) -> git_repo.DocumentVisitor: | ||
"""Return a git_repo.DocumentVisitor that points to this object.""" | ||
|
||
def add_image(name: str, doc: dict[str, Any]) -> None: | ||
"""Visitor function to find relevant images and record them for later inspection. | ||
Updates the image set with the images found in the document. | ||
""" | ||
images = _extract_images(doc) | ||
if not images: | ||
return | ||
if name in self.images: | ||
self.images[name].update(images) | ||
else: | ||
self.images[name] = set(images) | ||
|
||
return git_repo.DocumentVisitor(kinds=KINDS, func=add_image) | ||
|
||
def update_manifest(self, manifest: manifest.Manifest) -> None: | ||
"""Update the manifest with the images found in the repo.""" | ||
for cluster in manifest.clusters: | ||
for kustomization in cluster.kustomizations: | ||
if images := self.images.get(kustomization.namespaced_name): | ||
kustomization.images = list(images) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Tests for image.""" | ||
|
||
from pathlib import Path | ||
from typing import Any | ||
|
||
import pytest | ||
from syrupy.assertion import SnapshotAssertion | ||
|
||
from flux_local.git_repo import build_manifest, ResourceSelector, PathSelector | ||
from flux_local.image import ImageVisitor | ||
|
||
TESTDATA = Path("tests/testdata/cluster8") | ||
CWD = Path.cwd() | ||
|
||
|
||
@pytest.mark.parametrize( | ||
("test_path", "expected"), | ||
[ | ||
( | ||
CWD / "tests/testdata/cluster8", | ||
{"flux-system/apps": {"alpine", "busybox"}}, | ||
), | ||
( | ||
CWD / "tests/testdata/cluster7", | ||
{}, | ||
), | ||
], | ||
) | ||
async def test_image_visitor( | ||
snapshot: SnapshotAssertion, test_path: str, expected: dict[str, Any] | ||
) -> None: | ||
"""Tests for building the manifest.""" | ||
|
||
image_visitor = ImageVisitor() | ||
query = ResourceSelector( | ||
path=PathSelector(Path(test_path)), | ||
doc_visitor=image_visitor.repo_visitor(), | ||
) | ||
await build_manifest(selector=query) | ||
|
||
assert image_visitor.images == expected |
Oops, something went wrong.