Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ permissions:

env:
NFPM_VERSION: 'v2.35.3'
GOPROXY: "direct"
GOPROXY: "https://${{ secrets.ARTIFACTORY_USER }}:${{ secrets.ARTIFACTORY_TOKEN }}@azr.artifactory.f5net.com/artifactory/api/go/f5-nginx-go-dev"

jobs:
proxy-sanity-check:
Expand Down
20 changes: 18 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const (

// Regular expression to match invalid characters in paths.
// It matches whitespace, control characters, non-printable characters, and specific Unicode characters.
regexInvalidPath = "\\s|[[:cntrl:]]|[[:space:]]|[[^:print:]]|ㅤ|\\.\\.|\\*"
regexInvalidPath = "\\s|[[:cntrl:]]|[[:space:]]|[[^:print:]]|ㅤ|\\.\\.|\\*"
regexLabelPattern = "^[a-zA-Z0-9]([a-zA-Z0-9-_]{0,254}[a-zA-Z0-9])?$"
)

var viperInstance = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter))
Expand Down Expand Up @@ -931,7 +932,9 @@ func resolveLabels() map[string]interface{} {
result[trimmedKey] = parseJSON(trimmedValue)

default: // String
result[trimmedKey] = trimmedValue
if validateLabel(trimmedValue) {
result[trimmedKey] = trimmedValue
}
}
}

Expand All @@ -940,6 +943,19 @@ func resolveLabels() map[string]interface{} {
return result
}

func validateLabel(labelValue string) bool {
const maxLength = 256
labelPattern := regexp.MustCompile(regexLabelPattern)
if len(labelValue) > maxLength || !labelPattern.MatchString(labelValue) {
slog.Warn("Label value contains unsupported character or exceed maximum length of 256 characters ",
"label_value", labelValue)

return false
}

return true
}

func resolveEnvironmentVariableLabels() map[string]string {
envLabels := make(map[string]string)
envInput := viperInstance.GetString(LabelsRootKey)
Expand Down
60 changes: 58 additions & 2 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ func createConfig() *Config {
{
Action: "insert",
Key: "label1",
Value: "label 1",
Value: "label-1",
},
{
Action: "insert",
Expand Down Expand Up @@ -1314,7 +1314,7 @@ func createConfig() *Config {
},
},
Labels: map[string]any{
"label1": "label 1",
"label1": "label-1",
"label2": "new-value",
"label3": 123,
},
Expand Down Expand Up @@ -1410,3 +1410,59 @@ func createDefaultCollectorConfig() *Collector {
},
}
}

func TestValidateLabel(t *testing.T) {
tests := []struct {
name string
input string
expected bool
}{
{
name: "Test 1: Valid label - simple",
input: "label123",
expected: true,
},
{
name: "Test 2: Valid label - with dash and underscore",
input: "label-123_abc",
expected: true,
},
{
name: "Test 3: Invalid label - too long",
input: strings.Repeat("a", 257),
expected: false,
},
{
name: "Test 4: Invalid label - special char",
input: "label$",
expected: false,
},
{
name: "Test 5: Invalid label - starts with dash",
input: "-label",
expected: false,
},
{
name: "Test 6: Invalid label - ends with dash",
input: "label-",
expected: false,
},
{
name: "Test 7: Invalid label - empty",
input: "",
expected: false,
},
{
name: "Test 8: Invalid label - contains spaces",
input: "label 123",
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := validateLabel(tt.input)
assert.Equal(t, tt.expected, actual)
})
}
}
2 changes: 1 addition & 1 deletion internal/config/testdata/nginx-agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ watchers:
- \.*log$

labels:
label1: label 1
label1: label-1
label2: new-value
label3: 123

Expand Down
Loading