Annotations/AuthTLS: Allow named redirects. (#13819)

Signed-off-by: Dean Coakley <dean.s.coakley@gmail.com>
Co-authored-by: Dean Coakley <dean.s.coakley@gmail.com>
This commit is contained in:
k8s-infra-cherrypick-robot 2025-08-25 03:17:07 -07:00 committed by GitHub
parent c3f453e6e6
commit 4d19f5d71f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 15 deletions

View File

@ -42,7 +42,7 @@ const (
var (
authVerifyClientRegex = regexp.MustCompile(`^(on|off|optional|optional_no_ca)$`)
redirectRegex = regexp.MustCompile(`^((https?://)?[A-Za-z0-9\-.]+(:\d+)?)?(/[A-Za-z0-9\-_.]+)*/?$`)
redirectRegex = regexp.MustCompile(`^(@[A-Za-z0-9_-]+|((https?://)?[A-Za-z0-9\-.]+(:\d+)?)?(/[A-Za-z0-9\-_.]+)*/?)$`)
)
var authTLSAnnotations = parser.Annotation{
@ -148,12 +148,12 @@ func (a authTLS) Parse(ing *networking.Ingress) (interface{}, error) {
var err error
config := &Config{}
tlsauthsecret, err := parser.GetStringAnnotation(annotationAuthTLSSecret, ing, a.annotationConfig.Annotations)
authTLSSecret, err := parser.GetStringAnnotation(annotationAuthTLSSecret, ing, a.annotationConfig.Annotations)
if err != nil {
return &Config{}, err
}
ns, _, err := k8s.ParseNameNS(tlsauthsecret)
ns, _, err := k8s.ParseNameNS(authTLSSecret)
if err != nil {
return &Config{}, ing_errors.NewLocationDenied(err.Error())
}
@ -166,7 +166,7 @@ func (a authTLS) Parse(ing *networking.Ingress) (interface{}, error) {
return &Config{}, ing_errors.NewLocationDenied("cross namespace secrets are not supported")
}
authCert, err := a.r.GetAuthCertificate(tlsauthsecret)
authCert, err := a.r.GetAuthCertificate(authTLSSecret)
if err != nil {
e := fmt.Errorf("error obtaining certificate: %w", err)
return &Config{}, ing_errors.LocationDeniedError{Reason: e}

View File

@ -48,14 +48,7 @@ func buildIngress() *networking.Ingress {
Namespace: api.NamespaceDefault,
},
Spec: networking.IngressSpec{
DefaultBackend: &networking.IngressBackend{
Service: &networking.IngressServiceBackend{
Name: "default-backend",
Port: networking.ServiceBackendPort{
Number: 80,
},
},
},
DefaultBackend: &defaultBackend,
Rules: []networking.IngressRule{
{
Host: "foo.bar.com",
@ -163,15 +156,38 @@ func TestAnnotations(t *testing.T) {
if u.ValidationDepth != 2 {
t.Errorf("expected %v but got %v", 2, u.ValidationDepth)
}
if u.ErrorPage != "ok.com/error" {
t.Errorf("expected %v but got %v", "ok.com/error", u.ErrorPage)
}
if u.PassCertToUpstream != true {
t.Errorf("expected %v but got %v", true, u.PassCertToUpstream)
}
if u.MatchCN != "CN=(hello-app|ok|goodbye)" {
t.Errorf("expected %v but got %v", "CN=(hello-app|ok|goodbye)", u.MatchCN)
}
for _, tc := range []struct {
name string
errorPage string
want string
}{
{"url redirect", "ok.com/error", "ok.com/error"},
{"named redirect numeric", "@401", "@401"},
{"named redirect alphanumeric with underscores", "@four_oh_one", "@four_oh_one"},
} {
t.Run(tc.name, func(t *testing.T) {
data[parser.GetAnnotationWithPrefix(annotationAuthTLSErrorPage)] = tc.errorPage
ing.SetAnnotations(data)
i, err := NewParser(fakeSecret).Parse(ing)
if err != nil {
t.Errorf("Unexpected error with ingress: %v", err)
}
u, ok := i.(*Config)
if !ok {
t.Errorf("expected *Config but got %v", u)
}
if u.ErrorPage != tc.want {
t.Errorf("expected %v but got %v", tc.want, u.ErrorPage)
}
})
}
}
func TestInvalidAnnotations(t *testing.T) {