Skip to content

Commit

Permalink
Add a test repo to reproduce a connectivity issue (#231)
Browse files Browse the repository at this point in the history
Issue #225
Issue #198

Reproduces the issue with:
```
$ flux-local get cluster --path tests/testdata/cluster4/
NAME                                 PATH                                                              KUSTOMIZATIONS    
cluster-apps-kubernetes-dashboard    ./tests/testdata/cluster4/apps/monitoring/kubernetes-dashboard    1                 
cluster                              ./tests/testdata/cluster4/flux                                    2                 
```
  • Loading branch information
allenporter authored Jun 11, 2023
1 parent 1782ebf commit 315119c
Show file tree
Hide file tree
Showing 20 changed files with 270 additions and 14 deletions.
61 changes: 51 additions & 10 deletions flux_local/git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,18 @@ async def get_flux_kustomizations(
]


def find_source_kustomization(
search: Path, node_map: dict[Path, Kustomization]
) -> list[Kustomization]:
"""Return all source Kustomizations that might manage the specified path."""
results = []
set(node_map)
for parent in search.parents:
if node := node_map.get(parent):
results.append(node)
return results


def find_path_parent(search: Path, prefixes: set[Path]) -> Path | None:
"""Return a prefix path that is a parent of the search path."""
for parent in search.parents:
Expand Down Expand Up @@ -383,6 +395,7 @@ async def kustomization_traversal(path_selector: PathSelector) -> list[Kustomiza
visited |= set({path})

_LOGGER.debug("Found %s Kustomizations", len(docs))
result_docs = []
for doc in docs:
found_path: Path | None = None
_LOGGER.debug(
Expand All @@ -409,10 +422,20 @@ async def kustomization_traversal(path_selector: PathSelector) -> list[Kustomiza
path_queue.put(found_path)
else:
_LOGGER.debug("Already visited %s", found_path)
kustomizations.extend(docs)
result_docs.append(doc)
kustomizations.extend(result_docs)
return kustomizations


def node_name(ks: Kustomization) -> str:
"""Return a unique node name for the Kustomization.
This includes the path since it needs to be unique within the entire
repository since we support multi-cluster.
"""
return f"{ks.namespaced_name} @ {ks.id_name}"


def make_clusters(
kustomizations: list[Kustomization], sources: list[Source] | None = None
) -> list[Cluster]:
Expand All @@ -428,7 +451,7 @@ def make_clusters(
# Build a directed graph from a kustomization path to the path
# of the kustomization that created it.
graph = networkx.DiGraph()
parent_paths = set([Path(ks.path) for ks in kustomizations])
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(
Expand All @@ -452,20 +475,38 @@ def make_clusters(
_LOGGER.debug("Excluding OCIRepository without source %s", ks.name)
continue

path = Path(ks.path)
graph.add_node(path, ks=ks)
graph.add_node(node_name(ks), ks=ks)

# 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)
if (
parent_path := find_path_parent(source, parent_paths)
) and parent_path != path:
_LOGGER.debug("Found parent %s => %s", path, parent_path)
graph.add_edge(parent_path, 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,
)
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 (%s)", path, source)
_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.
Expand Down
5 changes: 5 additions & 0 deletions flux_local/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ def id_name(self) -> str:
"""Identifier for the Kustomization in tests"""
return f"{self.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}"

_COMPACT_EXCLUDE_FIELDS = {
"helm_releases": {
"__all__": HelmRelease._COMPACT_EXCLUDE_FIELDS,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,10 @@ async def fetch(root: Path, p: Path) -> list[Kustomization]:
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",
"./kubernetes/flux",
]


Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/cluster4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This repo is modeled after https://github.com/szinn/k8s-homelab where there are
fluxtomizations and kustomziations pointing at the same directory.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: kubernetes-dashboard
namespace: monitoring
spec:
interval: 15m
chart:
spec:
chart: kubernetes-dashboard
version: 6.0.0
sourceRef:
kind: HelmRepository
name: kubernetes-dashboard
namespace: flux-system
maxHistory: 3
install:
createNamespace: true
remediation:
retries: 3
upgrade:
cleanupOnFail: true
remediation:
retries: 3
uninstall:
keepHistory: false
values:
env:
TZ: America/New_York
extraArgs:
- --enable-skip-login
- --disable-settings-authorizer
- --enable-insecure-login
- --token-ttl=43200
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: |
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
hajimari.io/icon: mdi:kubernetes
hosts:
- &host kubernetes.devbu.io
tls:
- hosts:
- *host
metricsScraper:
enabled: true
serviceMonitor:
enabled: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: cluster-apps-kubernetes-dashboard
namespace: flux-system
spec:
path: ./tests/testdata/cluster4/apps/monitoring/kubernetes-dashboard
prune: true
sourceRef:
kind: GitRepository
name: home-ops-kubernetes
healthChecks:
- apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
name: kubernetes-dashboard
namespace: monitoring
interval: 30m
retryInterval: 1m
timeout: 3m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: monitoring
resources:
- ./helmrelease.yaml
labels:
- pairs:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
6 changes: 6 additions & 0 deletions tests/testdata/cluster4/apps/monitoring/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./namespace.yaml
- ./kubernetes-dashboard/ks.yaml
7 changes: 7 additions & 0 deletions tests/testdata/cluster4/apps/monitoring/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
kustomize.toolkit.fluxcd.io/prune: disabled
13 changes: 13 additions & 0 deletions tests/testdata/cluster4/flux/apps.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: cluster-apps
namespace: flux-system
spec:
interval: 10m
path: ./tests/testdata/cluster4/apps
prune: true
sourceRef:
kind: GitRepository
name: home-ops-kubernetes
32 changes: 32 additions & 0 deletions tests/testdata/cluster4/flux/config/cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: home-ops-kubernetes
namespace: flux-system
spec:
interval: 30m
url: ssh://[email protected]/example/home-ops
ref:
branch: main
secretRef:
name: github-deploy-key
ignore: |
# exclude all
/*
# include kubernetes directory
!/tests/testdata/cluster4/kubernetes
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: cluster
namespace: flux-system
spec:
interval: 30m
path: ./tests/testdata/cluster4/flux
prune: true
wait: false
sourceRef:
kind: GitRepository
name: home-ops-kubernetes
25 changes: 25 additions & 0 deletions tests/testdata/cluster4/flux/config/flux.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: flux-manifests
namespace: flux-system
spec:
interval: 10m
url: oci://ghcr.io/fluxcd/flux-manifests
ref:
tag: v0.40.0
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux
namespace: flux-system
spec:
interval: 10m
path: ./
prune: true
wait: true
sourceRef:
kind: OCIRepository
name: flux-manifests
6 changes: 6 additions & 0 deletions tests/testdata/cluster4/flux/config/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./flux.yaml
- ./cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: kubernetes-dashboard
namespace: flux-system
spec:
interval: 2h
url: https://kubernetes.github.io/dashboard/
5 changes: 5 additions & 0 deletions tests/testdata/cluster4/flux/repositories/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- kubernetes-dashboard.yaml
2 changes: 1 addition & 1 deletion tests/tool/testdata/diff_ks_yaml_empty_sources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ args:
- -o
- yaml
- --sources
- ""
- ''
8 changes: 8 additions & 0 deletions tests/tool/testdata/get_cluster2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
args:
- get
- cluster
- --path
- tests/testdata/cluster2/
stdout: |
NAME PATH KUSTOMIZATIONS
cluster ./tests/testdata/cluster2/flux 5
8 changes: 8 additions & 0 deletions tests/tool/testdata/get_cluster3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
args:
- get
- cluster
- --path
- tests/testdata/cluster3/
stdout: |
NAME PATH KUSTOMIZATIONS
flux-system ./tests/testdata/cluster3/ 1
8 changes: 8 additions & 0 deletions tests/tool/testdata/get_cluster4.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
args:
- get
- cluster
- --path
- tests/testdata/cluster4/
stdout: |
NAME PATH KUSTOMIZATIONS
cluster ./tests/testdata/cluster4/flux 3
4 changes: 2 additions & 2 deletions tests/tool/testdata/get_ks2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ args:
- tests/testdata/cluster2
stdout: |
NAME PATH
cluster ./tests/testdata/cluster2/flux
cluster-apps ./tests/testdata/cluster2/apps
cluster-apps-kubernetes-dashboard ./tests/testdata/cluster2/apps/monitoring/kubernetes-dashboard/app
cluster-apps-ingress-nginx ./tests/testdata/cluster2/apps/networking/ingress-nginx/app
cluster-apps-ingress-nginx-certificates ./tests/testdata/cluster2/apps/networking/ingress-nginx/certificates
cluster ./tests/testdata/cluster2/flux
cluster-apps-kubernetes-dashboard ./tests/testdata/cluster2/apps/monitoring/kubernetes-dashboard/app

0 comments on commit 315119c

Please sign in to comment.