-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support pod exec terminal logging #9385
Changes from 1 commit
74d5150
576831f
1cbef91
a72e178
9d9b01a
530867e
09642e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,6 +113,9 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
return | ||
} | ||
|
||
fieldLog := log.WithFields(log.Fields{"userName": sessionmgr.Username(ctx), "container": container, | ||
"podName": podName, "namespace": namespace, "cluster": a.Spec.Destination.Name}) | ||
|
||
appRBACName := apputil.AppRBACName(*a) | ||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName); err != nil { | ||
http.Error(w, err.Error(), http.StatusUnauthorized) | ||
|
@@ -150,7 +153,8 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
|
||
pod, err := kubeClientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) | ||
if err != nil { | ||
http.Error(w, "Cannot find pod: "+podName, http.StatusBadRequest) | ||
fieldLog.Warn("Terminal Pod Not Found") | ||
http.Error(w, "Cannot find pod", http.StatusBadRequest) | ||
return | ||
} | ||
|
||
|
@@ -159,20 +163,20 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
return | ||
} | ||
|
||
var foundContainerName string | ||
var findContainer bool | ||
for _, c := range pod.Spec.Containers { | ||
if container == c.Name { | ||
foundContainerName = c.Name | ||
findContainer = true | ||
break | ||
} | ||
} | ||
if foundContainerName == "" { | ||
http.Error(w, "Cannot find container: "+container, http.StatusBadRequest) | ||
if !findContainer { | ||
fieldLog.Warn("Terminal Container Not Found") | ||
http.Error(w, "Cannot find container", http.StatusBadRequest) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For auditing it would be interesting to also have this logged (as a warning) with all info: cluster, namespace, pod name and container name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CodeQL might complain about logging the un-sanitized There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @leoluz - yes this is the issue we were trying to avoid - There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@smcavallo but you are previously sanitizing isn't it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sanitizing, but validating. Which I think should be enough. If we're reaching this point of the code, then we've shown the user is authenticated and authorized to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @leoluz and @crenshaw-dev - totally make sense - we've already validated so it's OK to log these. I have added the additional info to these logs. |
||
return | ||
} | ||
|
||
log.WithFields(log.Fields{"userName": sessionmgr.Username(ctx), "container": foundContainerName, | ||
"podName": pod.Name, "namespace": pod.Namespace, "cluster": a.Spec.Destination.Name}).Info("Serving Terminal") | ||
fieldLog.Info("Serving Terminal") | ||
|
||
session, err := newTerminalSession(w, r, nil) | ||
if err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an error and should be logged like so:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leoluz - thank you for checking again - we are already logging the podName. when
fieldLog
is called it will output ALL the fields (user, namespace, pod, container) to the log line. since it is usingWithFields
-I defer to all the argocd folks but the distinction here which is important is user error vs application error.
It makes sense that this throws an http error to the user.
However it is not actually an application error - the application is performing normally.
From my perspective it would be better to be
Warn
instead ofError
for application log level.As an operator I would want to know that this is happening (
Warn
) but I would not consider this an indicator that argocd is unhealthy, having an issue, or doing something broken or unexpected.Let me know if I should change it or if the above doesn't make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with the fact that we don't need the pod name as it is already part of registered fields. However I believe this still needs to be logged as an error. It is ArgoCD internal code that does the call to kube-api to retrieve the pod by its name. If this request fails for some reason it is an internal error and should be logged like so. Retrieving the pod call can fail by several reasons and logging it as
terminal pod not found
is misleading.I suggest to change this log to:
By the way, log messages should be all lowercase sentences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leoluz what if a Pod is in the resource tree but not synced? In that case an error from the k8s API would be a user error rather than an application error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leoluz - good point - I have updated it and also changed the log messages to all lowercase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@crenshaw-dev My understanding is that (contrary to HTTP return codes) from the log perspective, it doesn't matter if the error was caused by the user or by something internal. Our code invoked a method that returned an error and in this case an error should be logged. However there is another "subtle" problem in this case: client-go returns an error if for example the resource isn't found. This isn't an exceptional scenario and if we want to be precise to whether or not log an error (and decide the proper http return code) we need to do an extra check: