Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make flux trace work with OCIRepository #2971

Merged
merged 1 commit into from Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions cmd/flux/testdata/trace/helmrelease-oci.golden
@@ -0,0 +1,21 @@

Object: HelmRelease/podinfo
Namespace: {{ .ns }}
Status: Managed by Flux
---
Kustomization: infrastructure
Namespace: {{ .fluxns }}
Path: ./infrastructure
Revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Status: Last reconciled at {{ .kustomizationLastReconcile }}
Message: Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f
---
OCIRepository: flux-system
Namespace: {{ .fluxns }}
URL: oci://ghcr.io/example/repo
Tag: 1.2.3
Revision: dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3
Origin Revision: 6.1.6/450796ddb2ab6724ee1cc32a4be56da032d1cca0
Origin Source: https://github.com/stefanprodan/podinfo.git
Status: Last reconciled at {{ .ociRepositoryLastReconcile }}
Message: stored artifact for digest 'dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3'
92 changes: 92 additions & 0 deletions cmd/flux/testdata/trace/helmrelease-oci.yaml
@@ -0,0 +1,92 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .ns }}
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: infrastructure
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: podinfo
namespace: {{ .ns }}
spec:
chart:
spec:
chart: podinfo
sourceRef:
kind: HelmRepository
name: podinfo
namespace: {{ .fluxns }}
interval: 5m
status:
conditions:
- lastTransitionTime: "2021-07-16T15:42:20Z"
message: Release reconciliation succeeded
reason: ReconciliationSucceeded
status: "True"
type: Ready
helmChart: {{ .fluxns }}/podinfo-podinfo
lastAppliedRevision: 6.0.0
lastAttemptedRevision: 6.0.0
lastAttemptedValuesChecksum: c31db75d05b7515eba2eef47bd71038c74b2e531
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: infrastructure
namespace: {{ .fluxns }}
spec:
path: ./infrastructure
sourceRef:
kind: OCIRepository
name: flux-system
validation: client
interval: 5m
prune: false
status:
conditions:
- lastTransitionTime: "2021-08-01T04:52:56Z"
message: 'Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
reason: ReconciliationSucceeded
status: "True"
type: Ready
lastAppliedRevision: main/696f056df216eea4f9401adbee0ff744d4df390f
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: flux-system
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 10m0s
provider: generic
ref:
tag: 1.2.3
timeout: 60s
url: oci://ghcr.io/example/repo
status:
artifact:
lastUpdateTime: "2022-08-10T10:07:59Z"
metadata:
org.opencontainers.image.revision: 6.1.6/450796ddb2ab6724ee1cc32a4be56da032d1cca0
org.opencontainers.image.source: https://github.com/stefanprodan/podinfo.git
path: "example"
revision: dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3
url: "example"
conditions:
- lastTransitionTime: "2021-07-20T00:48:16Z"
message: "stored artifact for digest 'dbdb109711ffb3be77504d2670dbe13c24dd63d8d7f1fb489d350e5bfe930dd3'"
reason: Succeed
status: "True"
type: Ready
32 changes: 16 additions & 16 deletions cmd/flux/testdata/trace/helmrelease.golden
@@ -1,19 +1,19 @@

Object: HelmRelease/podinfo
Namespace: {{ .ns }}
Status: Managed by Flux
Object: HelmRelease/podinfo
Namespace: {{ .ns }}
Status: Managed by Flux
---
Kustomization: infrastructure
Namespace: {{ .fluxns }}
Path: ./infrastructure
Revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Status: Last reconciled at {{ .kustomizationLastReconcile }}
Message: Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Kustomization: infrastructure
Namespace: {{ .fluxns }}
Path: ./infrastructure
Revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Status: Last reconciled at {{ .kustomizationLastReconcile }}
Message: Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f
---
GitRepository: flux-system
Namespace: {{ .fluxns }}
URL: ssh://git@github.com/example/repo
Branch: main
Revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Status: Last reconciled at {{ .gitRepositoryLastReconcile }}
Message: Fetched revision: main/696f056df216eea4f9401adbee0ff744d4df390f
GitRepository: flux-system
Namespace: {{ .fluxns }}
URL: ssh://git@github.com/example/repo
Branch: main
Revision: main/696f056df216eea4f9401adbee0ff744d4df390f
Status: Last reconciled at {{ .gitRepositoryLastReconcile }}
Message: Fetched revision: main/696f056df216eea4f9401adbee0ff744d4df390f
119 changes: 87 additions & 32 deletions cmd/flux/trace.go
Expand Up @@ -37,6 +37,7 @@ import (
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
fluxmeta "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/oci"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
)

