Merge pull request #5349 from fluxcd/trace-hr-oci

Fix `flux trace` for HRs from `OCIRepository`s
pull/5351/head
Max Jonas Werner 1 month ago committed by GitHub
commit 6150fe9942
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,18 @@
Object: deployment/podinfo
Namespace: {{ .ns }}
Status: Managed by Flux
---
HelmRelease: podinfo
Namespace: {{ .ns }}
Revision: 6.3.5
Status: Last reconciled at {{ .helmReleaseLastReconcile }}
Message: Release reconciliation succeeded
---
OCIRepository: podinfo-charts
Namespace: {{ .fluxns }}
URL: oci://ghcr.io/stefanprodan/charts/podinfo
Tag: 6.8.0
Revision: sha256:dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3
Status: Last reconciled at {{ .ociRepositoryLastReconcile }}
Message: stored artifact for digest 'sha256:dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3'

@ -0,0 +1,86 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .ns }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: podinfo
app.kubernetes.io/managed-by: Helm
helm.toolkit.fluxcd.io/name: podinfo
helm.toolkit.fluxcd.io/namespace: {{ .ns }}
name: podinfo
namespace: {{ .ns }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: podinfo
template:
metadata:
labels:
app.kubernetes.io/name: podinfo
spec:
containers:
- name: hello
command: [ "echo hello world" ]
image: busybox
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: podinfo
namespace: {{ .ns }}
spec:
chartRef:
kind: OCIRepository
name: podinfo-charts
namespace: {{ .fluxns }}
interval: 5m
status:
conditions:
- lastTransitionTime: "2021-07-16T15:42:20Z"
message: Release reconciliation succeeded
reason: ReconciliationSucceeded
status: "True"
type: Ready
lastAttemptedRevision: 6.3.5
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: flux-system
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: podinfo-charts
namespace: {{ .fluxns }}
spec:
interval: 10m0s
provider: generic
ref:
tag: 6.8.0
timeout: 60s
url: oci://ghcr.io/stefanprodan/charts/podinfo
status:
artifact:
lastUpdateTime: "2022-08-10T10:07:59Z"
metadata:
org.opencontainers.image.revision: 6.1.6@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0
org.opencontainers.image.source: https://github.com/stefanprodan/podinfo.git
path: "example"
revision: sha256:dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3
url: "example"
conditions:
- lastTransitionTime: "2021-07-20T00:48:16Z"
message: "stored artifact for digest 'sha256:dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3'"
reason: Succeed
status: "True"
type: Ready

@ -401,38 +401,65 @@ func traceHelm(ctx context.Context, kubeClient client.Client, hrName types.Names
var hrGitRepository *sourcev1.GitRepository var hrGitRepository *sourcev1.GitRepository
var hrGitRepositoryReady *metav1.Condition var hrGitRepositoryReady *metav1.Condition
if hr.Spec.Chart.Spec.SourceRef.Kind == sourcev1.GitRepositoryKind {
hrGitRepository = &sourcev1.GitRepository{}
sourceNamespace := hr.Namespace
if hr.Spec.Chart.Spec.SourceRef.Namespace != "" {
sourceNamespace = hr.Spec.Chart.Spec.SourceRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: hr.Spec.Chart.Spec.SourceRef.Name,
}, hrGitRepository)
if err != nil {
return "", fmt.Errorf("failed to find GitRepository: %w", err)
}
hrGitRepositoryReady = meta.FindStatusCondition(hrGitRepository.Status.Conditions, fluxmeta.ReadyCondition)
}
var hrHelmRepository *sourcev1.HelmRepository var hrHelmRepository *sourcev1.HelmRepository
var hrHelmRepositoryReady *metav1.Condition var hrHelmRepositoryReady *metav1.Condition
if hr.Spec.Chart.Spec.SourceRef.Kind == sourcev1.HelmRepositoryKind { var hrOCIRepository *sourcev1b2.OCIRepository
hrHelmRepository = &sourcev1.HelmRepository{} var hrOCIRepositoryReady *metav1.Condition
sourceNamespace := hr.Namespace if hr.Spec.Chart == nil {
if hr.Spec.Chart.Spec.SourceRef.Namespace != "" { if hr.Spec.ChartRef != nil {
sourceNamespace = hr.Spec.Chart.Spec.SourceRef.Namespace switch hr.Spec.ChartRef.Kind {
case sourcev1b2.OCIRepositoryKind:
hrOCIRepository = &sourcev1b2.OCIRepository{}
sourceNamespace := hr.Namespace
if hr.Spec.ChartRef.Namespace != "" {
sourceNamespace = hr.Spec.ChartRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: hr.Spec.ChartRef.Name,
}, hrOCIRepository)
if err != nil {
return "", fmt.Errorf("failed to find OCIRepository: %w", err)
}
hrOCIRepositoryReady = meta.FindStatusCondition(hrOCIRepository.Status.Conditions, fluxmeta.ReadyCondition)
}
kubeClient.Get(ctx, types.NamespacedName{
Namespace: hr.Spec.ChartRef.Namespace,
Name: hr.Spec.ChartRef.Name,
}, hrOCIRepository)
} }
err = kubeClient.Get(ctx, types.NamespacedName{ } else {
Namespace: sourceNamespace, if hr.Spec.Chart.Spec.SourceRef.Kind == sourcev1.GitRepositoryKind {
Name: hr.Spec.Chart.Spec.SourceRef.Name, hrGitRepository = &sourcev1.GitRepository{}
}, hrHelmRepository) sourceNamespace := hr.Namespace
if err != nil { if hr.Spec.Chart.Spec.SourceRef.Namespace != "" {
return "", fmt.Errorf("failed to find HelmRepository: %w", err) sourceNamespace = hr.Spec.Chart.Spec.SourceRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: hr.Spec.Chart.Spec.SourceRef.Name,
}, hrGitRepository)
if err != nil {
return "", fmt.Errorf("failed to find GitRepository: %w", err)
}
hrGitRepositoryReady = meta.FindStatusCondition(hrGitRepository.Status.Conditions, fluxmeta.ReadyCondition)
}
if hr.Spec.Chart.Spec.SourceRef.Kind == sourcev1.HelmRepositoryKind {
hrHelmRepository = &sourcev1.HelmRepository{}
sourceNamespace := hr.Namespace
if hr.Spec.Chart.Spec.SourceRef.Namespace != "" {
sourceNamespace = hr.Spec.Chart.Spec.SourceRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: hr.Spec.Chart.Spec.SourceRef.Name,
}, hrHelmRepository)
if err != nil {
return "", fmt.Errorf("failed to find HelmRepository: %w", err)
}
hrHelmRepositoryReady = meta.FindStatusCondition(hrHelmRepository.Status.Conditions, fluxmeta.ReadyCondition)
} }
hrHelmRepositoryReady = meta.FindStatusCondition(hrHelmRepository.Status.Conditions, fluxmeta.ReadyCondition)
} }
var traceTmpl = ` var traceTmpl = `
@ -515,6 +542,34 @@ Message: {{.GitRepositoryReady.Message}}
Status: Unknown Status: Unknown
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .OCIRepository }}
---
OCIRepository: {{.OCIRepository.Name}}
Namespace: {{.OCIRepository.Namespace}}
URL: {{.OCIRepository.Spec.URL}}
{{- if .OCIRepository.Spec.Reference }}
{{- if .OCIRepository.Spec.Reference.Tag }}
Tag: {{.OCIRepository.Spec.Reference.Tag}}
{{- else if .OCIRepository.Spec.Reference.SemVer }}
Tag: {{.OCIRepository.Spec.Reference.SemVer}}
{{- else if .OCIRepository.Spec.Reference.Digest }}
Digest: {{.OCIRepository.Spec.Reference.Digest}}
{{- end }}
{{- end }}
{{- if .OCIRepository.Status.Artifact }}
Revision: {{.OCIRepository.Status.Artifact.Revision}}
{{- end }}
{{- if .OCIRepositoryReady }}
{{- if eq .OCIRepositoryReady.Status "False" }}
Status: Last reconciliation failed at {{.OCIRepositoryReady.LastTransitionTime}}
{{- else }}
Status: Last reconciled at {{.OCIRepositoryReady.LastTransitionTime}}
{{- end }}
Message: {{.OCIRepositoryReady.Message}}
{{- else }}
Status: Unknown
{{- end }}
{{- end }}
` `
traceResult := struct { traceResult := struct {
@ -528,6 +583,9 @@ Status: Unknown
GitRepositoryReady *metav1.Condition GitRepositoryReady *metav1.Condition
HelmRepository *sourcev1.HelmRepository HelmRepository *sourcev1.HelmRepository
HelmRepositoryReady *metav1.Condition HelmRepositoryReady *metav1.Condition
OCIRepository *sourcev1b2.OCIRepository
OCIRepositoryReady *metav1.Condition
Annotations map[string]string
}{ }{
ObjectName: obj.GetKind() + "/" + obj.GetName(), ObjectName: obj.GetKind() + "/" + obj.GetName(),
ObjectNamespace: obj.GetNamespace(), ObjectNamespace: obj.GetNamespace(),
@ -539,6 +597,8 @@ Status: Unknown
GitRepositoryReady: hrGitRepositoryReady, GitRepositoryReady: hrGitRepositoryReady,
HelmRepository: hrHelmRepository, HelmRepository: hrHelmRepository,
HelmRepositoryReady: hrHelmRepositoryReady, HelmRepositoryReady: hrHelmRepositoryReady,
OCIRepository: hrOCIRepository,
OCIRepositoryReady: hrOCIRepositoryReady,
} }
t, err := template.New("tmpl").Parse(traceTmpl) t, err := template.New("tmpl").Parse(traceTmpl)

@ -85,6 +85,18 @@ func TestTrace(t *testing.T) {
"ociRepositoryLastReconcile": toLocalTime(t, "2021-07-20T00:48:16Z"), "ociRepositoryLastReconcile": toLocalTime(t, "2021-07-20T00:48:16Z"),
}, },
}, },
{
"Deployment from HelmRelease from OCI registry",
"trace podinfo --kind deployment --api-version=apps/v1",
"testdata/trace/deployment-hr-ocirepo.yaml",
"testdata/trace/deployment-hr-ocirepo.golden",
map[string]string{
"ns": allocateNamespace("podinfo"),
"fluxns": allocateNamespace("flux-system"),
"helmReleaseLastReconcile": toLocalTime(t, "2021-07-16T15:42:20Z"),
"ociRepositoryLastReconcile": toLocalTime(t, "2021-07-20T00:48:16Z"),
},
},
} }
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {

Loading…
Cancel
Save