55package filters
66
77import (
8- "fmt"
98 "strings"
109
1110 "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors"
@@ -47,11 +46,7 @@ func StreamChecker(log *logger.Logger, ast *transpiler.AST) error {
4746 if nsNode , found := inputNode .Find ("data_stream.namespace" ); found {
4847 nsKey , ok := nsNode .(* transpiler.Key )
4948 if ok {
50- newNamespace := nsKey .Value ().(transpiler.Node ).String ()
51- if ! isValid (newNamespace ) {
52- return ErrInvalidNamespace
53- }
54- namespace = newNamespace
49+ namespace = nsKey .Value ().(transpiler.Node ).String ()
5550 }
5651 } else {
5752 dsNode , found := inputNode .Find ("data_stream" )
@@ -63,17 +58,17 @@ func StreamChecker(log *logger.Logger, ast *transpiler.AST) error {
6358 if found {
6459 nsKey , ok := nsNode .(* transpiler.Key )
6560 if ok {
66- newNamespace := nsKey .Value ().(transpiler.Node ).String ()
67- if ! isValid (newNamespace ) {
68- return ErrInvalidNamespace
69- }
70- namespace = newNamespace
61+ namespace = nsKey .Value ().(transpiler.Node ).String ()
7162 }
7263 }
7364 }
7465 }
7566 }
7667
68+ if ! matchesNamespaceContraints (namespace ) {
69+ return ErrInvalidNamespace
70+ }
71+
7772 // get the type, longest type for now is metrics
7873 datasetType := "metrics"
7974 if nsNode , found := inputNode .Find ("data_stream.type" ); found {
@@ -100,6 +95,10 @@ func StreamChecker(log *logger.Logger, ast *transpiler.AST) error {
10095 }
10196 }
10297
98+ if ! matchesTypeConstraints (datasetType ) {
99+ return ErrInvalidIndex
100+ }
101+
103102 streamsNode , ok := inputNode .Find ("streams" )
104103 if ok {
105104 streamsList , ok := streamsNode .Value ().(* transpiler.List )
@@ -119,11 +118,8 @@ func StreamChecker(log *logger.Logger, ast *transpiler.AST) error {
119118 if dsNameNode , found := streamMap .Find ("data_stream.dataset" ); found {
120119 dsKey , ok := dsNameNode .(* transpiler.Key )
121120 if ok {
122- newDataset := dsKey .Value ().(transpiler.Node ).String ()
123- if ! isValid (newDataset ) {
124- return ErrInvalidDataset
125- }
126- datasetName = newDataset
121+ datasetName = dsKey .Value ().(transpiler.Node ).String ()
122+ break
127123 }
128124 } else {
129125 datasetNode , found := streamMap .Find ("data_stream" )
@@ -137,61 +133,74 @@ func StreamChecker(log *logger.Logger, ast *transpiler.AST) error {
137133 if found {
138134 dsKey , ok := dsNameNode .(* transpiler.Key )
139135 if ok {
140- newDataset := dsKey .Value ().(transpiler.Node ).String ()
141- if ! isValid (newDataset ) {
142- return ErrInvalidDataset
143- }
144- datasetName = newDataset
136+ datasetName = dsKey .Value ().(transpiler.Node ).String ()
137+ break
145138 }
146139 }
147140 }
148141 }
149142 }
150143 }
151144 }
152-
153- if indexName := fmt .Sprintf ("%s-%s-%s" , datasetType , datasetName , namespace ); ! matchesIndexContraints (indexName ) {
154- return ErrInvalidIndex
145+ if ! matchesDatasetConstraints (datasetName ) {
146+ return ErrInvalidDataset
155147 }
156148 }
157149
158150 return nil
159151}
160152
161- // The only two requirement are that it has only characters allowed in an Elasticsearch index name
162- // and does NOT contain a `-`.
163- func isValid (namespace string ) bool {
164- return matchesIndexContraints (namespace ) && ! strings .Contains (namespace , "-" )
165- }
166-
167153// The only two requirement are that it has only characters allowed in an Elasticsearch index name
168154// Index names must meet the following criteria:
155+ // Not longer than 100 bytes
169156// Lowercase only
170157// Cannot include \, /, *, ?, ", <, >, |, ` ` (space character), ,, #
158+ func matchesNamespaceContraints (namespace string ) bool {
159+ // length restriction is in bytes, not characters
160+ if len (namespace ) <= 0 || len (namespace ) > 100 {
161+ return false
162+ }
163+
164+ return isCharactersetValid (namespace )
165+ }
166+
167+ // matchesTypeConstraints fails for following rules. As type is first element of resulting index prefix restrictions need to be applied.
168+ // Not longer than 20 bytes
169+ // Lowercase only
171170// Cannot start with -, _, +
172- // Cannot be . or ..
173- func matchesIndexContraints ( namespace string ) bool {
174- // Cannot be . or ..
175- if namespace == "." || namespace == ".." {
171+ // Cannot include \, /, *, ?, ", <, >, |, ` ` (space character), ,, #
172+ func matchesTypeConstraints ( dsType string ) bool {
173+ // length restriction is in bytes, not characters
174+ if len ( dsType ) <= 0 || len ( dsType ) > 20 {
176175 return false
177176 }
178177
179- if len ( namespace ) <= 0 || len ( namespace ) > 255 {
178+ if strings . HasPrefix ( dsType , "-" ) || strings . HasPrefix ( dsType , "_" ) || strings . HasPrefix ( dsType , "+" ) {
180179 return false
181180 }
182181
183- // Lowercase only
184- if strings .ToLower (namespace ) != namespace {
182+ return isCharactersetValid (dsType )
183+ }
184+
185+ // matchesDatasetConstraints fails for following rules
186+ // Not longer than 100 bytes
187+ // Lowercase only
188+ // Cannot include \, /, *, ?, ", <, >, |, ` ` (space character), ,, #
189+ func matchesDatasetConstraints (dataset string ) bool {
190+ // length restriction is in bytes, not characters
191+ if len (dataset ) <= 0 || len (dataset ) > 100 {
185192 return false
186193 }
187194
188- // Cannot include \, /, *, ?, ", <, >, |, ` ` (space character), ,, #
189- if strings .ContainsAny (namespace , "\\ /*?\" <>| ,#" ) {
195+ return isCharactersetValid (dataset )
196+ }
197+
198+ func isCharactersetValid (input string ) bool {
199+ if strings .ToLower (input ) != input {
190200 return false
191201 }
192202
193- // Cannot start with -, _, +
194- if strings .HasPrefix (namespace , "-" ) || strings .HasPrefix (namespace , "_" ) || strings .HasPrefix (namespace , "+" ) {
203+ if strings .ContainsAny (input , "\\ /*?\" <>| ,#:" ) {
195204 return false
196205 }
197206
0 commit comments