diff --git a/flux_local/git_repo.py b/flux_local/git_repo.py index 4cf3de5c..5815552c 100644 --- a/flux_local/git_repo.py +++ b/flux_local/git_repo.py @@ -32,7 +32,6 @@ import contextlib from dataclasses import dataclass, field import logging -import networkx import os import tempfile from collections.abc import Callable, Awaitable, Iterable @@ -47,7 +46,7 @@ from .exceptions import FluxException from .manifest import ( CRD_KIND, - CLUSTER_KUSTOMIZE_DOMAIN, + FLUXTOMIZE_DOMAIN, KUSTOMIZE_DOMAIN, Cluster, ClusterPolicy, @@ -76,7 +75,10 @@ GIT_REPO_KIND = "GitRepository" OCI_REPO_KIND = "OCIRepository" DEFAULT_NAMESPACE = "flux-system" -ROOT_KUSTOMIZATION_NAME = "flux-system" +DEFAULT_NAME = "flux-system" +GREP_SOURCE_REF_KIND = f"spec.sourceRef.kind={GIT_REPO_KIND}|{OCI_REPO_KIND}" +ERROR_DETAIL_BAD_PATH = "Try specifying another path within the git repo?" +ERROR_DETAIL_BAD_KS = "Is a Kustomization pointing to a path that does not exist?" @dataclass @@ -161,7 +163,7 @@ def func(doc: dict[str, Any]) -> bool: return func -CLUSTER_KUSTOMIZE_DOMAIN_FILTER = domain_filter(CLUSTER_KUSTOMIZE_DOMAIN) +FLUXTOMIZE_DOMAIN_FILTER = domain_filter(FLUXTOMIZE_DOMAIN) KUSTOMIZE_DOMAIN_FILTER = domain_filter(KUSTOMIZE_DOMAIN) @@ -271,7 +273,7 @@ def predicate( def cluster_metadata_selector() -> MetadataSelector: """Create a new MetadataSelector for Kustomizations.""" - return MetadataSelector(namespace=DEFAULT_NAMESPACE) + return MetadataSelector(name=DEFAULT_NAME, namespace=DEFAULT_NAMESPACE) def ks_metadata_selector() -> MetadataSelector: @@ -314,8 +316,8 @@ class ResourceSelector: """ClusterPolicy objects to return.""" -async def get_flux_kustomizations( - root: Path, relative_path: Path +async def get_fluxtomizations( + root: Path, relative_path: Path, build: bool ) -> list[Kustomization]: """Find all flux Kustomizations in the specified path. @@ -323,13 +325,22 @@ async def get_flux_kustomizations( Kustomizations from the repo. Assumes that any flux Kustomization for a GitRepository is pointed at this cluster, following normal conventions. """ - cmd = kustomize.grep(f"kind={CLUSTER_KUSTOMIZE_KIND}", root / relative_path).grep( - f"spec.sourceRef.kind={GIT_REPO_KIND}|{OCI_REPO_KIND}" - ) + cmd: kustomize.Kustomize + if build: + _LOGGER.debug("kustomize.build") + cmd = ( + kustomize.build(root / relative_path) + .grep(f"kind={CLUSTER_KUSTOMIZE_KIND}") + .grep(GREP_SOURCE_REF_KIND) + ) + else: + _LOGGER.debug("kustomize.grep") + cmd = kustomize.grep( + f"kind={CLUSTER_KUSTOMIZE_KIND}", root / relative_path + ).grep(GREP_SOURCE_REF_KIND) docs = await cmd.objects() return [ - Kustomization.parse_doc(doc) - for doc in filter(CLUSTER_KUSTOMIZE_DOMAIN_FILTER, docs) + Kustomization.parse_doc(doc) for doc in filter(FLUXTOMIZE_DOMAIN_FILTER, docs) ] @@ -353,46 +364,27 @@ def find_path_parent(search: Path, prefixes: set[Path]) -> Path | None: return None -async def kustomization_traversal(path_selector: PathSelector) -> list[Kustomization]: +async def kustomization_traversal( + root_path_selector: PathSelector, path_selector: PathSelector, build: bool +) -> list[Kustomization]: """Search for kustomizations in the specified path.""" kustomizations: list[Kustomization] = [] visited: set[Path] = set() # Relative paths within the cluster + nodes: set[str] = set() path_queue: queue.Queue[Path] = queue.Queue() path_queue.put(path_selector.relative_path) - root = path_selector.root while not path_queue.empty(): path = path_queue.get() - _LOGGER.debug("Visiting path (%s) %s", root, path) + _LOGGER.debug("Visiting path (%s) %s", root_path_selector.path, path) try: - docs = await get_flux_kustomizations(root, path) + docs = await get_fluxtomizations(root_path_selector.root, path, build=build) except FluxException as err: - if visited: - raise FluxException( - f"Error building Fluxtomization in '{root}' path '{path}': {err}" - f"Is a Kustomization pointing to a path that does not exist?" - ) + detail = ERROR_DETAIL_BAD_KS if visited else ERROR_DETAIL_BAD_PATH raise FluxException( - f"Error building Fluxtomization in '{root}' path '{path}': {err}" - f"Try specifying another path within the git repo?" - ) - - # Source path is relative to the search path. Update to have the - # full prefix relative to the root. - for kustomization in docs: - if not kustomization.path: - _LOGGER.debug("Assigning implicit path %s", path_selector.relative_path) - kustomization.path = str(path_selector.relative_path) - if not kustomization.source_path: - continue - kustomization.source_path = str( - ((root / path) / kustomization.source_path).relative_to(root) - ) - _LOGGER.debug( - "Updated relative path: %s => %s", - node_name(kustomization), - kustomization.source_path, + f"Error building Fluxtomization in '{root_path_selector.root}' " + f"path '{path}': {err} - {detail}" ) visited |= set({path}) @@ -400,6 +392,20 @@ async def kustomization_traversal(path_selector: PathSelector) -> list[Kustomiza _LOGGER.debug("Found %s Kustomizations", len(docs)) result_docs = [] for doc in docs: + if doc.namespaced_name in nodes: + _LOGGER.debug( + "Ignoring duplicate Kustomization %s", doc.namespaced_name + ) + continue + nodes.add(doc.namespaced_name) + # Source path is relative to the search path. Update to have the + # full prefix relative to the root. + if not doc.path: + _LOGGER.debug( + "Assigning implicit path %s", root_path_selector.relative_path + ) + doc.path = str(root_path_selector.relative_path) + found_path: Path | None = None _LOGGER.debug( "Kustomization '%s' has sourceRef.kind '%s' of '%s'", @@ -428,7 +434,7 @@ async def kustomization_traversal(path_selector: PathSelector) -> list[Kustomiza _LOGGER.debug("Skipping kustomization %s; not known source", doc.name) continue - if not find_path_parent(found_path, visited) and found_path not in visited: + if found_path not in visited: path_queue.put(found_path) else: _LOGGER.debug("Already visited %s", found_path) @@ -446,125 +452,54 @@ def node_name(ks: Kustomization) -> str: return f"{ks.namespaced_name} @ {ks.id_name}" -def make_clusters( - kustomizations: list[Kustomization], sources: list[Source] | None = None -) -> list[Cluster]: - """Convert the flat list of Kustomizations into a Cluster. - - This will reverse engineer which Kustomizations are root nodes for the cluster - based on the parent paths. Root Kustomizations are made the cluster and everything - else is made a child. - """ - if not sources: - sources = [] - - # Build a directed graph from a kustomization path to the path - # of the kustomization that created it. - graph = networkx.DiGraph() - node_path_map = {Path(ks.path): ks for ks in kustomizations if ks.source_path} - for ks in kustomizations: - if not ks.source_path: - raise InputException( - "Kustomization did not have source path; Old kustomize?" - ) - - graph.add_node(node_name(ks), ks=ks) - if ks.name == ROOT_KUSTOMIZATION_NAME and ks.namespace == DEFAULT_NAMESPACE: - # Do not attempt parent search below - continue - - # Find the parent Kustomization that produced this based on the - # matching the kustomize source parent paths with a Kustomization - # target path. - source = Path(ks.source_path) - _LOGGER.debug("--- Examining candidate Kustomization ---") - _LOGGER.debug("Ks : %s", ks.namespaced_name) - _LOGGER.debug("Path : %s", Path(ks.path)) - _LOGGER.debug("Source path: %s", source) - source_kustomizations = find_source_kustomization(source, node_path_map) - _LOGGER.debug( - "Possible sources: %s", [f"{node_name(ks)}" for ks in source_kustomizations] - ) - if source_kustomizations: - while source_kustomizations: - candidate = source_kustomizations.pop(0) - # These names can be compared since they are within the scope of - # the source path so within the same cluster. - if candidate.namespaced_name != ks.namespaced_name: - _LOGGER.debug( - "Found parent %s => %s", - ks.namespaced_name, - candidate.namespaced_name, - ) - if graph.has_edge(node_name(ks), node_name(candidate)): - _LOGGER.debug("Already has opposite edge; Skipping cycle") - else: - graph.add_edge(node_name(candidate), node_name(ks)) - else: - _LOGGER.debug( - "Skipping candidate source %s", candidate.namespaced_name - ) - else: - _LOGGER.debug("No parent for %s (source=%s)", node_name(ks), source) - - # Clusters are subgraphs within the graph that are connected, with the root - # node being the cluster itself. All children Kustomizations are flattended. - _LOGGER.debug("Creating clusters based on connectivity") - for node, degree in graph.in_degree(): - _LOGGER.debug("Node: %s, degree: %s", node, degree) - roots = [node for node, degree in graph.in_degree() if degree == 0] - roots.sort() - - clusters: list[Cluster] = [] - _LOGGER.debug("roots=%s", roots) - for root in roots: - root_ks = graph.nodes[root]["ks"] - nodes = [root] + list(networkx.descendants(graph, root)) - nodes.sort() - kustomizations = [graph.nodes[node]["ks"] for node in nodes] - clusters.append( - Cluster( - name=root_ks.name, - namespace=root_ks.namespace, - path=root_ks.path, - kustomizations=kustomizations, - ) - ) - _LOGGER.debug( - "Created cluster %s with %s kustomizations", root_ks.name, len(nodes) - ) - - return clusters - - async def get_clusters( path_selector: PathSelector, cluster_selector: MetadataSelector, kustomization_selector: MetadataSelector, ) -> list[Cluster]: """Load Cluster objects from the specified path.""" - - kustomizations = await kustomization_traversal(path_selector) - clusters = list( - filter( - cluster_selector.predicate, - make_clusters(kustomizations, path_selector.sources or []), + try: + roots = await get_fluxtomizations( + path_selector.root, path_selector.relative_path, build=False ) - ) + except FluxException as err: + raise FluxException( + f"Error building Fluxtomization in '{path_selector.root}' path " + f"'{path_selector.relative_path}': {err}" + f"Try specifying another path within the git repo?" + ) + _LOGGER.debug("roots=%s", roots) + clusters = [ + Cluster(name=ks.name, namespace=ks.namespace or "", path=ks.path) + for ks in roots + if cluster_selector.predicate(ks) + ] + build = True + if not clusters: + # There are no flux-system Kustomizations within this path. Fall back to + # assuming everything in the current directory is part of a cluster. + _LOGGER.debug( + "No clusters found; Processing as a Kustomization: %s", + path_selector.relative_path, + ) + clusters = [ + Cluster(name="cluster", namespace="", path=str(path_selector.relative_path)) + ] + build = False + for cluster in clusters: - cluster.kustomizations = list( - filter(kustomization_selector.predicate, cluster.kustomizations) + _LOGGER.debug("Building cluster %s %s", cluster.name, cluster.path) + results = await kustomization_traversal( + path_selector, + PathSelector(path=Path(cluster.path), sources=path_selector.sources), + build=build, ) + results.sort(key=lambda x: (x.namespace, x.name)) + cluster.kustomizations = results + clusters.sort(key=lambda x: (x.path, x.namespace, x.name)) return clusters -async def get_kustomizations(path: Path) -> list[dict[str, Any]]: - """Load Kustomization objects from the specified path.""" - cmd = kustomize.grep(f"kind={KUSTOMIZE_KIND}", path) - docs = await cmd.objects() - return list(filter(KUSTOMIZE_DOMAIN_FILTER, docs)) - - async def build_kustomization( kustomization: Kustomization, cluster_path: Path, @@ -669,21 +604,6 @@ async def build_manifest( clusters = await get_clusters( selector.path, selector.cluster, selector.kustomization ) - if not clusters and selector.path.path: - _LOGGER.debug("No clusters found; Processing as a Kustomization: %s", selector) - # The argument path may be a Kustomization inside a cluster. Create a synthetic - # cluster with any found Kustomizations - cluster = Cluster( - name="cluster", namespace="", path=str(selector.path.relative_path) - ) - objects = await get_kustomizations(selector.path.path) - if objects: - cluster.kustomizations = [ - Kustomization( - name="kustomization", path=str(selector.path.relative_path) - ) - ] - clusters.append(cluster) async def update_kustomization(cluster: Cluster) -> None: build_tasks = [] diff --git a/flux_local/manifest.py b/flux_local/manifest.py index 00f282fb..68378db9 100644 --- a/flux_local/manifest.py +++ b/flux_local/manifest.py @@ -28,7 +28,7 @@ # Match a prefix of apiVersion to ensure we have the right type of object. # We don't check specific versions for forward compatibility on upgrade. -CLUSTER_KUSTOMIZE_DOMAIN = "kustomize.toolkit.fluxcd.io" +FLUXTOMIZE_DOMAIN = "kustomize.toolkit.fluxcd.io" KUSTOMIZE_DOMAIN = "kustomize.config.k8s.io" HELM_REPO_DOMAIN = "source.toolkit.fluxcd.io" HELM_RELEASE_DOMAIN = "helm.toolkit.fluxcd.io" @@ -283,7 +283,7 @@ class Kustomization(BaseManifest): @classmethod def parse_doc(cls, doc: dict[str, Any]) -> "Kustomization": """Parse a partial Kustomization from a kubernetes resource.""" - _check_version(doc, CLUSTER_KUSTOMIZE_DOMAIN) + _check_version(doc, FLUXTOMIZE_DOMAIN) if not (metadata := doc.get("metadata")): raise InputException(f"Invalid {cls} missing metadata: {doc}") if not (name := metadata.get("name")): @@ -349,7 +349,7 @@ class Cluster(BaseManifest): @classmethod def parse_doc(cls, doc: dict[str, Any]) -> "Cluster": """Parse a partial Kustomization from a kubernetes resource.""" - _check_version(doc, CLUSTER_KUSTOMIZE_DOMAIN) + _check_version(doc, FLUXTOMIZE_DOMAIN) if not (metadata := doc.get("metadata")): raise InputException(f"Invalid {cls} missing metadata: {doc}") if not (name := metadata.get("name")): @@ -362,6 +362,11 @@ def parse_doc(cls, doc: dict[str, Any]) -> "Cluster": raise InputException(f"Invalid {cls} missing spec.path: {doc}") return Cluster(name=name, namespace=namespace, path=path) + @property + def namespaced_name(self, sep: str = "/") -> str: + """Return the namespace and name concatenated as an id.""" + return f"{self.namespace}{sep}{self.name}" + @property def id_name(self) -> str: """Identifier for the Cluster in tests.""" diff --git a/tests/test_git_repo.py b/tests/test_git_repo.py index 7b72c5d2..575231ad 100644 --- a/tests/test_git_repo.py +++ b/tests/test_git_repo.py @@ -13,7 +13,6 @@ kustomization_traversal, Source, PathSelector, - make_clusters, ) from flux_local.kustomize import Kustomize from flux_local.manifest import Kustomization @@ -327,10 +326,12 @@ async def fetch(root: Path, p: Path) -> list[Kustomization]: return results.pop(0) with patch("flux_local.git_repo.PathSelector.root", Path("/home/example")), patch( - "flux_local.git_repo.get_flux_kustomizations", fetch + "flux_local.git_repo.get_fluxtomizations", fetch ): kustomizations = await kustomization_traversal( - path_selector=PathSelector(path=Path(path)) + root_path_selector=PathSelector(path=Path(path)), + path_selector=PathSelector(path=Path(path)), + build=True, ) assert len(kustomizations) == 4 assert paths == [ @@ -338,18 +339,6 @@ async def fetch(root: Path, p: Path) -> list[Kustomization]: ("/home/example", "kubernetes/apps"), ] - clusters = make_clusters(kustomizations) - assert len(clusters) == 1 - cluster = clusters[0] - assert cluster.name == "cluster" - assert cluster.namespace == "flux-system" - assert [ks.path for ks in cluster.kustomizations] == [ - "./kubernetes/flux", - "./kubernetes/apps", - "./kubernetes/apps/rook-ceph/rook-ceph/app", - "./kubernetes/apps/volsync/volsync/app", - ] - async def test_kustomization_traversal_multi_cluster() -> None: """Test discovery of multiple clusters in the repo.""" @@ -404,10 +393,12 @@ async def fetch(root: Path, p: Path) -> list[Kustomization]: return results.pop(0) with patch("flux_local.git_repo.PathSelector.root", Path("/home/example")), patch( - "flux_local.git_repo.get_flux_kustomizations", fetch + "flux_local.git_repo.get_fluxtomizations", fetch ): kustomizations = await kustomization_traversal( - path_selector=PathSelector(path=Path(".")) + root_path_selector=PathSelector(path=Path(".")), + path_selector=PathSelector(path=Path(".")), + build=True, ) assert len(kustomizations) == 6 # We don't need to visit the clusters subdirectories because the original @@ -416,27 +407,6 @@ async def fetch(root: Path, p: Path) -> list[Kustomization]: ("/home/example", "."), ] - clusters = make_clusters(kustomizations) - assert len(clusters) == 2 - cluster = clusters[0] - assert cluster.name == "cluster" - assert cluster.namespace == "flux-system" - assert cluster.path == "./clusters/dev" - assert [ks.path for ks in cluster.kustomizations] == [ - "./certmanager/dev", - "./clusters/dev", - "./crds", - ] - cluster = clusters[1] - assert cluster.name == "cluster" - assert cluster.namespace == "flux-system" - assert cluster.path == "./clusters/prod" - assert [ks.path for ks in cluster.kustomizations] == [ - "./certmanager/prod", - "./clusters/prod", - "./crds", - ] - def test_source() -> None: """Test parsing a source from a string.""" diff --git a/tests/testdata/cluster3/clusters/cluster3/flux-system/gotk-sync.yaml b/tests/testdata/cluster3/clusters/cluster3/flux-system/gotk-sync.yaml index f2d413e3..df553784 100644 --- a/tests/testdata/cluster3/clusters/cluster3/flux-system/gotk-sync.yaml +++ b/tests/testdata/cluster3/clusters/cluster3/flux-system/gotk-sync.yaml @@ -20,7 +20,7 @@ metadata: namespace: flux-system spec: interval: 10m0s - path: ./tests/testdata/cluster3/ + path: ./tests/testdata/cluster3/clusters/cluster3 prune: true sourceRef: kind: GitRepository diff --git a/tests/testdata/cluster5/kustomization.yaml b/tests/testdata/cluster5/kustomization.yaml index 6bb7dc20..e8e9cef7 100644 --- a/tests/testdata/cluster5/kustomization.yaml +++ b/tests/testdata/cluster5/kustomization.yaml @@ -4,3 +4,4 @@ kind: Kustomization resources: - metallb-release.yaml - weave-gitops-release.yaml + - repositories.yaml diff --git a/tests/testdata/cluster5/repositories.yaml b/tests/testdata/cluster5/repositories.yaml new file mode 100644 index 00000000..820cfd60 --- /dev/null +++ b/tests/testdata/cluster5/repositories.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: bitnami + namespace: flux-system +spec: + type: oci + interval: 30m + url: oci://registry-1.docker.io/bitnamicharts +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: weave-charts + namespace: flux-system +spec: + interval: 1h + url: https://helm.gitops.weave.works diff --git a/tests/testdata/cluster6/renovate/kustomization.yaml b/tests/testdata/cluster6/apps/renovate/kustomization.yaml similarity index 100% rename from tests/testdata/cluster6/renovate/kustomization.yaml rename to tests/testdata/cluster6/apps/renovate/kustomization.yaml diff --git a/tests/testdata/cluster6/renovate/release.yaml b/tests/testdata/cluster6/apps/renovate/release.yaml similarity index 100% rename from tests/testdata/cluster6/renovate/release.yaml rename to tests/testdata/cluster6/apps/renovate/release.yaml diff --git a/tests/testdata/cluster6/renovate/repository.yaml b/tests/testdata/cluster6/apps/renovate/repository.yaml similarity index 100% rename from tests/testdata/cluster6/renovate/repository.yaml rename to tests/testdata/cluster6/apps/renovate/repository.yaml diff --git a/tests/testdata/cluster6/cluster/apps.yaml b/tests/testdata/cluster6/cluster/apps.yaml new file mode 100644 index 00000000..c83e511e --- /dev/null +++ b/tests/testdata/cluster6/cluster/apps.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: apps + namespace: flux-system +spec: + path: ./tests/testdata/cluster6/apps/ + sourceRef: + kind: GitRepository + name: flux-system diff --git a/tests/testdata/cluster6/cluster/flux-system/gotk-sync.yaml b/tests/testdata/cluster6/cluster/flux-system/gotk-sync.yaml new file mode 100644 index 00000000..9704d5e7 --- /dev/null +++ b/tests/testdata/cluster6/cluster/flux-system/gotk-sync.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta1 +kind: GitRepository +metadata: + name: flux-system + namespace: flux-system +spec: + interval: 1m0s + ref: + branch: main + secretRef: + name: flux-system + url: ssh://git@github.com/allenporter/flux-local +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +kind: Kustomization +metadata: + name: flux-system + namespace: flux-system +spec: + interval: 10m0s + path: ./tests/testdata/cluster6/cluster + prune: true + sourceRef: + kind: GitRepository + name: flux-system diff --git a/tests/testdata/cluster6/cluster/flux-system/kustomization.yaml b/tests/testdata/cluster6/cluster/flux-system/kustomization.yaml new file mode 100644 index 00000000..197efd8a --- /dev/null +++ b/tests/testdata/cluster6/cluster/flux-system/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - gotk-sync.yaml diff --git a/tests/tool/testdata/build6.yaml b/tests/tool/testdata/build6.yaml index fc4adf8b..32164b3a 100644 --- a/tests/tool/testdata/build6.yaml +++ b/tests/tool/testdata/build6.yaml @@ -57,4 +57,51 @@ stdout: |+ interval: 30m url: https://docs.renovatebot.com/helm-charts + --- + apiVersion: kustomize.toolkit.fluxcd.io/v1 + kind: Kustomization + metadata: + name: apps + namespace: flux-system + annotations: + config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' + spec: + path: ./tests/testdata/cluster6/apps/ + sourceRef: + kind: GitRepository + name: flux-system + --- + apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 + kind: Kustomization + metadata: + name: flux-system + namespace: flux-system + annotations: + config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' + spec: + interval: 10m0s + path: ./tests/testdata/cluster6/cluster + prune: true + sourceRef: + kind: GitRepository + name: flux-system + --- + apiVersion: source.toolkit.fluxcd.io/v1beta1 + kind: GitRepository + metadata: + name: flux-system + namespace: flux-system + annotations: + config.kubernetes.io/index: '2' + internal.config.kubernetes.io/index: '2' + spec: + interval: 1m0s + ref: + branch: main + secretRef: + name: flux-system + url: ssh://git@github.com/allenporter/flux-local + ... diff --git a/tests/tool/testdata/get_cluster2.yaml b/tests/tool/testdata/get_cluster2.yaml index 722ed74b..eb4c1e39 100644 --- a/tests/tool/testdata/get_cluster2.yaml +++ b/tests/tool/testdata/get_cluster2.yaml @@ -4,5 +4,5 @@ args: - --path - tests/testdata/cluster2/ stdout: | - NAME PATH KUSTOMIZATIONS - cluster ./tests/testdata/cluster2/flux 5 + NAME PATH KUSTOMIZATIONS + cluster tests/testdata/cluster2 5 diff --git a/tests/tool/testdata/get_cluster3.yaml b/tests/tool/testdata/get_cluster3.yaml index eea06a25..25187b88 100644 --- a/tests/tool/testdata/get_cluster3.yaml +++ b/tests/tool/testdata/get_cluster3.yaml @@ -6,5 +6,5 @@ args: - --sources - cluster=tests/testdata/cluster3 stdout: | - NAME PATH KUSTOMIZATIONS - flux-system ./tests/testdata/cluster3/ 3 + NAME PATH KUSTOMIZATIONS + flux-system ./tests/testdata/cluster3/clusters/cluster3 2 diff --git a/tests/tool/testdata/get_cluster4.yaml b/tests/tool/testdata/get_cluster4.yaml index fb292d13..43984827 100644 --- a/tests/tool/testdata/get_cluster4.yaml +++ b/tests/tool/testdata/get_cluster4.yaml @@ -4,5 +4,5 @@ args: - --path - tests/testdata/cluster4/ stdout: | - NAME PATH KUSTOMIZATIONS - cluster ./tests/testdata/cluster4/flux 3 + NAME PATH KUSTOMIZATIONS + cluster tests/testdata/cluster4 3 diff --git a/tests/tool/testdata/get_cluster6.yaml b/tests/tool/testdata/get_cluster6.yaml index 1f848216..291742d8 100644 --- a/tests/tool/testdata/get_cluster6.yaml +++ b/tests/tool/testdata/get_cluster6.yaml @@ -4,5 +4,5 @@ args: - --path - tests/testdata/cluster6/ stdout: | - NAME PATH KUSTOMIZATIONS - cluster tests/testdata/cluster6 1 + NAME PATH KUSTOMIZATIONS + flux-system ./tests/testdata/cluster6/cluster 2 diff --git a/tests/tool/testdata/get_hr2.yaml b/tests/tool/testdata/get_hr2.yaml new file mode 100644 index 00000000..1ddbec24 --- /dev/null +++ b/tests/tool/testdata/get_hr2.yaml @@ -0,0 +1,10 @@ +args: +- get +- hr +- -A +- --path +- tests/testdata/cluster2 +stdout: | + NAMESPACE NAME REVISION CHART SOURCE + networking ingress-nginx 4.5.2 networking-ingress-nginx ingress-nginx + monitoring kubernetes-dashboard 6.0.0 monitoring-kubernetes-dashboard kubernetes-dashboard diff --git a/tests/tool/testdata/get_hr3.yaml b/tests/tool/testdata/get_hr3.yaml new file mode 100644 index 00000000..d6c17b8f --- /dev/null +++ b/tests/tool/testdata/get_hr3.yaml @@ -0,0 +1,8 @@ +args: +- get +- hr +- -A +- --path +- tests/testdata/cluster3 +stdout: | + no HelmRelease objects found in cluster diff --git a/tests/tool/testdata/get_hr4.yaml b/tests/tool/testdata/get_hr4.yaml new file mode 100644 index 00000000..118d92c1 --- /dev/null +++ b/tests/tool/testdata/get_hr4.yaml @@ -0,0 +1,9 @@ +args: +- get +- hr +- -A +- --path +- tests/testdata/cluster4 +stdout: | + NAMESPACE NAME REVISION CHART SOURCE + monitoring kubernetes-dashboard 6.0.0 monitoring-kubernetes-dashboard kubernetes-dashboard diff --git a/tests/tool/testdata/get_hr5.yaml b/tests/tool/testdata/get_hr5.yaml new file mode 100644 index 00000000..0faed139 --- /dev/null +++ b/tests/tool/testdata/get_hr5.yaml @@ -0,0 +1,10 @@ +args: +- get +- hr +- -A +- --path +- tests/testdata/cluster5 +stdout: | + NAMESPACE NAME REVISION CHART SOURCE + flux-system weave-gitops 4.0.22 flux-system-weave-gitops weave-charts + metallb metallb 4.1.14 metallb-metallb bitnami diff --git a/tests/tool/testdata/get_ks3.yaml b/tests/tool/testdata/get_ks3.yaml new file mode 100644 index 00000000..64ed465a --- /dev/null +++ b/tests/tool/testdata/get_ks3.yaml @@ -0,0 +1,12 @@ +args: +- get +- ks +- -A +- --path +- tests/testdata/cluster3 +- --sources +- cluster=tests/testdata/cluster3 +stdout: | + NAMESPACE NAME PATH + flux-system namespaces tests/testdata/cluster3/namespaces/overlays/cluster3 + flux-system tenants tests/testdata/cluster3/tenants/overlays/cluster3 diff --git a/tests/tool/testdata/get_ks4.yaml b/tests/tool/testdata/get_ks4.yaml new file mode 100644 index 00000000..21aeeda2 --- /dev/null +++ b/tests/tool/testdata/get_ks4.yaml @@ -0,0 +1,10 @@ +args: +- get +- ks +- --path +- tests/testdata/cluster4 +stdout: | + NAME PATH + cluster ./tests/testdata/cluster4/flux + cluster-apps ./tests/testdata/cluster4/apps + cluster-apps-kubernetes-dashboard ./tests/testdata/cluster4/apps/monitoring/kubernetes-dashboard diff --git a/tests/tool/testdata/get_ks5.yaml b/tests/tool/testdata/get_ks5.yaml index 60cf634a..6f0c00ac 100644 --- a/tests/tool/testdata/get_ks5.yaml +++ b/tests/tool/testdata/get_ks5.yaml @@ -4,5 +4,6 @@ args: - --path - tests/testdata/cluster5 stdout: | - NAME PATH - flux-system ./tests/testdata/cluster5/clusters/prod + NAME PATH + infra-controllers tests/testdata/cluster5 + flux-system ./tests/testdata/cluster5/clusters/prod diff --git a/tests/tool/testdata/get_ks6.yaml b/tests/tool/testdata/get_ks6.yaml index 79d4491b..1e07ca40 100644 --- a/tests/tool/testdata/get_ks6.yaml +++ b/tests/tool/testdata/get_ks6.yaml @@ -4,5 +4,6 @@ args: - --path - tests/testdata/cluster6 stdout: | - NAME PATH - kustomization tests/testdata/cluster6 + NAME PATH + apps ./tests/testdata/cluster6/apps/ + flux-system ./tests/testdata/cluster6/cluster diff --git a/tests/tool/testdata/get_ks_path_ks.yaml b/tests/tool/testdata/get_ks_path_ks.yaml index 051393a5..7b0eb956 100644 --- a/tests/tool/testdata/get_ks_path_ks.yaml +++ b/tests/tool/testdata/get_ks_path_ks.yaml @@ -5,5 +5,4 @@ args: - --path - ./tests/testdata/cluster/apps/prod stdout: | - NAMESPACE NAME PATH - None kustomization tests/testdata/cluster/apps/prod + no Kustomization objects found in cluster