Expand Down Expand Up @@ -219,72 +220,122 @@ func traceKustomization(ctx context.Context, kubeClient client.Client, ksName ty
}
ksReady := meta.FindStatusCondition(ks.Status.Conditions, fluxmeta.ReadyCondition)

var ksRepository *sourcev1.GitRepository
var gitRepository *sourcev1.GitRepository
var ociRepository *sourcev1.OCIRepository
var ksRepositoryReady *metav1.Condition
if ks.Spec.SourceRef.Kind == sourcev1.GitRepositoryKind {
ksRepository = &sourcev1.GitRepository{}
switch ks.Spec.SourceRef.Kind {
case sourcev1.GitRepositoryKind:
gitRepository = &sourcev1.GitRepository{}
sourceNamespace := ks.Namespace
if ks.Spec.SourceRef.Namespace != "" {
sourceNamespace = ks.Spec.SourceRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: ks.Spec.SourceRef.Name,
}, ksRepository)
}, gitRepository)
if err != nil {
return "", fmt.Errorf("failed to find GitRepository: %w", err)
}
ksRepositoryReady = meta.FindStatusCondition(ksRepository.Status.Conditions, fluxmeta.ReadyCondition)
ksRepositoryReady = meta.FindStatusCondition(gitRepository.Status.Conditions, fluxmeta.ReadyCondition)
case sourcev1.OCIRepositoryKind:
ociRepository = &sourcev1.OCIRepository{}
sourceNamespace := ks.Namespace
if ks.Spec.SourceRef.Namespace != "" {
sourceNamespace = ks.Spec.SourceRef.Namespace
}
err = kubeClient.Get(ctx, types.NamespacedName{
Namespace: sourceNamespace,
Name: ks.Spec.SourceRef.Name,
}, ociRepository)
if err != nil {
return "", fmt.Errorf("failed to find OCIRepository: %w", err)
}
ksRepositoryReady = meta.FindStatusCondition(ociRepository.Status.Conditions, fluxmeta.ReadyCondition)
}

