Add test for empty label selector and fix ACL name
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
parent
c67a4c62f1
commit
8f4ae31562
|
|
@ -75,7 +75,7 @@ type ImageRepositorySpec struct {
|
|||
}
|
||||
|
||||
type AccessFrom struct {
|
||||
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector,omitempty"`
|
||||
NamespaceSelectors []NamespaceSelector `json:"namespaceSelectors,omitempty"`
|
||||
}
|
||||
|
||||
type NamespaceSelector struct {
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ spec:
|
|||
accessFrom:
|
||||
description: AccessFrom defines an ACL for allowing cross-namespace references to the ImageRepository object based on the caller's namespace labels.
|
||||
properties:
|
||||
namespaceSelector:
|
||||
namespaceSelectors:
|
||||
items:
|
||||
properties:
|
||||
matchLabels:
|
||||
|
|
|
|||
|
|
@ -6,3 +6,7 @@ metadata:
|
|||
spec:
|
||||
image: ghcr.io/stefanprodan/podinfo
|
||||
interval: 1m0s
|
||||
accessFrom:
|
||||
namespaceSelectors:
|
||||
- matchLabels:
|
||||
kubernetes.io/metadata.name: flux-system
|
||||
|
|
|
|||
|
|
@ -332,29 +332,17 @@ func (r *ImagePolicyReconciler) hasAccessToRepository(ctx context.Context, polic
|
|||
}
|
||||
policyLabels := policyNamespace.GetLabels()
|
||||
|
||||
// deny access if the policy namespace has no labels
|
||||
if len(policyLabels) == 0 {
|
||||
return false, fmt.Errorf("ImageRepository '%s/%s' can't be accessed due to missing lables on namespace '%s'",
|
||||
repo.Namespace, repo.Name, policy.Namespace)
|
||||
}
|
||||
|
||||
// check if the policy namespace labels match any ACL
|
||||
var allowed bool
|
||||
for _, selector := range acl.NamespaceSelectors {
|
||||
sel, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{MatchLabels: selector.MatchLabels})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if sel.Matches(labels.Set(policyLabels)) {
|
||||
allowed = true
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
if !allowed {
|
||||
return allowed, fmt.Errorf("ImageRepository '%s/%s' can't be accessed due to lables mismatch on namespace '%s'",
|
||||
repo.Namespace, repo.Name, policy.Namespace)
|
||||
}
|
||||
|
||||
return allowed, nil
|
||||
return false, fmt.Errorf("ImageRepository '%s/%s' can't be accessed due to labels mismatch on namespace '%s'",
|
||||
repo.Namespace, repo.Name, policy.Namespace)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -458,6 +458,85 @@ var _ = Describe("ImagePolicy controller", func() {
|
|||
})
|
||||
})
|
||||
|
||||
When("is in different namespace with no empty match labels", func() {
|
||||
It("grants access", func() {
|
||||
policyNamespace := &corev1.Namespace{}
|
||||
policyNamespace.Name = "acl-" + randStringRunes(5)
|
||||
|
||||
Expect(k8sClient.Create(context.Background(), policyNamespace)).To(Succeed())
|
||||
defer k8sClient.Delete(context.Background(), policyNamespace)
|
||||
|
||||
versions := []string{"1.0.0", "1.0.1"}
|
||||
imgRepo := loadImages(registryServer, "acl-image-"+randStringRunes(5), versions)
|
||||
|
||||
repo := imagev1.ImageRepository{
|
||||
Spec: imagev1.ImageRepositorySpec{
|
||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||
Image: imgRepo,
|
||||
AccessFrom: &imagev1.AccessFrom{
|
||||
NamespaceSelectors: []imagev1.NamespaceSelector{
|
||||
{
|
||||
MatchLabels: make(map[string]string),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
repoObjectName := types.NamespacedName{
|
||||
Name: "acl-repo-" + randStringRunes(5),
|
||||
Namespace: "default",
|
||||
}
|
||||
repo.Name = repoObjectName.Name
|
||||
repo.Namespace = repoObjectName.Namespace
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
|
||||
defer cancel()
|
||||
|
||||
r := imageRepoReconciler
|
||||
Expect(r.Create(ctx, &repo)).To(Succeed())
|
||||
|
||||
Eventually(func() bool {
|
||||
err := r.Get(ctx, repoObjectName, &repo)
|
||||
return err == nil && repo.Status.LastScanResult != nil
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
Expect(repo.Status.CanonicalImageName).To(Equal(imgRepo))
|
||||
Expect(repo.Status.LastScanResult.TagCount).To(Equal(len(versions)))
|
||||
|
||||
polObjectName := types.NamespacedName{
|
||||
Name: "acl-pol-" + randStringRunes(5),
|
||||
Namespace: policyNamespace.Name,
|
||||
}
|
||||
pol := imagev1.ImagePolicy{
|
||||
Spec: imagev1.ImagePolicySpec{
|
||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||
Name: repoObjectName.Name,
|
||||
Namespace: repoObjectName.Namespace,
|
||||
},
|
||||
Policy: imagev1.ImagePolicyChoice{
|
||||
SemVer: &imagev1.SemVerPolicy{
|
||||
Range: "1.0.x",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
pol.Namespace = polObjectName.Namespace
|
||||
pol.Name = polObjectName.Name
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), contextTimeout)
|
||||
defer cancel()
|
||||
|
||||
Expect(r.Create(ctx, &pol)).To(Succeed())
|
||||
|
||||
Eventually(func() bool {
|
||||
err := r.Get(ctx, polObjectName, &pol)
|
||||
return err == nil && pol.Status.LatestImage != ""
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
Expect(pol.Status.LatestImage).To(Equal(imgRepo + ":1.0.1"))
|
||||
|
||||
Expect(r.Delete(ctx, &pol)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
When("is in different namespace with matching ACL", func() {
|
||||
It("grants access", func() {
|
||||
policyNamespace := &corev1.Namespace{}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Resource Types:
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>namespaceSelector</code><br>
|
||||
<code>namespaceSelectors</code><br>
|
||||
<em>
|
||||
<a href="#image.toolkit.fluxcd.io/v1beta1.NamespaceSelector">
|
||||
[]NamespaceSelector
|
||||
|
|
|
|||
|
|
@ -132,9 +132,9 @@ spec:
|
|||
secretRef:
|
||||
name: regcred
|
||||
accessFrom:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: flux-system
|
||||
namespaceSelectors:
|
||||
- matchLabels:
|
||||
kubernetes.io/metadata.name: flux-system
|
||||
```
|
||||
|
||||
**Note** that the `kubernetes.io/metadata.name` is a readonly label added by Kubernetes >= 1.21
|
||||
|
|
|
|||
Loading…
Reference in New Issue