From d45f1a45c7bf3efa7121718aa24b0723cecb5575 Mon Sep 17 00:00:00 2001 From: Alvaro Aleman Date: Sat, 27 Feb 2021 13:46:21 -0500 Subject: [PATCH] Prow: Set proper user-agent in config The default user-agentis $0/$version, which is pretty useless because it always ends up being app.binary/$version. This PR changes that instead be the components name which is useful for: * Audit log: We can now both use the user-agent or SA to identify components * ManagedFields: Managed fields now have the correct fieldOwner set This allows for example the use of `kubectl-blame`: ``` $ k blame prowjob ebb68c01-792b-11eb-a360-96cd908b0bc6 apiVersion: prow.k8s.io/v1 kind: ProwJob metadata: horologium (Update 2021-02-27 13:45:11 -0500) annotations: horologium (Update 2021-02-27 13:45:11 -0500) prow.k8s.io/job: echo-test creationTimestamp: "2021-02-27T18:45:11Z" generation: 4 horologium (Update 2021-02-27 13:45:11 -0500) labels: horologium (Update 2021-02-27 13:45:11 -0500) created-by-prow: "true" app.binary (Update 2021-02-27 13:45:11 -0500) prow.k8s.io/build-id: "1365734741038338048" app.binary (Update 2021-02-27 13:45:11 -0500) prow.k8s.io/id: ebb68c01-792b-11eb-a360-96cd908b0bc6 horologium (Update 2021-02-27 13:45:11 -0500) prow.k8s.io/job: echo-test horologium (Update 2021-02-27 13:45:11 -0500) prow.k8s.io/type: periodic name: ebb68c01-792b-11eb-a360-96cd908b0bc6 namespace: prow resourceVersion: "144661945" uid: 63f44066-411e-4ff3-9ab4-97ddb2ce636d horologium (Update 2021-02-27 13:45:11 -0500) spec: horologium (Update 2021-02-27 13:45:11 -0500) agent: kubernetes horologium (Update 2021-02-27 13:45:11 -0500) cluster: default horologium (Update 2021-02-27 13:45:11 -0500) decoration_config: horologium (Update 2021-02-27 13:45:11 -0500) gcs_configuration: horologium (Update 2021-02-27 13:45:11 -0500) bucket: s3://prow-logs horologium (Update 2021-02-27 13:45:11 -0500) path_strategy: explicit horologium (Update 2021-02-27 13:45:11 -0500) s3_credentials_secret: s3-credentials horologium (Update 2021-02-27 13:45:11 -0500) utility_images: horologium (Update 2021-02-27 13:45:11 -0500) clonerefs: gcr.io/k8s-prow/clonerefs:v20200608-16190316cf horologium (Update 2021-02-27 13:45:11 -0500) entrypoint: gcr.io/k8s-prow/entrypoint:v20200608-16190316cf horologium (Update 2021-02-27 13:45:11 -0500) initupload: gcr.io/k8s-prow/initupload:v20200608-16190316cf horologium (Update 2021-02-27 13:45:11 -0500) sidecar: gcr.io/k8s-prow/sidecar:v20200608-16190316cf horologium (Update 2021-02-27 13:45:11 -0500) job: echo-test horologium (Update 2021-02-27 13:45:11 -0500) namespace: test-pods horologium (Update 2021-02-27 13:45:11 -0500) pod_spec: horologium (Update 2021-02-27 13:45:11 -0500) containers: horologium (Update 2021-02-27 13:45:11 -0500) - command: horologium (Update 2021-02-27 13:45:11 -0500) - /bin/sleep horologium (Update 2021-02-27 13:45:11 -0500) - 1m horologium (Update 2021-02-27 13:45:11 -0500) image: alpine horologium (Update 2021-02-27 13:45:11 -0500) name: "" horologium (Update 2021-02-27 13:45:11 -0500) resources: {} horologium (Update 2021-02-27 13:45:11 -0500) report: true horologium (Update 2021-02-27 13:45:11 -0500) type: periodic horologium (Update 2021-02-27 13:45:11 -0500) status: app.binary (Update 2021-02-27 13:45:11 -0500) build_id: "1365734741038338048" app.binary (Update 2021-02-27 13:45:11 -0500) description: Job triggered. app.binary (Update 2021-02-27 13:45:11 -0500) pendingTime: "2021-02-27T18:45:11Z" app.binary (Update 2021-02-27 13:45:11 -0500) pod_name: ebb68c01-792b-11eb-a360-96cd908b0bc6 app.binary (Update 2021-02-27 13:45:11 -0500) prev_report_states: app.binary (Update 2021-02-27 13:45:11 -0500) gcsk8sreporter: pending app.binary (Update 2021-02-27 13:45:11 -0500) gcsreporter: pending horologium (Update 2021-02-27 13:45:11 -0500) startTime: "2021-02-27T18:45:11Z" app.binary (Update 2021-02-27 13:45:11 -0500) state: pending app.binary (Update 2021-02-27 13:45:11 -0500) url: https://prow.tld/view/s3/s3/prow-logs/logs/echo-test/1365734741038338048 ``` Note: Due to a bug in controller-runtime, this doesn't work for a client that comes from a Manager that has leader election enabled, like planks prowjob client above: https://github.com/kubernetes-sigs/controller-runtime/pull/1401 I will bump the dependency ASAP once the upstream fix is in. --- prow/kube/BUILD.bazel | 1 + prow/kube/config.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/prow/kube/BUILD.bazel b/prow/kube/BUILD.bazel index 48e218baebd1..4e0fcf7d6a67 100644 --- a/prow/kube/BUILD.bazel +++ b/prow/kube/BUILD.bazel @@ -40,6 +40,7 @@ go_library( "//prow/apis/prowjobs/v1:go_default_library", "//prow/client/clientset/versioned:go_default_library", "//prow/client/clientset/versioned/typed/prowjobs/v1:go_default_library", + "//prow/version:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@io_k8s_api//core/v1:go_default_library", diff --git a/prow/kube/config.go b/prow/kube/config.go index f8c38e35fb59..282bf271ad33 100644 --- a/prow/kube/config.go +++ b/prow/kube/config.go @@ -23,6 +23,8 @@ import ( "github.com/sirupsen/logrus" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + + "k8s.io/test-infra/prow/version" ) func kubeConfigs(kubeconfig string) (map[string]rest.Config, string, error) { @@ -48,6 +50,8 @@ func kubeConfigs(kubeconfig string) (map[string]rest.Config, string, error) { if err != nil { return nil, "", fmt.Errorf("create %s client: %v", context, err) } + // This ends up being used for the managed fields owner name, so do not include the version here + contextCfg.UserAgent = version.UserAgent() configs[context] = *contextCfg logrus.Infof("Parsed kubeconfig context: %s", context) } @@ -86,6 +90,8 @@ func LoadClusterConfigs(kubeconfig, projectedTokenFile string) (map[string]rest. localCfg, err := rest.InClusterConfig() if err != nil { logrus.WithError(err).Warn("Could not create in-cluster config (expected when running outside the cluster).") + } else { + localCfg.UserAgent = version.UserAgent() } if localCfg != nil && projectedTokenFile != "" { localCfg.BearerToken = ""