Skip to content

Commit 4221b0e

Browse files
Copilotcsatib02
andcommitted
Implement skipInvalidResources for syslog-ng logging
Co-authored-by: csatib02 <113284287+csatib02@users.noreply.github.com>
1 parent 9df7614 commit 4221b0e

File tree

4 files changed

+194
-21
lines changed

4 files changed

+194
-21
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: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,160 @@ 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+
wantOut: `@version: current
641+
642+
@include "scl.conf"
643+
644+
source "main_input" {
645+
channel {
646+
source {
647+
network(flags("no-parse") port(601) transport("tcp"));
648+
};
649+
parser {
650+
json-parser(prefix("json."));
651+
};
652+
};
653+
};
654+
`,
655+
},
656+
"clusterFlow referencing non-existent cluster output with skipInvalidResources": {
657+
input: Input{
658+
Name: "test",
659+
SyslogNGSpec: &v1beta1.SyslogNGSpec{},
660+
ClusterFlows: []v1beta1.SyslogNGClusterFlow{
661+
{
662+
ObjectMeta: metav1.ObjectMeta{
663+
Namespace: "default",
664+
Name: "test-flow",
665+
},
666+
Spec: v1beta1.SyslogNGClusterFlowSpec{
667+
GlobalOutputRefs: []string{
668+
"clusterout",
669+
},
670+
},
671+
},
672+
},
673+
ClusterOutputs: nil,
674+
SecretLoaderFactory: &TestSecretLoaderFactory{},
675+
SourcePort: 601,
676+
SkipInvalidResources: true,
677+
},
678+
wantOut: `@version: current
679+
680+
@include "scl.conf"
681+
682+
source "main_input" {
683+
channel {
684+
source {
685+
network(flags("no-parse") port(601) transport("tcp"));
686+
};
687+
parser {
688+
json-parser(prefix("json."));
689+
};
690+
};
691+
};
692+
`,
693+
},
694+
"flow with mixed valid and invalid outputs with skipInvalidResources": {
695+
input: Input{
696+
SyslogNGSpec: &v1beta1.SyslogNGSpec{},
697+
Name: "test",
698+
Flows: []v1beta1.SyslogNGFlow{
699+
{
700+
ObjectMeta: metav1.ObjectMeta{
701+
Namespace: "default",
702+
Name: "test-flow-invalid",
703+
},
704+
Spec: v1beta1.SyslogNGFlowSpec{
705+
GlobalOutputRefs: []string{
706+
"nonexistent",
707+
},
708+
},
709+
},
710+
{
711+
ObjectMeta: metav1.ObjectMeta{
712+
Namespace: "default",
713+
Name: "test-flow-valid",
714+
},
715+
Spec: v1beta1.SyslogNGFlowSpec{
716+
GlobalOutputRefs: []string{
717+
"clusterout",
718+
},
719+
},
720+
},
721+
},
722+
ClusterOutputs: []v1beta1.SyslogNGClusterOutput{
723+
{
724+
ObjectMeta: metav1.ObjectMeta{
725+
Name: "clusterout",
726+
Namespace: "logging",
727+
},
728+
Spec: v1beta1.SyslogNGClusterOutputSpec{
729+
SyslogNGOutputSpec: v1beta1.SyslogNGOutputSpec{
730+
Syslog: &output.SyslogOutput{
731+
Host: "127.0.0.1",
732+
},
733+
},
734+
},
735+
},
736+
},
737+
SecretLoaderFactory: &TestSecretLoaderFactory{},
738+
SourcePort: 601,
739+
SkipInvalidResources: true,
740+
},
741+
wantOut: `@version: current
742+
743+
@include "scl.conf"
744+
745+
source "main_input" {
746+
channel {
747+
source {
748+
network(flags("no-parse") port(601) transport("tcp"));
749+
};
750+
parser {
751+
json-parser(prefix("json."));
752+
};
753+
};
754+
};
755+
756+
destination "clusteroutput_logging_clusterout" {
757+
syslog("127.0.0.1" persist_name("clusteroutput_logging_clusterout"));
758+
};
759+
760+
filter "flow_default_test-flow-valid_ns_filter" {
761+
match("default" value("json.kubernetes.namespace_name") type("string"));
762+
};
763+
log {
764+
source("main_input");
765+
filter("flow_default_test-flow-valid_ns_filter");
766+
log {
767+
destination("clusteroutput_logging_clusterout");
768+
};
769+
};
770+
`,
771+
},
618772
"parser": {
619773
input: Input{
620774
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)