pkg/gitops/claims_test.go
Rama main · réplica de lectura del repositorio original.
package gitops
import (
"slices"
"strings"
"testing"
"github.com/skyhook-io/radar/pkg/resourceid"
)
func TestClaims(t *testing.T) {
cm := resourceid.Ref{Kind: "ConfigMap", Namespace: "shop", Name: "settings"}
app := func(ns, name string) resourceid.Ref {
return resourceid.Ref{Group: "argoproj.io", Kind: "Application", Namespace: ns, Name: name}
}
for _, tc := range []struct {
name string
labels map[string]string
annotations map[string]string
want []Claim
}{
{name: "no metadata"},
{
name: "tracking ID on its own object",
annotations: map[string]string{argoTrackingIDAnnotation: "shop:/ConfigMap:shop/settings"},
want: []Claim{{Manager: app("", "shop"), Source: ClaimArgoTrackingID}},
},
{
name: "tracking ID of an Application outside Argo CD's namespace",
annotations: map[string]string{argoTrackingIDAnnotation: "team_shop:/ConfigMap:shop/settings"},
want: []Claim{{Manager: app("team", "shop"), Source: ClaimArgoTrackingID}},
},
{
// A Secret copied with its source's annotations names the source.
name: "tracking ID copied from another object",
annotations: map[string]string{argoTrackingIDAnnotation: "shop:/ConfigMap:other/settings"},
want: []Claim{{Manager: app("", "shop"), Source: ClaimArgoTrackingID, Copied: true}},
},
{
name: "malformed tracking ID makes no claim",
annotations: map[string]string{argoTrackingIDAnnotation: "shop:garbage"},
},
{
// Kubernetes names can't contain "_", so a second one is malformed.
name: "an Application name with an underscore makes no claim",
labels: map[string]string{argoInstanceLabel: "team_shop_x"},
annotations: map[string]string{argoTrackingIDAnnotation: "team_shop_x:/ConfigMap:shop/settings"},
},
{
name: "instance label, with and without a namespace",
labels: map[string]string{argoInstanceLabel: "team_shop"},
want: []Claim{{Manager: app("team", "shop"), Source: ClaimArgoInstanceLabel}},
},
{
name: "Flux labels need both name and namespace",
labels: map[string]string{fluxKustomizeNameLabel: "apps", fluxHelmNameLabel: "web", fluxHelmNSLabel: "flux-system"},
want: []Claim{{
Manager: resourceid.Ref{Group: "helm.toolkit.fluxcd.io", Kind: "HelmRelease", Namespace: "flux-system", Name: "web"},
Source: ClaimFluxHelmRelease,
}},
},
{
// Every candidate survives, so a resolver can see the disagreement.
name: "several sources",
labels: map[string]string{fluxKustomizeNameLabel: "apps", fluxKustomizeNSLabel: "flux-system", argoInstanceLabel: "shop"},
annotations: map[string]string{helmReleaseNameAnno: "web", helmReleaseNSAnno: "shop"},
want: []Claim{
{Manager: resourceid.Ref{Group: "kustomize.toolkit.fluxcd.io", Kind: "Kustomization", Namespace: "flux-system", Name: "apps"}, Source: ClaimFluxKustomization},
{Manager: app("", "shop"), Source: ClaimArgoInstanceLabel},
{Manager: resourceid.Ref{Kind: "HelmRelease", Namespace: "shop", Name: "web"}, Source: ClaimHelmRelease},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
if got := Claims(cm, tc.labels, tc.annotations); !slices.Equal(got, tc.want) {
t.Fatalf("Claims = %+v\nwant %+v", got, tc.want)
}
})
}
}
// With annotation+label tracking, Argo CD writes the label cut to 63
// characters: it names the tracking ID's Application, not another one.
func TestTruncatedInstanceLabelNamesTheTrackedApplication(t *testing.T) {
cm := resourceid.Ref{Kind: "ConfigMap", Namespace: "shop", Name: "settings"}
full := strings.Repeat("n", 40) + "_" + strings.Repeat("a", 40)
got := Claims(cm, map[string]string{argoInstanceLabel: full[:63]}, map[string]string{argoTrackingIDAnnotation: full + ":/ConfigMap:shop/settings"})
if len(got) != 2 || got[0].Manager != got[1].Manager {
t.Fatalf("Claims = %+v; want both to name the tracked Application", got)
}
}
// Argo CD also trims what no longer ends in a letter or digit after the cut.
func TestTruncatedInstanceLabelTrimsLikeArgoCD(t *testing.T) {
cm := resourceid.Ref{Kind: "ConfigMap", Namespace: "shop", Name: "settings"}
full := "team_" + strings.Repeat("a", 57) + "-release"
label := strings.TrimRight(full[:63], "-")
got := Claims(cm, map[string]string{argoInstanceLabel: label}, map[string]string{argoTrackingIDAnnotation: full + ":/ConfigMap:shop/settings"})
if len(label) != 62 || len(got) != 2 || got[0].Manager != got[1].Manager {
t.Fatalf("label %q (%d): Claims = %+v; want both to name the tracked Application", label, len(label), got)
}
}
// Argo CD writes its destination namespace into a cluster-scoped object's
// tracking ID, or none, and ignores it when comparing.
func TestTrackingIDOfAClusterScopedObject(t *testing.T) {
role := resourceid.Ref{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "reader"}
for _, id := range []string{"shop:rbac.authorization.k8s.io/ClusterRole:/reader", "shop:rbac.authorization.k8s.io/ClusterRole:shop/reader"} {
if got := Claims(role, nil, map[string]string{argoTrackingIDAnnotation: id}); len(got) != 1 || got[0].Copied {
t.Errorf("Claims(%s) = %+v; want one claim on its own object", id, got)
}
}
if got := Claims(role, nil, map[string]string{argoTrackingIDAnnotation: "shop:rbac.authorization.k8s.io/ClusterRole:/writer"}); len(got) != 1 || !got[0].Copied {
t.Errorf("Claims naming another ClusterRole = %+v; want copied", got)
}
}