Skip to content

Commit 0c09073

Browse files
authored
Organization patch: Add label map if not exists (#121)
If the `{"labels":{}}` key is missing from the object sent to the webhook, applying the returned patch failed.
1 parent 0e26c3e commit 0c09073

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

webhooks/namespace_project_organization_mutator.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func (m *NamespaceProjectOrganizationMutator) handleUserRequested(ctx context.Co
137137
}
138138

139139
if defaultOrgAdded {
140-
return admission.Patched("added default organization", m.orgLabelPatch(org))
140+
return admission.Patched("added default organization", m.orgLabelPatch(rawObject, org))
141141
}
142142

143143
return admission.Allowed("Requester is member of organization")
@@ -164,17 +164,26 @@ func (m *NamespaceProjectOrganizationMutator) handleServiceAccountNamespace(ctx
164164
}
165165

166166
if requestedOrg == "" {
167-
return admission.Patched("added organization label", m.orgLabelPatch(nsOrg))
167+
return admission.Patched("added organization label", m.orgLabelPatch(rawObject, nsOrg))
168168
}
169169

170170
return admission.Allowed("service account may use the organization of its namespace")
171171
}
172172

173173
// orgLabelPatch returns a JSON patch operation to add the `OrganizationLabel` with value `org` to an object.
174-
func (m *NamespaceProjectOrganizationMutator) orgLabelPatch(org string) jsonpatch.Operation {
174+
func (m *NamespaceProjectOrganizationMutator) orgLabelPatch(objToPatch unstructured.Unstructured, org string) jsonpatch.Operation {
175+
_, exists, _ := unstructured.NestedStringMap(objToPatch.Object, "metadata", "labels")
176+
if exists {
177+
return jsonpatch.Operation{
178+
Operation: "add",
179+
Path: "/" + strings.Join([]string{"metadata", "labels", escapeJSONPointerSegment(m.OrganizationLabel)}, "/"),
180+
Value: org,
181+
}
182+
}
183+
175184
return jsonpatch.Operation{
176185
Operation: "add",
177-
Path: "/" + strings.Join([]string{"metadata", "labels", escapeJSONPointerSegment(m.OrganizationLabel)}, "/"),
178-
Value: org,
186+
Path: "/metadata/labels",
187+
Value: map[string]string{m.OrganizationLabel: org},
179188
}
180189
}

webhooks/namespace_project_organization_mutator_test.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ func Test_NamespaceProjectOrganizationMutator_Handle(t *testing.T) {
9999
orgPatch: "some-org",
100100
},
101101

102+
{
103+
name: "Namespace: user with default org, no org set on object but other labels exist",
104+
105+
object: newNamespace("project", map[string]string{"foo": "bar"}, nil),
106+
additionalObjects: func(*testing.T) []client.Object {
107+
return []client.Object{
108+
newUser("user", "some-org"),
109+
newGroup("some-org", "user"),
110+
}
111+
},
112+
113+
user: "user",
114+
allowed: true,
115+
orgPatch: "some-org",
116+
},
117+
102118
{
103119
name: "Project: request with org label set, user not in org",
104120

@@ -396,17 +412,23 @@ func Test_NamespaceProjectOrganizationMutator_Handle(t *testing.T) {
396412
require.Equal(t, tc.allowed, resp.Allowed)
397413

398414
if tc.orgPatch != "" {
399-
requireOrgPatch(t, tc.orgPatch, resp.Patches)
415+
requireOrgPatch(t, tc.object, tc.orgPatch, resp.Patches)
400416
} else {
401417
require.Empty(t, resp.Patches)
402418
}
403419
})
404420
}
405421
}
406422

407-
func requireOrgPatch(t *testing.T, org string, ps []jsonpatch.Operation) {
423+
func requireOrgPatch(t *testing.T, origObject client.Object, org string, ps []jsonpatch.Operation) {
424+
t.Helper()
425+
408426
require.Len(t, ps, 1)
409-
require.Equal(t, jsonpatch.NewOperation("add", "/metadata/labels/example.com~1organization", org), ps[0])
427+
if origObject.GetLabels() != nil {
428+
require.Equal(t, jsonpatch.NewOperation("add", "/metadata/labels/example.com~1organization", org), ps[0])
429+
return
430+
}
431+
require.Equal(t, jsonpatch.NewOperation("add", "/metadata/labels", map[string]string{"example.com/organization": org}), ps[0])
410432
}
411433

412434
func newGroup(name string, users ...string) *userv1.Group {

0 commit comments

Comments
 (0)