Skip to content

Commit 010b3fa

Browse files
author
Jim Minter
committed
fix templateinstance update test logic
1 parent 5748c60 commit 010b3fa

File tree

1 file changed

+108
-36
lines changed

1 file changed

+108
-36
lines changed

test/extended/templates/templateinstance_impersonation.go

+108-36
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import (
66

77
kerrors "k8s.io/apimachinery/pkg/api/errors"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/apimachinery/pkg/runtime"
910
"k8s.io/apimachinery/pkg/util/sets"
1011
kapi "k8s.io/kubernetes/pkg/api"
12+
"k8s.io/kubernetes/pkg/client/retry"
1113

1214
authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
1315
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
@@ -34,10 +36,17 @@ var _ = g.Describe("[templates] templateinstance impersonation tests", func() {
3436

3537
dummytemplateinstance *templateapi.TemplateInstance
3638

39+
dummycondition = templateapi.TemplateInstanceCondition{
40+
Type: templateapi.TemplateInstanceConditionType("dummy"),
41+
Status: kapi.ConditionTrue,
42+
}
43+
3744
tests []struct {
3845
user *userapi.User
39-
expectCreateUpdateSuccess bool
46+
expectCreateSuccess bool
4047
expectDeleteSuccess bool
48+
hasUpdatePermission bool
49+
hasUpdateStatusPermission bool
4150
}
4251
)
4352

@@ -60,6 +69,7 @@ var _ = g.Describe("[templates] templateinstance impersonation tests", func() {
6069
Name: "template",
6170
Namespace: "dummy",
6271
},
72+
Objects: []runtime.Object{},
6373
},
6474
// all the tests work with a templateinstance which is set up to
6575
// impersonate edituser1
@@ -71,38 +81,52 @@ var _ = g.Describe("[templates] templateinstance impersonation tests", func() {
7181

7282
tests = []struct {
7383
user *userapi.User
74-
expectCreateUpdateSuccess bool
84+
expectCreateSuccess bool
7585
expectDeleteSuccess bool
86+
hasUpdatePermission bool
87+
hasUpdateStatusPermission bool
7688
}{
7789
{
78-
user: nil, // system-admin
79-
expectCreateUpdateSuccess: true, // can impersonate anyone
90+
user: nil, // system-admin
91+
expectCreateSuccess: true, // can impersonate anyone
8092
expectDeleteSuccess: true,
93+
hasUpdatePermission: true,
94+
hasUpdateStatusPermission: true,
8195
},
8296
{
83-
user: adminuser,
84-
expectCreateUpdateSuccess: false, // cannot impersonate edituser1
97+
user: adminuser,
98+
expectCreateSuccess: false, // cannot impersonate edituser1
8599
expectDeleteSuccess: true,
100+
hasUpdatePermission: true,
101+
hasUpdateStatusPermission: false,
86102
},
87103
{
88-
user: impersonateuser,
89-
expectCreateUpdateSuccess: true, // can impersonate edituser1
104+
user: impersonateuser,
105+
expectCreateSuccess: true, // can impersonate edituser1
90106
expectDeleteSuccess: true,
107+
hasUpdatePermission: true,
108+
hasUpdateStatusPermission: false,
91109
},
92110
{
93-
user: edituser1,
94-
expectCreateUpdateSuccess: true, // is edituser1
111+
user: edituser1,
112+
expectCreateSuccess: true, // is edituser1
95113
expectDeleteSuccess: true,
114+
hasUpdatePermission: true,
115+
hasUpdateStatusPermission: false,
96116
},
97117
{
98-
user: edituser2,
99-
expectCreateUpdateSuccess: false, // cannot impersonate edituser1
118+
user: edituser2,
119+
expectCreateSuccess: false, // cannot impersonate edituser1
100120
expectDeleteSuccess: true,
121+
hasUpdatePermission: true,
122+
hasUpdateStatusPermission: false,
101123
},
102124
{
103-
user: viewuser,
104-
expectCreateUpdateSuccess: false, // cannot create things and cannot impersonate edituser1
125+
user: viewuser,
126+
expectCreateSuccess: false, // cannot create things and cannot impersonate edituser1
105127
expectDeleteSuccess: false,
128+
hasUpdatePermission: false,
129+
hasUpdateStatusPermission: false,
106130
},
107131
}
108132

@@ -168,7 +192,7 @@ var _ = g.Describe("[templates] templateinstance impersonation tests", func() {
168192
o.Expect(err).NotTo(o.HaveOccurred())
169193
templateinstance, err := cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Create(templateinstancecopy.(*templateapi.TemplateInstance))
170194

171-
if !test.expectCreateUpdateSuccess {
195+
if !test.expectCreateSuccess {
172196
o.Expect(err).To(o.HaveOccurred())
173197
o.Expect(kerrors.IsInvalid(err) || kerrors.IsForbidden(err)).To(o.BeTrue())
174198
} else {
@@ -181,39 +205,87 @@ var _ = g.Describe("[templates] templateinstance impersonation tests", func() {
181205
})
182206

183207
g.It("should pass impersonation update tests", func() {
184-
// check who can update TemplateInstances (anyone with project write access
185-
// AND is/can impersonate spec.requester.username)
208+
// check who can update TemplateInstances. Via Update(), spec updates
209+
// should be rejected (with the exception of spec.metadata fields used
210+
// by the garbage collector, not tested here). Status updates should be
211+
// silently ignored. Via UpdateStatus(), spec updates should be
212+
// silently ignored. Status should only be updatable by a user with
213+
// update access to that endpoint. In practice this is intended only to
214+
// be the templateinstance controller and system:admin.
186215
for _, test := range tests {
216+
var templateinstancecopy *templateapi.TemplateInstance
187217
setUser(cli, test.user)
188218

189-
templateinstancecopy, err := kapi.Scheme.DeepCopy(dummytemplateinstance)
190-
o.Expect(err).NotTo(o.HaveOccurred())
191-
templateinstance, err := cli.AdminTemplateClient().Template().TemplateInstances(cli.Namespace()).Create(templateinstancecopy.(*templateapi.TemplateInstance))
219+
templateinstance, err := cli.AdminTemplateClient().Template().TemplateInstances(cli.Namespace()).Create(dummytemplateinstance)
192220
o.Expect(err).NotTo(o.HaveOccurred())
193221

194-
var newtemplateinstance *templateapi.TemplateInstance
195-
for try := 0; try < 3; try++ {
196-
newtemplateinstance, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Update(templateinstance)
197-
if kerrors.IsConflict(err) {
198-
templateinstance, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Get(templateinstance.Name, metav1.GetOptions{})
199-
o.Expect(err).NotTo(o.HaveOccurred())
200-
} else {
201-
break
202-
}
222+
// ensure spec (particularly including spec.requester.username) is
223+
// immutable via Update()
224+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
225+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Get(templateinstance.Name, metav1.GetOptions{})
226+
o.Expect(err).NotTo(o.HaveOccurred())
227+
228+
templateinstancecopy.Spec.Requester.Username = edituser2.Name
229+
230+
_, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Update(templateinstancecopy)
231+
return err
232+
})
233+
o.Expect(err).To(o.HaveOccurred())
234+
o.Expect(kerrors.IsInvalid(err) || kerrors.IsForbidden(err)).To(o.BeTrue())
235+
236+
// ensure status changes are ignored via Update()
237+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
238+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Get(templateinstance.Name, metav1.GetOptions{})
239+
o.Expect(err).NotTo(o.HaveOccurred())
240+
241+
templateinstancecopy.Status.Conditions = append(templateinstancecopy.Status.Conditions, dummycondition)
242+
243+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Update(templateinstancecopy)
244+
return err
245+
})
246+
if !test.hasUpdatePermission {
247+
o.Expect(err).To(o.HaveOccurred())
248+
o.Expect(kerrors.IsInvalid(err) || kerrors.IsForbidden(err)).To(o.BeTrue())
249+
} else {
250+
o.Expect(err).NotTo(o.HaveOccurred())
251+
o.Expect(templateinstancecopy.Status.Conditions).NotTo(o.ContainElement(dummycondition))
203252
}
204-
if !test.expectCreateUpdateSuccess {
253+
254+
// ensure spec changes are ignored via UpdateStatus()
255+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
256+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Get(templateinstance.Name, metav1.GetOptions{})
257+
o.Expect(err).NotTo(o.HaveOccurred())
258+
259+
templateinstancecopy.Spec.Requester.Username = edituser2.Name
260+
261+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).UpdateStatus(templateinstancecopy)
262+
return err
263+
})
264+
if !test.hasUpdateStatusPermission {
205265
o.Expect(err).To(o.HaveOccurred())
206266
o.Expect(kerrors.IsInvalid(err) || kerrors.IsForbidden(err)).To(o.BeTrue())
207267
} else {
208268
o.Expect(err).NotTo(o.HaveOccurred())
209-
templateinstance = newtemplateinstance
269+
o.Expect(templateinstancecopy.Spec).To(o.Equal(dummytemplateinstance.Spec))
210270
}
211271

212-
// ensure spec (particularly including spec.requester.username) is
213-
// immutable
214-
templateinstance.Spec.Requester.Username = edituser2.Name
215-
_, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Update(templateinstance)
216-
o.Expect(err).To(o.HaveOccurred())
272+
// ensure status changes are allowed via UpdateStatus()
273+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
274+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).Get(templateinstance.Name, metav1.GetOptions{})
275+
o.Expect(err).NotTo(o.HaveOccurred())
276+
277+
templateinstancecopy.Status.Conditions = []templateapi.TemplateInstanceCondition{dummycondition}
278+
279+
templateinstancecopy, err = cli.TemplateClient().Template().TemplateInstances(cli.Namespace()).UpdateStatus(templateinstancecopy)
280+
return err
281+
})
282+
if !test.hasUpdateStatusPermission {
283+
o.Expect(err).To(o.HaveOccurred())
284+
o.Expect(kerrors.IsInvalid(err) || kerrors.IsForbidden(err)).To(o.BeTrue())
285+
} else {
286+
o.Expect(err).NotTo(o.HaveOccurred())
287+
o.Expect(templateinstancecopy.Status.Conditions).To(o.ContainElement(dummycondition))
288+
}
217289

218290
err = cli.AdminTemplateClient().Template().TemplateInstances(cli.Namespace()).Delete(templateinstance.Name, nil)
219291
o.Expect(err).NotTo(o.HaveOccurred())

0 commit comments

Comments
 (0)