Skip to content

Commit

Permalink
Set user info annotations
Browse files Browse the repository at this point in the history
Signed-off-by: Pierangelo Di Pilato <[email protected]>
  • Loading branch information
pierDipi committed Dec 6, 2021
1 parent 500de57 commit 0bb0dbb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
10 changes: 7 additions & 3 deletions webhook/resourcesemantics/defaulting/defaulting.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (ac *reconciler) mutate(ctx context.Context, req *admissionv1.AdmissionRequ
logger.Error("Unhandled kind: ", gvk)
return nil, fmt.Errorf("unhandled kind: %v", gvk)
}
patches, err := ac.callback(ctx, gvk, req, duck.JSONPatch{})
patches, err := ac.callback(ctx, gvk, req, true /* shouldSetUserInfo */, duck.JSONPatch{})
if err != nil {
logger.Errorw("Failed the callback defaulter", zap.Error(err))
// Return the error message as-is to give the defaulter callback
Expand Down Expand Up @@ -346,7 +346,7 @@ func (ac *reconciler) mutate(ctx context.Context, req *admissionv1.AdmissionRequ
return nil, err
}

if patches, err = ac.callback(ctx, gvk, req, patches); err != nil {
if patches, err = ac.callback(ctx, gvk, req, false /* shouldSetUserInfo */, patches); err != nil {
logger.Errorw("Failed the callback defaulter", zap.Error(err))
// Return the error message as-is to give the defaulter callback
// discretion over (our portion of) the message that the user sees.
Expand Down Expand Up @@ -380,7 +380,7 @@ func (ac *reconciler) setUserInfoAnnotations(ctx context.Context, patches duck.J
return append(patches, patch...), nil
}

func (ac *reconciler) callback(ctx context.Context, gvk schema.GroupVersionKind, req *admissionv1.AdmissionRequest, patches duck.JSONPatch) (duck.JSONPatch, error) {
func (ac *reconciler) callback(ctx context.Context, gvk schema.GroupVersionKind, req *admissionv1.AdmissionRequest, shouldSetUserInfo bool, patches duck.JSONPatch) (duck.JSONPatch, error) {
// Get callback.
callback, ok := ac.callbacks[gvk]
if !ok {
Expand Down Expand Up @@ -422,6 +422,10 @@ func (ac *reconciler) callback(ctx context.Context, gvk schema.GroupVersionKind,
return patches, err
}

if shouldSetUserInfo {
setUserInfoAnnotationsUnstructured(ctx, after, before, req)
}

// Create patches.
patch, err := duck.CreatePatch(before.Object, after.Object)
return append(patches, patch...), err
Expand Down
12 changes: 12 additions & 0 deletions webhook/resourcesemantics/defaulting/defaulting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,14 @@ func TestAdmitCreates(t *testing.T) {
Operation: "add",
Path: "/spec/FieldForCallbackDefaultingUsername",
Value: user1,
}, {
Operation: "replace",
Path: "/metadata/annotations/pkg.knative.dev~1lastModifier",
Value: user1,
}, {
Operation: "add",
Path: "/metadata/annotations/pkg.knative.dev~1creator",
Value: user1,
}},
}}

Expand Down Expand Up @@ -630,6 +638,10 @@ func TestAdmitUpdatesCallback(t *testing.T) {
return req
},
patches: []jsonpatch.JsonPatchOperation{{
Operation: "replace",
Path: "/metadata/annotations/pkg.knative.dev~1lastModifier",
Value: user2,
}, {
Operation: "replace",
Path: "/spec/fieldDefaultingCallback",
Value: "I'm a default",
Expand Down
28 changes: 28 additions & 0 deletions webhook/resourcesemantics/defaulting/user_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ package defaulting
import (
"context"

admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"knative.dev/pkg/apis"
)

Expand Down Expand Up @@ -50,3 +53,28 @@ func setUserInfoAnnotations(ctx context.Context, resource apis.HasSpec, groupNam
}
}
}

// setUserInfoAnnotationsUnstructured sets creator and updater annotations on a resource.
func setUserInfoAnnotationsUnstructured(ctx context.Context, after *unstructured.Unstructured, before *unstructured.Unstructured, req *admissionv1.AdmissionRequest) {
if v, ok := after.Object["metadata"]; ok {
if metadata, ok := v.(map[string]interface{}); ok {
if v, ok := metadata["annotations"]; ok {
if annotations, ok := v.(map[string]interface{}); ok {
if apis.IsInUpdate(ctx) {

if equality.Semantic.DeepEqual(before.UnstructuredContent(), after.UnstructuredContent()) {
return
}

annotations[req.Resource.Group+apis.UpdaterAnnotationSuffix] = req.UserInfo.Username
return
}

annotations[req.Resource.Group+apis.CreatorAnnotationSuffix] = req.UserInfo.Username
annotations[req.Resource.Group+apis.UpdaterAnnotationSuffix] = req.UserInfo.Username
}
}

}
}
}

0 comments on commit 0bb0dbb

Please sign in to comment.