Files
lolia-frp/pkg/config/v1/validation/proxy_test.go
T
fatedier 4c07ebda5b refactor(validation): inline annotation qualified name check (#5601)
Replace the single use of k8s.io/apimachinery/pkg/util/validation
.IsQualifiedName (annotation key validation in pkg/config/v1/validation)
with a local implementation in pkg/util/validation. Newer apimachinery
versions link klog only for IP/CIDR warning helpers, which grows frpc and
frps, and this was the only frp import of that package.

The local IsQualifiedName keeps the exact behavior and error messages of
apimachinery v0.28.8, including the qualified-name (label key) format and
the DNS-1123 subdomain prefix rules. Annotation keys are still lowercased
before validation, so the accepted set is unchanged.

Verified against apimachinery v0.28.8 on 228,220 inputs (exhaustive short
strings, boundary lengths and seeded random data, including lowercased
variants): every error message matches.

No dependency versions change; go.mod and go.sum are untouched.
2026-11-04 19:59:26 +08:00

92 lines
2.7 KiB
Go

// Copyright 2026 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation
import (
"testing"
"github.com/stretchr/testify/require"
v1 "github.com/fatedier/frp/pkg/config/v1"
)
func TestValidateDomainConfigForServerRejectsSubdomainHostCaseInsensitively(t *testing.T) {
tests := []struct {
name string
subDomainHost string
customDomain string
wantErr bool
}{
{
name: "lowercase subdomain",
subDomainHost: "frp.example.com",
customDomain: "victim.frp.example.com",
wantErr: true,
},
{
name: "mixed case custom domain",
subDomainHost: "frp.example.com",
customDomain: "victim.FRP.example.com",
wantErr: true,
},
{
name: "mixed case wildcard domain",
subDomainHost: "frp.example.com",
customDomain: "*.FRP.example.com",
wantErr: true,
},
{
name: "mixed case subdomain host",
subDomainHost: "FRP.Example.Com",
customDomain: "victim.frp.example.com",
wantErr: true,
},
{
name: "external domain",
subDomainHost: "frp.example.com",
customDomain: "victim.example.net",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateDomainConfigForServer(
&v1.DomainConfig{CustomDomains: []string{tt.customDomain}},
&v1.ServerConfig{SubDomainHost: tt.subDomainHost},
)
if tt.wantErr {
require.ErrorContains(t, err, "should not belong to subdomain host")
return
}
require.NoError(t, err)
})
}
}
func TestValidateAnnotationsQualifiedName(t *testing.T) {
require.NoError(t, ValidateAnnotations(map[string]string{
"frp.e2e.test/foo": "value1",
"app.kubernetes.io/name": "value2",
}))
// The call site lowercases keys before validation.
require.NoError(t, ValidateAnnotations(map[string]string{"Example.COM/MyName": "value"}))
err := ValidateAnnotations(map[string]string{"bad key": "value"})
require.ErrorContains(t, err, "annotation key bad key is invalid: name part must consist of alphanumeric characters")
err = ValidateAnnotations(map[string]string{"example.com/": "value"})
require.ErrorContains(t, err, "name part must be non-empty")
}