Skip to content

Commit 741030b

Browse files
committed
image: mutate group admission attributes to ensure grouped resources are captured
1 parent 75c6750 commit 741030b

File tree

3 files changed

+84
-5
lines changed

3 files changed

+84
-5
lines changed

pkg/api/latest/latest.go

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ func OriginLegacyKind(gvk unversioned.GroupVersionKind) bool {
5555
return OriginKind(gvk) && gvk.Group == ""
5656
}
5757

58+
// IsOriginAPIGroup returns true if the provided group name belongs to Origin API.
59+
func IsOriginAPIGroup(groupName string) bool {
60+
for _, v := range Versions {
61+
if v.Group == groupName {
62+
return true
63+
}
64+
}
65+
return false
66+
}
67+
5868
// IsKindInAnyOriginGroup returns true if OpenShift owns the kind described in any apiVersion.
5969
// TODO: this may not work once we divide builds/deployments/images into their own API groups
6070
func IsKindInAnyOriginGroup(kind string) bool {

pkg/image/admission/imagepolicy/imagepolicy.go

+38-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
1717
"k8s.io/kubernetes/pkg/util/sets"
1818

19+
"github.com/openshift/origin/pkg/api/latest"
1920
"github.com/openshift/origin/pkg/api/meta"
2021
"github.com/openshift/origin/pkg/client"
2122
oadmission "github.com/openshift/origin/pkg/cmd/server/admission"
@@ -124,6 +125,34 @@ func (a *imagePolicyPlugin) Validate() error {
124125
return nil
125126
}
126127

128+
// mutateAttributesToLegacyResources mutates the admission attributes in a way where the
129+
// Origin API groups are converted to "legacy" or "core" group.
130+
// This provides a backward compatibility with existing configurations and also closes the
131+
// hole where clients might bypass the admission by using API group endpoint and API group
132+
// resource instead of legacy one.
133+
func mutateAttributesToLegacyResources(attr admission.Attributes) admission.Attributes {
134+
resource := attr.GetResource()
135+
if len(resource.Group) > 0 && latest.IsOriginAPIGroup(resource.Group) {
136+
resource.Group = ""
137+
}
138+
kind := attr.GetKind()
139+
if len(kind.Group) > 0 && latest.IsOriginAPIGroup(kind.Group) {
140+
kind.Group = ""
141+
}
142+
attrs := admission.NewAttributesRecord(
143+
attr.GetObject(),
144+
attr.GetOldObject(),
145+
attr.GetKind(),
146+
attr.GetNamespace(),
147+
attr.GetName(),
148+
resource,
149+
attr.GetSubresource(),
150+
attr.GetOperation(),
151+
attr.GetUserInfo(),
152+
)
153+
return attrs
154+
}
155+
127156
// Admit attempts to apply the image policy to the incoming resource.
128157
func (a *imagePolicyPlugin) Admit(attr admission.Attributes) error {
129158
switch attr.GetOperation() {
@@ -138,27 +167,31 @@ func (a *imagePolicyPlugin) Admit(attr admission.Attributes) error {
138167
return nil
139168
}
140169

141-
gr := attr.GetResource().GroupResource()
170+
newAttr := mutateAttributesToLegacyResources(attr)
171+
172+
// This will convert any non-legacy Origin resource to a legacy resource, so specifying
173+
// a 'builds.build.openshift.io' is converted to 'builds'.
174+
gr := newAttr.GetResource().GroupResource()
142175
if !a.accepter.Covers(gr) {
143176
return nil
144177
}
145178

146-
m, err := meta.GetImageReferenceMutator(attr.GetObject())
179+
m, err := meta.GetImageReferenceMutator(newAttr.GetObject())
147180
if err != nil {
148-
return apierrs.NewForbidden(gr, attr.GetName(), fmt.Errorf("unable to apply image policy against objects of type %T: %v", attr.GetObject(), err))
181+
return apierrs.NewForbidden(gr, newAttr.GetName(), fmt.Errorf("unable to apply image policy against objects of type %T: %v", newAttr.GetObject(), err))
149182
}
150183

151184
// load exclusion rules from the namespace cache
152185
var excluded sets.String
153-
if ns := attr.GetNamespace(); len(ns) > 0 {
186+
if ns := newAttr.GetNamespace(); len(ns) > 0 {
154187
if ns, err := a.projectCache.GetNamespace(ns); err == nil {
155188
if value := ns.Annotations[api.IgnorePolicyRulesAnnotation]; len(value) > 0 {
156189
excluded = sets.NewString(strings.Split(value, ",")...)
157190
}
158191
}
159192
}
160193

161-
if err := accept(a.accepter, a.config.ResolveImages, a.resolver, m, attr, excluded); err != nil {
194+
if err := accept(a.accepter, a.config.ResolveImages, a.resolver, m, newAttr, excluded); err != nil {
162195
return err
163196
}
164197

pkg/image/admission/imagepolicy/imagepolicy_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,42 @@ func TestAdmissionResolveImages(t *testing.T) {
577577
},
578578
},
579579
},
580+
// resolves builds.build.openshift.io with image stream tags, uses the image DockerImageReference with SHA set.
581+
{
582+
client: testclient.NewSimpleFake(
583+
&imageapi.ImageStreamTag{
584+
ObjectMeta: kapi.ObjectMeta{Name: "test:other", Namespace: "default"},
585+
Image: *image1,
586+
},
587+
),
588+
attrs: admission.NewAttributesRecord(
589+
&buildapi.Build{
590+
Spec: buildapi.BuildSpec{
591+
CommonSpec: buildapi.CommonSpec{
592+
Strategy: buildapi.BuildStrategy{
593+
CustomStrategy: &buildapi.CustomBuildStrategy{
594+
From: kapi.ObjectReference{Kind: "ImageStreamTag", Name: "test:other"},
595+
},
596+
},
597+
},
598+
},
599+
}, nil, unversioned.GroupVersionKind{Group: "build.openshift.io", Version: "v1", Kind: "Build"},
600+
"default", "build1", unversioned.GroupVersionResource{Group: "build.openshift.io", Version: "v1", Resource: "builds"},
601+
"", admission.Create, nil,
602+
),
603+
admit: true,
604+
expect: &buildapi.Build{
605+
Spec: buildapi.BuildSpec{
606+
CommonSpec: buildapi.CommonSpec{
607+
Strategy: buildapi.BuildStrategy{
608+
CustomStrategy: &buildapi.CustomBuildStrategy{
609+
From: kapi.ObjectReference{Kind: "DockerImage", Name: "integrated.registry/image1/image1@sha256:0000000000000000000000000000000000000000000000000000000000000001"},
610+
},
611+
},
612+
},
613+
},
614+
},
615+
},
580616
// resolves builds with image stream images
581617
{
582618
client: testclient.NewSimpleFake(

0 commit comments

Comments
 (0)