Skip to content

Commit 9dcbb07

Browse files
committed
test: syslogng end2end test to check if log forwarding works correctly
Signed-off-by: Peter Wilcsinszky <[email protected]>
1 parent 2d445be commit 9dcbb07

File tree

7 files changed

+243
-385
lines changed

7 files changed

+243
-385
lines changed

e2e/go.mod

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
emperror.dev/errors v0.8.1
77
github.com/cisco-open/operator-tools v0.29.0
88
github.com/go-logr/logr v1.2.4
9+
github.com/kube-logging/logging-operator v0.0.0-20230530115305-fbc338a23756
910
github.com/kube-logging/logging-operator/pkg/sdk v0.9.1
1011
github.com/spf13/cast v1.5.0
1112
github.com/stretchr/testify v1.8.2
@@ -20,7 +21,7 @@ require (
2021
github.com/Masterminds/semver/v3 v3.2.1 // indirect
2122
github.com/beorn7/perks v1.0.1 // indirect
2223
github.com/briandowns/spinner v1.12.0 // indirect
23-
github.com/cespare/xxhash/v2 v2.1.2 // indirect
24+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
2425
github.com/cisco-open/k8s-objectmatcher v1.9.0 // indirect
2526
github.com/cppforlife/go-patch v0.2.0 // indirect
2627
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -46,30 +47,30 @@ require (
4647
github.com/mailru/easyjson v0.7.7 // indirect
4748
github.com/mattn/go-colorable v0.1.12 // indirect
4849
github.com/mattn/go-isatty v0.0.14 // indirect
49-
github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
50+
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
5051
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5152
github.com/modern-go/reflect2 v1.0.2 // indirect
5253
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
5354
github.com/pkg/errors v0.9.1 // indirect
5455
github.com/pmezard/go-difflib v1.0.0 // indirect
5556
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.64.1 // indirect
56-
github.com/prometheus/client_golang v1.14.0 // indirect
57+
github.com/prometheus/client_golang v1.15.0 // indirect
5758
github.com/prometheus/client_model v0.3.0 // indirect
58-
github.com/prometheus/common v0.37.0 // indirect
59-
github.com/prometheus/procfs v0.8.0 // indirect
59+
github.com/prometheus/common v0.42.0 // indirect
60+
github.com/prometheus/procfs v0.9.0 // indirect
6061
github.com/spf13/pflag v1.0.5 // indirect
6162
github.com/wayneashleyberry/terminal-dimensions v1.0.0 // indirect
6263
go.uber.org/atomic v1.7.0 // indirect
6364
go.uber.org/multierr v1.6.0 // indirect
6465
golang.org/x/net v0.9.0 // indirect
65-
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
66+
golang.org/x/oauth2 v0.5.0 // indirect
6667
golang.org/x/sys v0.7.0 // indirect
6768
golang.org/x/term v0.7.0 // indirect
6869
golang.org/x/text v0.9.0 // indirect
6970
golang.org/x/time v0.3.0 // indirect
7071
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
7172
google.golang.org/appengine v1.6.7 // indirect
72-
google.golang.org/protobuf v1.28.1 // indirect
73+
google.golang.org/protobuf v1.30.0 // indirect
7374
gopkg.in/inf.v0 v0.9.1 // indirect
7475
gopkg.in/yaml.v2 v2.4.0 // indirect
7576
gopkg.in/yaml.v3 v3.0.1 // indirect

e2e/go.sum

Lines changed: 17 additions & 365 deletions
Large diffs are not rendered by default.
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// Copyright © 2021 Cisco Systems, Inc. and/or its affiliates
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package syslong_ng_aggregator
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"os"
21+
"os/exec"
22+
"path/filepath"
23+
"strings"
24+
"testing"
25+
"time"
26+
27+
"github.com/cisco-open/operator-tools/pkg/typeoverride"
28+
"github.com/cisco-open/operator-tools/pkg/utils"
29+
"github.com/stretchr/testify/require"
30+
appsv1 "k8s.io/api/apps/v1"
31+
batchv1 "k8s.io/api/batch/v1"
32+
corev1 "k8s.io/api/core/v1"
33+
rbacv1 "k8s.io/api/rbac/v1"
34+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
35+
"k8s.io/apimachinery/pkg/api/resource"
36+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+
"k8s.io/apimachinery/pkg/runtime"
38+
"sigs.k8s.io/controller-runtime/pkg/client"
39+
"sigs.k8s.io/controller-runtime/pkg/cluster"
40+
41+
"github.com/kube-logging/logging-operator/pkg/resources/syslogng"
42+
"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
43+
"github.com/kube-logging/logging-operator/pkg/sdk/logging/model/syslogng/filter"
44+
syslogngoutput "github.com/kube-logging/logging-operator/pkg/sdk/logging/model/syslogng/output"
45+
46+
"github.com/kube-logging/logging-operator/e2e/common"
47+
"github.com/kube-logging/logging-operator/e2e/common/cond"
48+
"github.com/kube-logging/logging-operator/e2e/common/setup"
49+
)
50+
51+
var TestTempDir string
52+
53+
func init() {
54+
var ok bool
55+
TestTempDir, ok = os.LookupEnv("PROJECT_DIR")
56+
if !ok {
57+
TestTempDir = "../.."
58+
}
59+
TestTempDir = filepath.Join(TestTempDir, "build/_test")
60+
err := os.MkdirAll(TestTempDir, os.FileMode(0755))
61+
if err != nil {
62+
panic(err)
63+
}
64+
}
65+
66+
func TestSyslogNGIsRunningAndForwardingLogs(t *testing.T) {
67+
ns := "syslog-ng-1"
68+
common.WithCluster(t, func(t *testing.T, c common.Cluster) {
69+
setup.LoggingOperator(t, c, setup.LoggingOperatorOptionFunc(func(options *setup.LoggingOperatorOptions) {
70+
options.Config.DisableWebhook = true
71+
options.Config.Namespace = ns
72+
}))
73+
74+
consumer := setup.LogConsumer(t, c.GetClient(), setup.LogConsumerOptionFunc(func(options *setup.LogConsumerOptions) {
75+
options.Namespace = ns
76+
}))
77+
78+
ctx := context.Background()
79+
80+
logging := v1beta1.Logging{
81+
ObjectMeta: metav1.ObjectMeta{
82+
Name: "syslog-ng-aggregator-test",
83+
Namespace: ns,
84+
},
85+
Spec: v1beta1.LoggingSpec{
86+
EnableRecreateWorkloadOnImmutableFieldChange: true,
87+
ControlNamespace: ns,
88+
FluentbitSpec: &v1beta1.FluentbitSpec{
89+
Network: &v1beta1.FluentbitNetwork{
90+
Keepalive: utils.BoolPointer(false),
91+
},
92+
},
93+
SyslogNGSpec: &v1beta1.SyslogNGSpec{
94+
StatefulSetOverrides: &typeoverride.StatefulSet{
95+
Spec: typeoverride.StatefulSetSpec{
96+
Template: typeoverride.PodTemplateSpec{
97+
Spec: typeoverride.PodSpec{
98+
Containers: []corev1.Container{
99+
{
100+
Name: syslogng.ContainerName,
101+
Resources: corev1.ResourceRequirements{
102+
Limits: corev1.ResourceList{
103+
corev1.ResourceCPU: resource.MustParse("50m"),
104+
corev1.ResourceMemory: resource.MustParse("20M"),
105+
},
106+
Requests: corev1.ResourceList{
107+
corev1.ResourceCPU: resource.MustParse("25m"),
108+
corev1.ResourceMemory: resource.MustParse("10M"),
109+
},
110+
},
111+
},
112+
},
113+
},
114+
},
115+
},
116+
},
117+
},
118+
},
119+
}
120+
require.NoError(t, c.GetClient().Create(ctx, &logging))
121+
output := v1beta1.SyslogNGOutput{
122+
ObjectMeta: metav1.ObjectMeta{
123+
Name: "test-output",
124+
Namespace: ns,
125+
},
126+
Spec: v1beta1.SyslogNGOutputSpec{
127+
HTTP: &syslogngoutput.HTTPOutput{
128+
URL: consumer.InputURL(),
129+
DiskBuffer: &syslogngoutput.DiskBuffer{
130+
DiskBufSize: 100 * 1024 * 1024,
131+
Reliable: true,
132+
Dir: syslogng.BufferPath,
133+
},
134+
},
135+
},
136+
}
137+
require.NoError(t, c.GetClient().Create(ctx, &output))
138+
flow := v1beta1.SyslogNGFlow{
139+
ObjectMeta: metav1.ObjectMeta{
140+
Name: "test-flow",
141+
Namespace: ns,
142+
},
143+
Spec: v1beta1.SyslogNGFlowSpec{
144+
Match: &v1beta1.SyslogNGMatch{
145+
Regexp: &filter.RegexpMatchExpr{
146+
Pattern: "log-producer",
147+
Value: "json.kubernetes.labels.my-unique-label",
148+
Type: "string",
149+
},
150+
},
151+
LocalOutputRefs: []string{output.Name},
152+
},
153+
}
154+
require.NoError(t, c.GetClient().Create(ctx, &flow))
155+
156+
meta := logging.SyslogNGObjectMeta(syslogng.StatefulSetName, syslogng.ComponentSyslogNG)
157+
aggergatorPodName := meta.Name + "-0"
158+
require.Eventually(t, cond.PodShouldBeRunning(t, c.GetClient(), client.ObjectKey{Namespace: ns, Name: aggergatorPodName}), 5*time.Minute, 5*time.Second)
159+
160+
setup.LogProducer(t, c.GetClient(), setup.LogProducerOptionFunc(func(options *setup.LogProducerOptions) {
161+
options.Namespace = ns
162+
options.Labels = map[string]string{
163+
"my-unique-label": "log-producer",
164+
}
165+
}))
166+
167+
require.Eventually(t, func() bool {
168+
rawOut, err := exec.Command("kubectl", "-n", consumer.PodKey.Namespace, "logs", consumer.PodKey.Name).Output()
169+
if err != nil {
170+
t.Logf("failed to get log consumer logs: %v", err)
171+
return false
172+
}
173+
t.Logf("log consumer logs: %s", rawOut)
174+
return strings.Contains(string(rawOut), "got request")
175+
}, 5*time.Minute, 2*time.Second)
176+
177+
require.NoError(t, exec.Command("kubectl", "-n", consumer.PodKey.Namespace, "exec", consumer.PodKey.Name, "--", "curl", "-sS", "http://localhost:8082/off").Run())
178+
179+
require.Eventually(t, cond.PodShouldBeRunning(t, c.GetClient(), client.ObjectKey{Namespace: ns, Name: aggergatorPodName}), 30*time.Second, time.Second/2)
180+
181+
require.NoError(t, exec.Command("kubectl", "-n", consumer.PodKey.Namespace, "exec", consumer.PodKey.Name, "--", "curl", "-sS", "http://localhost:8082/on").Run())
182+
183+
}, func(t *testing.T, c common.Cluster) error {
184+
path := filepath.Join(TestTempDir, fmt.Sprintf("cluster-%s.log", t.Name()))
185+
t.Logf("Printing cluster logs to %s", path)
186+
return c.PrintLogs(common.PrintLogConfig{
187+
Namespaces: []string{ns, "default"},
188+
FilePath: path,
189+
Limit: 100 * 1000,
190+
})
191+
}, func(o *cluster.Options) {
192+
if o.Scheme == nil {
193+
o.Scheme = runtime.NewScheme()
194+
}
195+
require.NoError(t, v1beta1.AddToScheme(o.Scheme))
196+
require.NoError(t, apiextensionsv1.AddToScheme(o.Scheme))
197+
require.NoError(t, appsv1.AddToScheme(o.Scheme))
198+
require.NoError(t, batchv1.AddToScheme(o.Scheme))
199+
require.NoError(t, corev1.AddToScheme(o.Scheme))
200+
require.NoError(t, rbacv1.AddToScheme(o.Scheme))
201+
})
202+
}

e2e/volumedrain/volumedrain_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func init() {
6060
panic(err)
6161
}
6262
}
63+
6364
func TestVolumeDrain_Downscale(t *testing.T) {
6465
ns := "testing-1"
6566
common.WithCluster(t, func(t *testing.T, c common.Cluster) {

pkg/resources/syslogng/dataprovider.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import (
1818
"context"
1919

2020
"emperror.dev/errors"
21-
"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
2221
v1 "k8s.io/api/apps/v1"
2322
"k8s.io/apimachinery/pkg/types"
2423
"sigs.k8s.io/controller-runtime/pkg/client"
24+
25+
"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
2526
)
2627

2728
type DataProvider struct {
@@ -38,7 +39,7 @@ func NewDataProvider(client client.Client, logging *v1beta1.Logging) *DataProvid
3839

3940
func (p *DataProvider) GetReplicaCount(ctx context.Context) (*int32, error) {
4041
sts := &v1.StatefulSet{}
41-
om := p.logging.SyslogNGObjectMeta(statefulSetName, ComponentSyslogNG)
42+
om := p.logging.SyslogNGObjectMeta(StatefulSetName, ComponentSyslogNG)
4243
err := p.client.Get(ctx, types.NamespacedName{Namespace: om.Namespace, Name: om.Name}, sts)
4344
if err != nil {
4445
return nil, errors.WrapIf(client.IgnoreNotFound(err), "getting syslog-ng statefulset")

pkg/resources/syslogng/statefulset.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ import (
2323
"github.com/cisco-open/operator-tools/pkg/merge"
2424
"github.com/cisco-open/operator-tools/pkg/reconciler"
2525
util "github.com/cisco-open/operator-tools/pkg/utils"
26-
"github.com/kube-logging/logging-operator/pkg/resources/kubetool"
27-
"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
2826
appsv1 "k8s.io/api/apps/v1"
2927
corev1 "k8s.io/api/core/v1"
3028
"k8s.io/apimachinery/pkg/api/resource"
3129
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3230
"k8s.io/apimachinery/pkg/runtime"
31+
32+
"github.com/kube-logging/logging-operator/pkg/resources/kubetool"
33+
"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
3334
)
3435

3536
func (r *Reconciler) statefulset() (runtime.Object, reconciler.DesiredState, error) {
@@ -45,7 +46,7 @@ func (r *Reconciler) statefulset() (runtime.Object, reconciler.DesiredState, err
4546
}
4647

4748
desired := &appsv1.StatefulSet{
48-
ObjectMeta: r.Logging.SyslogNGObjectMeta(statefulSetName, ComponentSyslogNG),
49+
ObjectMeta: r.Logging.SyslogNGObjectMeta(StatefulSetName, ComponentSyslogNG),
4950
Spec: appsv1.StatefulSetSpec{
5051
PodManagementPolicy: appsv1.OrderedReadyPodManagement,
5152
Selector: &metav1.LabelSelector{
@@ -81,7 +82,7 @@ func (r *Reconciler) statefulset() (runtime.Object, reconciler.DesiredState, err
8182
buffersVolumeName = name
8283
}
8384
}
84-
syslogngContainer := kubetool.FindContainerByName(desired.Spec.Template.Spec.Containers, containerName)
85+
syslogngContainer := kubetool.FindContainerByName(desired.Spec.Template.Spec.Containers, ContainerName)
8586
if mnt := kubetool.FindVolumeMountByName(syslogngContainer.VolumeMounts, buffersVolumeName); mnt != nil {
8687
if !sliceAny(syslogngContainer.Args, func(arg string) bool { return strings.Contains(arg, "--persist-file") }) {
8788
syslogngContainer.Args = append(syslogngContainer.Args,
@@ -94,7 +95,7 @@ func (r *Reconciler) statefulset() (runtime.Object, reconciler.DesiredState, err
9495

9596
func syslogNGContainer(spec *v1beta1.SyslogNGSpec) corev1.Container {
9697
return corev1.Container{
97-
Name: containerName,
98+
Name: ContainerName,
9899
Image: v1beta1.RepositoryWithTag(syslogngImageRepository, syslogngImageTag),
99100
ImagePullPolicy: corev1.PullIfNotPresent,
100101
Ports: []corev1.ContainerPort{{
@@ -119,7 +120,7 @@ func syslogNGContainer(spec *v1beta1.SyslogNGSpec) corev1.Container {
119120
corev1.ResourceCPU: resource.MustParse("500m"),
120121
},
121122
},
122-
Env: []corev1.EnvVar{{Name: "BUFFER_PATH", Value: bufferPath}},
123+
Env: []corev1.EnvVar{{Name: "BUFFER_PATH", Value: BufferPath}},
123124
LivenessProbe: &corev1.Probe{
124125
ProbeHandler: corev1.ProbeHandler{
125126
Exec: &corev1.ExecAction{
@@ -268,7 +269,7 @@ func (r *Reconciler) bufferMetricsSidecarContainer() *corev1.Container {
268269
VolumeMounts: []corev1.VolumeMount{
269270
{
270271
Name: r.Logging.Spec.SyslogNGSpec.BufferVolumeMetrics.MountName,
271-
MountPath: bufferPath,
272+
MountPath: BufferPath,
272273
},
273274
},
274275
}
@@ -335,7 +336,7 @@ func generateReadinessCheck(spec *v1beta1.SyslogNGSpec) *corev1.Probe {
335336
}
336337

337338
func configReloadContainer(spec *v1beta1.SyslogNGSpec) corev1.Container {
338-
//TODO: ADD TLS reload watch
339+
// TODO: ADD TLS reload watch
339340
container := corev1.Container{
340341
Name: "config-reloader",
341342
Image: v1beta1.RepositoryWithTag(configReloaderImageRepository, configReloaderImageTag),

pkg/resources/syslogng/syslogng.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ const (
4141
ServicePort = 601
4242
configSecretName = "syslog-ng"
4343
configKey = "syslog-ng.conf"
44-
statefulSetName = "syslog-ng"
44+
StatefulSetName = "syslog-ng"
4545
outputSecretName = "syslog-ng-output"
4646
OutputSecretPath = "/etc/syslog-ng/secret"
47-
bufferPath = "/buffers"
47+
BufferPath = "/buffers"
4848
serviceAccountName = "syslog-ng"
4949
roleBindingName = "syslog-ng"
5050
roleName = "syslog-ng"
5151
clusterRoleBindingName = "syslog-ng"
5252
clusterRoleName = "syslog-ng"
53-
containerName = "syslog-ng"
53+
ContainerName = "syslog-ng"
5454
defaultBufferVolumeMetricsPort = 9200
5555
syslogngImageRepository = "ghcr.io/axoflow/axosyslog"
5656
syslogngImageTag = "4.2.0"

0 commit comments

Comments
 (0)