Skip to content

Commit f78ee94

Browse files
authored
fix: Validate use verb for PodSecurityPolicies (#68)
Resolves: #63 Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>
1 parent 3b55776 commit f78ee94

File tree

2 files changed

+68
-43
lines changed

2 files changed

+68
-43
lines changed

pkg/cmd/resource_resolver.go

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ func (rv *resourceResolver) isVerbSupportedBy(verb string, resource apismeta.API
143143
if verb == rbac.VerbAll {
144144
return true
145145
}
146+
if resource.Name == "podsecuritypolicies" && verb == "use" {
147+
return true
148+
}
146149
supported := false
147150
for _, v := range resource.Verbs {
148151
if v == verb {

pkg/cmd/resource_resolver_test.go

+65-43
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ func TestResourceResolver_Resolve(t *testing.T) {
2828
podsGR := schema.GroupResource{Resource: "pods"}
2929
deploymentsGVR := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "deployments"}
3030
deploymentsGR := schema.GroupResource{Group: "extensions", Resource: "deployments"}
31+
pspGVR := schema.GroupVersionResource{Group: "policy", Version: "v1beta1", Resource: "podsecuritypolicies"}
32+
pspGV := schema.GroupResource{Group: "policy", Resource: "podsecuritypolicies"}
3133

3234
client := fake.NewSimpleClientset()
3335

@@ -47,6 +49,12 @@ func TestResourceResolver_Resolve(t *testing.T) {
4749
{Group: "extensions", Version: "v1beta1", Name: "deployments/scale", Verbs: []string{"update", "patch"}},
4850
},
4951
},
52+
{
53+
GroupVersion: "policy/v1beta1",
54+
APIResources: []apismeta.APIResource{
55+
{Group: "policy", Version: "v1beta1", Name: "podsecuritypolicies", Verbs: []string{"list", "get"}},
56+
},
57+
},
5058
}
5159

5260
type mappingResult struct {
@@ -56,111 +64,125 @@ func TestResourceResolver_Resolve(t *testing.T) {
5664
returnError error
5765
}
5866

59-
type expected struct {
60-
gr schema.GroupResource
61-
err error
62-
}
63-
64-
data := []struct {
65-
scenario string
67+
testCases := []struct {
68+
name string
6669
action Action
6770
mappingResult *mappingResult
68-
expected
71+
expectedGR schema.GroupResource
72+
expectedError error
6973
}{
7074
{
71-
scenario: "A",
72-
action: Action{Verb: "list", Resource: "pods"},
75+
name: "A",
76+
action: Action{Verb: "list", Resource: "pods"},
7377
mappingResult: &mappingResult{
7478
argGVR: schema.GroupVersionResource{Resource: "pods"},
7579
returnGVR: podsGVR,
7680
},
77-
expected: expected{gr: podsGR},
81+
expectedGR: podsGR,
7882
},
7983
{
80-
scenario: "B",
81-
action: Action{Verb: "list", Resource: "po"},
84+
name: "B",
85+
action: Action{Verb: "list", Resource: "po"},
8286
mappingResult: &mappingResult{
8387
argGVR: schema.GroupVersionResource{Resource: "po"},
8488
returnGVR: podsGVR,
8589
},
86-
expected: expected{gr: podsGR},
90+
expectedGR: podsGR,
8791
},
8892
{
89-
scenario: "C",
90-
action: Action{Verb: "eat", Resource: "pods"},
93+
name: "C",
94+
action: Action{Verb: "eat", Resource: "pods"},
9195
mappingResult: &mappingResult{
9296
argGVR: schema.GroupVersionResource{Resource: "pods"},
9397
returnGVR: podsGVR,
9498
},
95-
expected: expected{err: errors.New("the \"pods\" resource does not support the \"eat\" verb, only [list create delete]")},
99+
expectedError: errors.New("the \"pods\" resource does not support the \"eat\" verb, only [list create delete]"),
96100
},
97101
{
98-
scenario: "D",
99-
action: Action{Verb: "list", Resource: "deployments.extensions"},
102+
name: "D",
103+
action: Action{Verb: "list", Resource: "deployments.extensions"},
100104
mappingResult: &mappingResult{
101105
argGVR: schema.GroupVersionResource{Group: "extensions", Version: "", Resource: "deployments"},
102106
returnGVR: deploymentsGVR,
103107
},
104-
expected: expected{gr: deploymentsGR},
108+
expectedGR: deploymentsGR,
105109
},
106110
{
107-
scenario: "E",
108-
action: Action{Verb: "get", Resource: "pods", SubResource: "log"},
111+
name: "E",
112+
action: Action{Verb: "get", Resource: "pods", SubResource: "log"},
109113
mappingResult: &mappingResult{
110114
argGVR: schema.GroupVersionResource{Resource: "pods"},
111115
returnGVR: podsGVR,
112116
},
113-
expected: expected{gr: podsGR},
117+
expectedGR: podsGR,
114118
},
115119
{
116-
scenario: "F",
117-
action: Action{Verb: "get", Resource: "pods", SubResource: "logz"},
120+
name: "F",
121+
action: Action{Verb: "get", Resource: "pods", SubResource: "logz"},
118122
mappingResult: &mappingResult{
119123
argGVR: schema.GroupVersionResource{Resource: "pods"},
120124
returnGVR: podsGVR,
121125
},
122-
expected: expected{err: errors.New("the server doesn't have a resource type \"pods/logz\"")},
126+
expectedError: errors.New("the server doesn't have a resource type \"pods/logz\""),
123127
},
124128
{
125-
scenario: "G",
126-
action: Action{Verb: "list", Resource: "bees"},
129+
name: "G",
130+
action: Action{Verb: "list", Resource: "bees"},
127131
mappingResult: &mappingResult{
128132
argGVR: schema.GroupVersionResource{Resource: "bees"},
129133
returnError: errors.New("mapping failed"),
130134
},
131-
expected: expected{err: errors.New("the server doesn't have a resource type \"bees\"")},
135+
expectedError: errors.New("the server doesn't have a resource type \"bees\""),
132136
},
133137
{
134-
scenario: "H",
135-
action: Action{Verb: rbac.VerbAll, Resource: "pods"},
138+
name: "H",
139+
action: Action{Verb: rbac.VerbAll, Resource: "pods"},
136140
mappingResult: &mappingResult{
137141
argGVR: schema.GroupVersionResource{Resource: "pods"},
138142
returnGVR: podsGVR,
139143
},
140-
expected: expected{gr: podsGR},
144+
expectedGR: podsGR,
145+
},
146+
{
147+
name: "I",
148+
action: Action{Verb: "list", Resource: rbac.ResourceAll},
149+
expectedGR: schema.GroupResource{Resource: rbac.ResourceAll},
150+
},
151+
{
152+
name: "Should resolve psp",
153+
action: Action{Verb: "use", Resource: "psp"},
154+
mappingResult: &mappingResult{
155+
argGVR: schema.GroupVersionResource{Resource: "psp"},
156+
returnGVR: pspGVR,
157+
},
158+
expectedGR: pspGV,
141159
},
142160
{
143-
scenario: "I",
144-
action: Action{Verb: "list", Resource: rbac.ResourceAll},
145-
expected: expected{gr: schema.GroupResource{Resource: rbac.ResourceAll}},
161+
name: "Should return error when psp verb is not supported",
162+
action: Action{Verb: "cook", Resource: "psp"},
163+
mappingResult: &mappingResult{
164+
argGVR: schema.GroupVersionResource{Resource: "psp"},
165+
returnGVR: pspGVR,
166+
},
167+
expectedError: errors.New("the \"podsecuritypolicies\" resource does not support the \"cook\" verb, only [list get]"),
146168
},
147169
}
148170

149-
for _, tt := range data {
150-
t.Run(tt.scenario, func(t *testing.T) {
171+
for _, tc := range testCases {
172+
t.Run(tc.name, func(t *testing.T) {
151173
mapper := new(mapperMock)
152174

153-
if tt.mappingResult != nil {
154-
mapper.On("ResourceFor", tt.mappingResult.argGVR).
155-
Return(tt.mappingResult.returnGVR, tt.mappingResult.returnError)
175+
if tc.mappingResult != nil {
176+
mapper.On("ResourceFor", tc.mappingResult.argGVR).
177+
Return(tc.mappingResult.returnGVR, tc.mappingResult.returnError)
156178
}
157179

158180
resolver := NewResourceResolver(client.Discovery(), mapper)
159181

160-
resource, err := resolver.Resolve(tt.action.Verb, tt.action.Resource, tt.action.SubResource)
182+
resource, err := resolver.Resolve(tc.action.Verb, tc.action.Resource, tc.action.SubResource)
161183

162-
assert.Equal(t, tt.expected.err, err)
163-
assert.Equal(t, tt.expected.gr, resource)
184+
assert.Equal(t, tc.expectedError, err)
185+
assert.Equal(t, tc.expectedGR, resource)
164186

165187
mapper.AssertExpectations(t)
166188
})

0 commit comments

Comments
 (0)