Skip to content

Commit 34ac4af

Browse files
authored
Merge pull request #2116 from kube-logging/copilot/fix-7d3b6ea5-1612-4c73-b160-15fd29dec4c1
2 parents 54058b5 + 5120b4f commit 34ac4af

File tree

4 files changed

+198
-22
lines changed

4 files changed

+198
-22
lines changed

controllers/logging/logging_controller.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -461,15 +461,17 @@ func (r *LoggingReconciler) clusterConfigurationSyslogNG(resources model.Logging
461461

462462
_, syslogngSpec := resources.GetSyslogNGSpec()
463463
in := syslogngconfig.Input{
464-
Name: resources.Logging.Name,
465-
Namespace: resources.Logging.Namespace,
466-
ClusterOutputs: resources.SyslogNG.ClusterOutputs,
467-
Outputs: resources.SyslogNG.Outputs,
468-
ClusterFlows: resources.SyslogNG.ClusterFlows,
469-
Flows: resources.SyslogNG.Flows,
470-
SecretLoaderFactory: &slf,
471-
SourcePort: syslogng.ServicePort,
472-
SyslogNGSpec: syslogngSpec,
464+
Name: resources.Logging.Name,
465+
Namespace: resources.Logging.Namespace,
466+
ClusterOutputs: resources.SyslogNG.ClusterOutputs,
467+
Outputs: resources.SyslogNG.Outputs,
468+
ClusterFlows: resources.SyslogNG.ClusterFlows,
469+
Flows: resources.SyslogNG.Flows,
470+
SecretLoaderFactory: &slf,
471+
SourcePort: syslogng.ServicePort,
472+
SyslogNGSpec: syslogngSpec,
473+
SkipInvalidResources: resources.Logging.Spec.SkipInvalidResources,
474+
Logger: r.Log,
473475
}
474476
var b strings.Builder
475477
if err := syslogngconfig.RenderConfigInto(in, &b); err != nil {

pkg/sdk/logging/model/syslogng/config/config.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"emperror.dev/errors"
2323
"github.com/cisco-open/operator-tools/pkg/secret"
24+
"github.com/go-logr/logr"
2425
"github.com/siliconbrain/go-seqs/seqs"
2526
"k8s.io/apimachinery/pkg/types"
2627
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -45,15 +46,17 @@ func RenderConfigInto(in Input, out io.Writer) error {
4546
}
4647

4748
type Input struct {
48-
Name string
49-
Namespace string
50-
SyslogNGSpec *v1beta1.SyslogNGSpec
51-
ClusterOutputs []v1beta1.SyslogNGClusterOutput
52-
Outputs []v1beta1.SyslogNGOutput
53-
ClusterFlows []v1beta1.SyslogNGClusterFlow
54-
Flows []v1beta1.SyslogNGFlow
55-
SecretLoaderFactory SecretLoaderFactory
56-
SourcePort int
49+
Name string
50+
Namespace string
51+
SyslogNGSpec *v1beta1.SyslogNGSpec
52+
ClusterOutputs []v1beta1.SyslogNGClusterOutput
53+
Outputs []v1beta1.SyslogNGOutput
54+
ClusterFlows []v1beta1.SyslogNGClusterFlow
55+
Flows []v1beta1.SyslogNGFlow
56+
SecretLoaderFactory SecretLoaderFactory
57+
SourcePort int
58+
SkipInvalidResources bool
59+
Logger logr.Logger
5760
}
5861

5962
type outputInfo struct {
@@ -114,16 +117,30 @@ func configRenderer(in Input) (render.Renderer, error) {
114117
logDefs := make([]render.Renderer, 0, len(in.ClusterFlows)+len(in.Flows))
115118
for _, cf := range in.ClusterFlows {
116119
if err := validateClusterOutputs(clusterOutputRefs, client.ObjectKeyFromObject(&cf).String(), cf.Spec.GlobalOutputRefs, cf.Kind); err != nil {
120+
if in.SkipInvalidResources {
121+
// Skip this cluster flow and continue with the next one
122+
in.Logger.Error(err, "skipping invalid SyslogNGClusterFlow", "name", cf.Name, "namespace", cf.Namespace)
123+
continue
124+
}
117125
errs = errors.Append(errs, err)
118126
}
119127
logDefs = append(logDefs, renderClusterFlow(in.Name, clusterOutputRefs, sourceName, cf, in.SecretLoaderFactory))
120128
}
121129
for _, f := range in.Flows {
130+
var flowErrs error
122131
if err := validateClusterOutputs(clusterOutputRefs, client.ObjectKeyFromObject(&f).String(), f.Spec.GlobalOutputRefs, f.Kind); err != nil {
123-
errs = errors.Append(errs, err)
132+
flowErrs = errors.Append(flowErrs, err)
124133
}
125134
if err := validateOutputs(outputRefs, client.ObjectKeyFromObject(&f).String(), f.Spec.LocalOutputRefs); err != nil {
126-
errs = errors.Append(errs, err)
135+
flowErrs = errors.Append(flowErrs, err)
136+
}
137+
if flowErrs != nil {
138+
if in.SkipInvalidResources {
139+
// Skip this flow and continue with the next one
140+
in.Logger.Error(flowErrs, "skipping invalid SyslogNGFlow", "name", f.Name, "namespace", f.Namespace)
141+
continue
142+
}
143+
errs = errors.Append(errs, flowErrs)
127144
}
128145
logDefs = append(logDefs, renderFlow(in.Name, clusterOutputRefs, sourceName, keyDelim(in.SyslogNGSpec.JSONKeyDelimiter), f, in.SecretLoaderFactory))
129146
}

pkg/sdk/logging/model/syslogng/config/config_test.go

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func TestRenderConfigInto(t *testing.T) {
3333
testCases := map[string]struct {
3434
input Input
3535
wantOut string
36-
wantErr any
36+
wantErr bool
3737
}{
3838
"empty input": {
3939
input: Input{
@@ -615,6 +615,163 @@ log {
615615
},
616616
wantErr: true,
617617
},
618+
"flow referencing non-existent cluster output with skipInvalidResources": {
619+
input: Input{
620+
SyslogNGSpec: &v1beta1.SyslogNGSpec{},
621+
Name: "test",
622+
Flows: []v1beta1.SyslogNGFlow{
623+
{
624+
ObjectMeta: metav1.ObjectMeta{
625+
Namespace: "default",
626+
Name: "test-flow",
627+
},
628+
Spec: v1beta1.SyslogNGFlowSpec{
629+
GlobalOutputRefs: []string{
630+
"clusterout",
631+
},
632+
},
633+
},
634+
},
635+
ClusterOutputs: nil,
636+
SecretLoaderFactory: &TestSecretLoaderFactory{},
637+
SourcePort: 601,
638+
SkipInvalidResources: true,
639+
},
640+
wantErr: false,
641+
wantOut: `@version: current
642+
643+
@include "scl.conf"
644+
645+
source "main_input" {
646+
channel {
647+
source {
648+
network(flags("no-parse") port(601) transport("tcp"));
649+
};
650+
parser {
651+
json-parser(prefix("json."));
652+
};
653+
};
654+
};
655+
`,
656+
},
657+
"clusterFlow referencing non-existent cluster output with skipInvalidResources": {
658+
input: Input{
659+
Name: "test",
660+
SyslogNGSpec: &v1beta1.SyslogNGSpec{},
661+
ClusterFlows: []v1beta1.SyslogNGClusterFlow{
662+
{
663+
ObjectMeta: metav1.ObjectMeta{
664+
Namespace: "default",
665+
Name: "test-flow",
666+
},
667+
Spec: v1beta1.SyslogNGClusterFlowSpec{
668+
GlobalOutputRefs: []string{
669+
"clusterout",
670+
},
671+
},
672+
},
673+
},
674+
ClusterOutputs: nil,
675+
SecretLoaderFactory: &TestSecretLoaderFactory{},
676+
SourcePort: 601,
677+
SkipInvalidResources: true,
678+
},
679+
wantErr: false,
680+
wantOut: `@version: current
681+
682+
@include "scl.conf"
683+
684+
source "main_input" {
685+
channel {
686+
source {
687+
network(flags("no-parse") port(601) transport("tcp"));
688+
};
689+
parser {
690+
json-parser(prefix("json."));
691+
};
692+
};
693+
};
694+
`,
695+
},
696+
"flow with mixed valid and invalid outputs with skipInvalidResources": {
697+
input: Input{
698+
SyslogNGSpec: &v1beta1.SyslogNGSpec{},
699+
Name: "test",
700+
Flows: []v1beta1.SyslogNGFlow{
701+
{
702+
ObjectMeta: metav1.ObjectMeta{
703+
Namespace: "default",
704+
Name: "test-flow-invalid",
705+
},
706+
Spec: v1beta1.SyslogNGFlowSpec{
707+
GlobalOutputRefs: []string{
708+
"nonexistent",
709+
},
710+
},
711+
},
712+
{
713+
ObjectMeta: metav1.ObjectMeta{
714+
Namespace: "default",
715+
Name: "test-flow-valid",
716+
},
717+
Spec: v1beta1.SyslogNGFlowSpec{
718+
GlobalOutputRefs: []string{
719+
"clusterout",
720+
},
721+
},
722+
},
723+
},
724+
ClusterOutputs: []v1beta1.SyslogNGClusterOutput{
725+
{
726+
ObjectMeta: metav1.ObjectMeta{
727+
Name: "clusterout",
728+
Namespace: "logging",
729+
},
730+
Spec: v1beta1.SyslogNGClusterOutputSpec{
731+
SyslogNGOutputSpec: v1beta1.SyslogNGOutputSpec{
732+
Syslog: &output.SyslogOutput{
733+
Host: "127.0.0.1",
734+
},
735+
},
736+
},
737+
},
738+
},
739+
SecretLoaderFactory: &TestSecretLoaderFactory{},
740+
SourcePort: 601,
741+
SkipInvalidResources: true,
742+
},
743+
wantErr: false,
744+
wantOut: `@version: current
745+
746+
@include "scl.conf"
747+
748+
source "main_input" {
749+
channel {
750+
source {
751+
network(flags("no-parse") port(601) transport("tcp"));
752+
};
753+
parser {
754+
json-parser(prefix("json."));
755+
};
756+
};
757+
};
758+
759+
destination "clusteroutput_logging_clusterout" {
760+
syslog("127.0.0.1" persist_name("clusteroutput_logging_clusterout"));
761+
};
762+
763+
filter "flow_default_test-flow-valid_ns_filter" {
764+
match("default" value("json.kubernetes.namespace_name") type("string"));
765+
};
766+
log {
767+
source("main_input");
768+
filter("flow_default_test-flow-valid_ns_filter");
769+
log {
770+
destination("clusteroutput_logging_clusterout");
771+
};
772+
};
773+
`,
774+
},
618775
"parser": {
619776
input: Input{
620777
Name: "test",

pkg/sdk/logging/model/syslogng/config/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.24.1
55
require (
66
emperror.dev/errors v0.8.1
77
github.com/cisco-open/operator-tools v0.37.0
8+
github.com/go-logr/logr v1.4.3
89
github.com/kube-logging/logging-operator/pkg/sdk v0.12.0
910
github.com/siliconbrain/go-seqs v0.15.0
1011
github.com/stretchr/testify v1.11.0
@@ -22,7 +23,6 @@ require (
2223
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
2324
github.com/fsnotify/fsnotify v1.9.0 // indirect
2425
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
25-
github.com/go-logr/logr v1.4.3 // indirect
2626
github.com/go-openapi/jsonpointer v0.21.1 // indirect
2727
github.com/go-openapi/jsonreference v0.21.0 // indirect
2828
github.com/go-openapi/swag v0.23.1 // indirect

0 commit comments

Comments
 (0)