var traceTmpl = `
Object: {{.ObjectName}}
Object: {{.ObjectName}}
{{- if .ObjectNamespace }}
Namespace: {{.ObjectNamespace}}
Namespace: {{.ObjectNamespace}}
{{- end }}
Status: Managed by Flux
Status: Managed by Flux
{{- if .Kustomization }}
---
Kustomization: {{.Kustomization.Name}}
Namespace: {{.Kustomization.Namespace}}
Kustomization: {{.Kustomization.Name}}
Namespace: {{.Kustomization.Namespace}}
{{- if .Kustomization.Spec.TargetNamespace }}
Target: {{.Kustomization.Spec.TargetNamespace}}
Target: {{.Kustomization.Spec.TargetNamespace}}
{{- end }}
Path: {{.Kustomization.Spec.Path}}
Revision: {{.Kustomization.Status.LastAppliedRevision}}
Path: {{.Kustomization.Spec.Path}}
Revision: {{.Kustomization.Status.LastAppliedRevision}}
{{- if .KustomizationReady }}
Status: Last reconciled at {{.KustomizationReady.LastTransitionTime}}
Message: {{.KustomizationReady.Message}}
Status: Last reconciled at {{.KustomizationReady.LastTransitionTime}}
Message: {{.KustomizationReady.Message}}
{{- else }}
Status: Unknown
Status: Unknown
{{- end }}
{{- end }}
{{- if .GitRepository }}
---
GitRepository: {{.GitRepository.Name}}
Namespace: {{.GitRepository.Namespace}}
URL: {{.GitRepository.Spec.URL}}
GitRepository: {{.GitRepository.Name}}
Namespace: {{.GitRepository.Namespace}}
URL: {{.GitRepository.Spec.URL}}
{{- if .GitRepository.Spec.Reference }}
{{- if .GitRepository.Spec.Reference.Tag }}
Tag: {{.GitRepository.Spec.Reference.Tag}}
Tag: {{.GitRepository.Spec.Reference.Tag}}
{{- else if .GitRepository.Spec.Reference.SemVer }}
Tag: {{.GitRepository.Spec.Reference.SemVer}}
Tag: {{.GitRepository.Spec.Reference.SemVer}}
{{- else if .GitRepository.Spec.Reference.Branch }}
Branch: {{.GitRepository.Spec.Reference.Branch}}
Branch: {{.GitRepository.Spec.Reference.Branch}}
{{- end }}
{{- end }}
{{- if .GitRepository.Status.Artifact }}
Revision: {{.GitRepository.Status.Artifact.Revision}}
Revision: {{.GitRepository.Status.Artifact.Revision}}
{{- end }}
{{- if .GitRepositoryReady }}
{{- if eq .GitRepositoryReady.Status "False" }}
Status: Last reconciliation failed at {{.GitRepositoryReady.LastTransitionTime}}
{{- if .RepositoryReady }}
{{- if eq .RepositoryReady.Status "False" }}
Status: Last reconciliation failed at {{.RepositoryReady.LastTransitionTime}}
{{- else }}
Status: Last reconciled at {{.GitRepositoryReady.LastTransitionTime}}
Status: Last reconciled at {{.RepositoryReady.LastTransitionTime}}
{{- end }}
Message: {{.GitRepositoryReady.Message}}
Message: {{.RepositoryReady.Message}}
{{- else }}
Status: Unknown
Status: Unknown
{{- 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}}
{{- if .OCIRepository.Status.Artifact.Metadata }}
{{- $metadata := .OCIRepository.Status.Artifact.Metadata }}
{{- range $k, $v := .Annotations }}
{{ with (index $metadata $v) }}{{ $k }}{{ . }}{{ end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .RepositoryReady }}
{{- if eq .RepositoryReady.Status "False" }}
Status: Last reconciliation failed at {{.RepositoryReady.LastTransitionTime}}
{{- else }}
Status: Last reconciled at {{.RepositoryReady.LastTransitionTime}}
{{- end }}
Message: {{.RepositoryReady.Message}}
{{- else }}
Status: Unknown
{{- end }}
{{- end }}
`
Expand All @@ -295,14 +346,18 @@ Status: Unknown
Kustomization *kustomizev1.Kustomization
KustomizationReady *metav1.Condition
GitRepository *sourcev1.GitRepository
GitRepositoryReady *metav1.Condition
OCIRepository *sourcev1.OCIRepository
RepositoryReady *metav1.Condition
Annotations map[string]string
}{
ObjectName: obj.GetKind() + "/" + obj.GetName(),
ObjectNamespace: obj.GetNamespace(),
Kustomization: ks,
KustomizationReady: ksReady,
GitRepository: ksRepository,
GitRepositoryReady: ksRepositoryReady,
GitRepository: gitRepository,
OCIRepository: ociRepository,
RepositoryReady: ksRepositoryReady,
Annotations: map[string]string{"Origin Source: ": oci.SourceAnnotation, "Origin Revision: ": oci.RevisionAnnotation},
}

t, err := template.New("tmpl").Parse(traceTmpl)
Expand Down
12 changes: 12 additions & 0 deletions cmd/flux/trace_test.go
Expand Up @@ -57,6 +57,18 @@ func TestTrace(t *testing.T) {
"gitRepositoryLastReconcile": toLocalTime(t, "2021-07-20T00:48:16Z"),
},
},
{
"HelmRelease from OCI registry",
"trace podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta1",
"testdata/trace/helmrelease-oci.yaml",
"testdata/trace/helmrelease-oci.golden",
map[string]string{
"ns": allocateNamespace("podinfo"),
"fluxns": allocateNamespace("flux-system"),
"kustomizationLastReconcile": toLocalTime(t, "2021-08-01T04:52:56Z"),
"ociRepositoryLastReconcile": toLocalTime(t, "2021-07-20T00:48:16Z"),
},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down