Skip to content

Commit 212bf90

Browse files
authored
Add userID to log messages (#4202)
* Add userID to log messages * Remove confusing comment in userID log tests
1 parent d0e9668 commit 212bf90

File tree

7 files changed

+245
-5
lines changed

7 files changed

+245
-5
lines changed

integrationtests/controller/bundle/suite_test.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package bundle
22

33
import (
4+
"bytes"
45
"context"
56
"testing"
67
"time"
@@ -19,16 +20,19 @@ import (
1920

2021
"k8s.io/client-go/rest"
2122

23+
ctrl "sigs.k8s.io/controller-runtime"
2224
"sigs.k8s.io/controller-runtime/pkg/client"
2325
"sigs.k8s.io/controller-runtime/pkg/envtest"
26+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
2427
)
2528

2629
var (
27-
cancel context.CancelFunc
28-
cfg *rest.Config
29-
ctx context.Context
30-
k8sClient client.Client
31-
testenv *envtest.Environment
30+
cancel context.CancelFunc
31+
cfg *rest.Config
32+
ctx context.Context
33+
k8sClient client.Client
34+
testenv *envtest.Environment
35+
logsBuffer bytes.Buffer
3236

3337
namespace string
3438
)
@@ -49,6 +53,10 @@ var _ = BeforeSuite(func() {
4953
cfg, err = utils.StartTestEnv(testenv)
5054
Expect(err).NotTo(HaveOccurred())
5155

56+
// Set up log capture
57+
GinkgoWriter.TeeTo(&logsBuffer)
58+
ctrl.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
59+
5260
k8sClient, err = utils.NewClient(cfg)
5361
Expect(err).NotTo(HaveOccurred())
5462

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package bundle
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
7+
"github.com/rancher/fleet/integrationtests/utils"
8+
"github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
9+
10+
corev1 "k8s.io/api/core/v1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"sigs.k8s.io/controller-runtime/pkg/client"
13+
)
14+
15+
var _ = Describe("Bundle UserID logging", func() {
16+
var (
17+
bundle *v1alpha1.Bundle
18+
cluster *v1alpha1.Cluster
19+
namespace string
20+
)
21+
22+
createBundle := func(name, clusterName string, labels map[string]string) {
23+
bundle = &v1alpha1.Bundle{
24+
ObjectMeta: metav1.ObjectMeta{
25+
Name: name,
26+
Namespace: namespace,
27+
Labels: labels,
28+
},
29+
Spec: v1alpha1.BundleSpec{
30+
BundleDeploymentOptions: v1alpha1.BundleDeploymentOptions{
31+
DefaultNamespace: "default",
32+
},
33+
Targets: []v1alpha1.BundleTarget{
34+
{
35+
Name: clusterName,
36+
ClusterName: clusterName,
37+
},
38+
},
39+
Resources: []v1alpha1.BundleResource{
40+
{
41+
Name: "test-configmap.yaml",
42+
Content: "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: test-cm\ndata:\n key: value\n",
43+
},
44+
},
45+
},
46+
}
47+
Expect(k8sClient.Create(ctx, bundle)).ToNot(HaveOccurred())
48+
}
49+
50+
BeforeEach(func() {
51+
var err error
52+
namespace, err = utils.NewNamespaceName()
53+
Expect(err).ToNot(HaveOccurred())
54+
ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
55+
Expect(k8sClient.Create(ctx, ns)).ToNot(HaveOccurred())
56+
57+
logsBuffer.Reset()
58+
59+
DeferCleanup(func() {
60+
Expect(k8sClient.Delete(ctx, bundle)).ToNot(HaveOccurred())
61+
Expect(k8sClient.Delete(ctx, cluster)).ToNot(HaveOccurred())
62+
Expect(k8sClient.Delete(ctx, ns)).ToNot(HaveOccurred())
63+
})
64+
})
65+
66+
waitForReconciliation := func() {
67+
Eventually(func() int64 {
68+
err := k8sClient.Get(ctx, client.ObjectKey{Namespace: bundle.Namespace, Name: bundle.Name}, bundle)
69+
if err != nil {
70+
return 0
71+
}
72+
return bundle.Status.ObservedGeneration
73+
}).Should(BeNumerically(">", 0))
74+
75+
Eventually(func() string {
76+
return logsBuffer.String()
77+
}).Should(ContainSubstring(bundle.Name))
78+
}
79+
80+
When("Bundle has user ID label", func() {
81+
const userID = "user-12345"
82+
83+
BeforeEach(func() {
84+
var err error
85+
cluster, err = utils.CreateCluster(ctx, k8sClient, "test-cluster", namespace, nil, namespace)
86+
Expect(err).NotTo(HaveOccurred())
87+
88+
createBundle("test-bundle-with-userid", "test-cluster", map[string]string{
89+
v1alpha1.CreatedByUserIDLabel: userID,
90+
})
91+
})
92+
93+
It("includes userID in log output", func() {
94+
waitForReconciliation()
95+
96+
logs := logsBuffer.String()
97+
Expect(logs).To(Or(
98+
ContainSubstring(`"userID":"`+userID+`"`),
99+
ContainSubstring(`"userID": "`+userID+`"`),
100+
))
101+
102+
Expect(logs).To(ContainSubstring("bundle"))
103+
Expect(logs).To(ContainSubstring(bundle.Name))
104+
})
105+
})
106+
107+
When("Bundle does not have user ID label", func() {
108+
BeforeEach(func() {
109+
var err error
110+
cluster, err = utils.CreateCluster(ctx, k8sClient, "test-cluster-2", namespace, nil, namespace)
111+
Expect(err).NotTo(HaveOccurred())
112+
113+
createBundle("test-bundle-without-userid", "test-cluster-2", nil)
114+
})
115+
116+
It("does not include userID in log output", func() {
117+
waitForReconciliation()
118+
119+
logs := logsBuffer.String()
120+
bundleLogs := utils.ExtractResourceLogs(logs, bundle.Name)
121+
Expect(bundleLogs).NotTo(ContainSubstring(`"userID"`))
122+
})
123+
})
124+
})
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package controller
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
7+
"github.com/rancher/fleet/integrationtests/utils"
8+
fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
9+
corev1 "k8s.io/api/core/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
)
12+
13+
var _ = Describe("GitRepo UserID logging", func() {
14+
var (
15+
gitrepo *fleet.GitRepo
16+
namespace string
17+
)
18+
19+
createGitRepo := func(name string, labels map[string]string) {
20+
gitrepo = &fleet.GitRepo{
21+
ObjectMeta: metav1.ObjectMeta{
22+
Name: name,
23+
Namespace: namespace,
24+
Labels: labels,
25+
},
26+
Spec: fleet.GitRepoSpec{
27+
Repo: "https://github.com/rancher/fleet-test-data/single-path",
28+
},
29+
}
30+
Expect(k8sClient.Create(ctx, gitrepo)).ToNot(HaveOccurred())
31+
}
32+
33+
BeforeEach(func() {
34+
var err error
35+
namespace, err = utils.NewNamespaceName()
36+
Expect(err).ToNot(HaveOccurred())
37+
ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
38+
Expect(k8sClient.Create(ctx, ns)).ToNot(HaveOccurred())
39+
40+
logsBuffer.Reset()
41+
42+
DeferCleanup(func() {
43+
Expect(k8sClient.Delete(ctx, gitrepo)).ToNot(HaveOccurred())
44+
Expect(k8sClient.Delete(ctx, ns)).ToNot(HaveOccurred())
45+
})
46+
})
47+
48+
When("GitRepo has user ID label", func() {
49+
const userID = "user-12345"
50+
51+
BeforeEach(func() {
52+
createGitRepo("test-gitrepo-with-userid", map[string]string{
53+
fleet.CreatedByUserIDLabel: userID,
54+
})
55+
})
56+
57+
It("includes userID in log output", func() {
58+
Eventually(func() string {
59+
return logsBuffer.String()
60+
}, timeout).Should(Or(
61+
ContainSubstring(`"userID":"`+userID+`"`),
62+
ContainSubstring(`"userID": "`+userID+`"`),
63+
))
64+
65+
logs := logsBuffer.String()
66+
Expect(logs).To(ContainSubstring("gitjob"))
67+
Expect(logs).To(ContainSubstring(gitrepo.Name))
68+
})
69+
})
70+
71+
When("GitRepo does not have user ID label", func() {
72+
BeforeEach(func() {
73+
createGitRepo("test-gitrepo-without-userid", nil)
74+
})
75+
76+
It("does not include userID in log output", func() {
77+
Eventually(func() string {
78+
return logsBuffer.String()
79+
}, timeout).Should(ContainSubstring(gitrepo.Name))
80+
81+
logs := logsBuffer.String()
82+
gitrepoLogs := utils.ExtractResourceLogs(logs, gitrepo.Name)
83+
Expect(gitrepoLogs).NotTo(ContainSubstring(`"userID"`))
84+
})
85+
})
86+
})

integrationtests/utils/helpers.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package utils
22

33
import (
44
"context"
5+
"strings"
56

67
"github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
78

@@ -51,3 +52,14 @@ func CreateCluster(ctx context.Context, k8sClient client.Client, name, controlle
5152
err = k8sClient.Status().Update(ctx, cluster)
5253
return cluster, err
5354
}
55+
56+
// ExtractResourceLogs extracts log lines related to a specific resource name
57+
func ExtractResourceLogs(allLogs, resourceName string) string {
58+
var resourceLogs []string
59+
for _, line := range strings.Split(allLogs, "\n") {
60+
if strings.Contains(line, resourceName) {
61+
resourceLogs = append(resourceLogs, line)
62+
}
63+
}
64+
return strings.Join(resourceLogs, "\n")
65+
}

internal/cmd/controller/gitops/reconciler/gitjob_controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ func (r *GitJobReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
199199
}
200200

201201
logger = logger.WithValues("generation", gitrepo.Generation, "commit", gitrepo.Status.Commit).WithValues("conditions", gitrepo.Status.Conditions)
202+
203+
if userID := gitrepo.Labels[v1alpha1.CreatedByUserIDLabel]; userID != "" {
204+
logger = logger.WithValues("userID", userID)
205+
}
206+
202207
ctx = log.IntoContext(ctx, logger)
203208

204209
logger.V(1).Info("Reconciling GitRepo")

internal/cmd/controller/reconciler/bundle_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ func (r *BundleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
220220
)
221221
}
222222

223+
if userID := bundle.Labels[fleet.CreatedByUserIDLabel]; userID != "" {
224+
logger = logger.WithValues("userID", userID)
225+
}
226+
223227
if !bundle.DeletionTimestamp.IsZero() {
224228
return r.handleDelete(ctx, logger, req, bundle)
225229
}

pkg/apis/fleet.cattle.io/v1alpha1/gitrepo_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var (
1313
RepoLabel = "fleet.cattle.io/repo-name"
1414
BundleLabel = "fleet.cattle.io/bundle-name"
1515
BundleNamespaceLabel = "fleet.cattle.io/bundle-namespace"
16+
CreatedByUserIDLabel = "fleet.cattle.io/created-by-user-id"
1617
)
1718

1819
const (

0 commit comments

Comments
 (0)