Skip to content

Commit 8508875

Browse files
authored
Merge pull request #88858 from cmluciano/cml/hostnamewildcard
ingress: allow wildcard hosts in IngressRule
2 parents 0ad60b3 + e931e30 commit 8508875

File tree

9 files changed

+134
-44
lines changed

9 files changed

+134
-44
lines changed

api/openapi-spec/swagger.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/networking/types.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,18 +349,28 @@ type IngressStatus struct {
349349
// host match, then routed to the backend associated with the matching
350350
// IngressRuleValue.
351351
type IngressRule struct {
352-
// Host is the fully qualified domain name of a network host, as defined
353-
// by RFC 3986. Note the following deviations from the "host" part of the
354-
// URI as defined in the RFC:
355-
// 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the
356-
// IP in the Spec of the parent Ingress.
352+
// Host is the fully qualified domain name of a network host, as defined by RFC 3986.
353+
// Note the following deviations from the "host" part of the
354+
// URI as defined in RFC 3986:
355+
// 1. IPs are not allowed. Currently an IngressRuleValue can only apply to
356+
// the IP in the Spec of the parent Ingress.
357357
// 2. The `:` delimiter is not respected because ports are not allowed.
358358
// Currently the port of an Ingress is implicitly :80 for http and
359359
// :443 for https.
360360
// Both these may change in the future.
361-
// Incoming requests are matched against the host before the IngressRuleValue.
362-
// If the host is unspecified, the Ingress routes all traffic based on the
363-
// specified IngressRuleValue.
361+
// Incoming requests are matched against the host before the
362+
// IngressRuleValue. If the host is unspecified, the Ingress routes all
363+
// traffic based on the specified IngressRuleValue.
364+
//
365+
// Host can be "precise" which is a domain name without the terminating dot of
366+
// a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name
367+
// prefixed with a single wildcard label (e.g. "*.foo.com").
368+
// The wildcard character '*' must appear by itself as the first DNS label and
369+
// matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*").
370+
// Requests will be matched against the Host field in the following way:
371+
// 1. If Host is precise, the request matches this rule if the http host header is equal to Host.
372+
// 2. If Host is a wildcard, then the request matches this rule if the http host header
373+
// is to equal to the suffix (removing the first label) of the wildcard rule.
364374
// +optional
365375
Host string
366376
// IngressRuleValue represents a rule to route requests for this

pkg/apis/networking/validation/validation_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,28 @@ func TestValidateIngress(t *testing.T) {
10081008
"spec.rules[0].host",
10091009
},
10101010
},
1011+
"valid wildcard host": {
1012+
tweakIngress: func(ing *networking.Ingress) {
1013+
ing.Spec.Rules[0].Host = "*.bar.com"
1014+
},
1015+
expectErrsOnFields: []string{},
1016+
},
1017+
"invalid wildcard host (foo.*.bar.com)": {
1018+
tweakIngress: func(ing *networking.Ingress) {
1019+
ing.Spec.Rules[0].Host = "foo.*.bar.com"
1020+
},
1021+
expectErrsOnFields: []string{
1022+
"spec.rules[0].host",
1023+
},
1024+
},
1025+
"invalid wildcard host (*)": {
1026+
tweakIngress: func(ing *networking.Ingress) {
1027+
ing.Spec.Rules[0].Host = "*"
1028+
},
1029+
expectErrsOnFields: []string{
1030+
"spec.rules[0].host",
1031+
},
1032+
},
10111033
}
10121034

10131035
for name, testCase := range testCases {
@@ -1683,6 +1705,24 @@ func TestValidateIngressTLS(t *testing.T) {
16831705
}
16841706
}
16851707
}
1708+
1709+
// Test for wildcard host and wildcard TLS
1710+
validCases := map[string]networking.Ingress{}
1711+
wildHost := "*.bar.com"
1712+
goodWildcardTLS := newValid()
1713+
goodWildcardTLS.Spec.Rules[0].Host = "*.bar.com"
1714+
goodWildcardTLS.Spec.TLS = []networking.IngressTLS{
1715+
{
1716+
Hosts: []string{wildHost},
1717+
},
1718+
}
1719+
validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS
1720+
for k, v := range validCases {
1721+
errs := validateIngress(&v, IngressValidationOptions{requireRegexPath: true}, networkingv1beta1.SchemeGroupVersion)
1722+
if len(errs) != 0 {
1723+
t.Errorf("expected success for %q", k)
1724+
}
1725+
}
16861726
}
16871727

16881728
func TestValidateIngressStatusUpdate(t *testing.T) {

staging/src/k8s.io/api/extensions/v1beta1/generated.proto

Lines changed: 18 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/api/extensions/v1beta1/types.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -633,18 +633,28 @@ type IngressStatus struct {
633633
// the related backend services. Incoming requests are first evaluated for a host
634634
// match, then routed to the backend associated with the matching IngressRuleValue.
635635
type IngressRule struct {
636-
// Host is the fully qualified domain name of a network host, as defined
637-
// by RFC 3986. Note the following deviations from the "host" part of the
638-
// URI as defined in the RFC:
639-
// 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the
640-
// IP in the Spec of the parent Ingress.
636+
// Host is the fully qualified domain name of a network host, as defined by RFC 3986.
637+
// Note the following deviations from the "host" part of the
638+
// URI as defined in RFC 3986:
639+
// 1. IPs are not allowed. Currently an IngressRuleValue can only apply to
640+
// the IP in the Spec of the parent Ingress.
641641
// 2. The `:` delimiter is not respected because ports are not allowed.
642642
// Currently the port of an Ingress is implicitly :80 for http and
643643
// :443 for https.
644644
// Both these may change in the future.
645-
// Incoming requests are matched against the host before the IngressRuleValue.
646-
// If the host is unspecified, the Ingress routes all traffic based on the
647-
// specified IngressRuleValue.
645+
// Incoming requests are matched against the host before the
646+
// IngressRuleValue. If the host is unspecified, the Ingress routes all
647+
// traffic based on the specified IngressRuleValue.
648+
//
649+
// Host can be "precise" which is a domain name without the terminating dot of
650+
// a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name
651+
// prefixed with a single wildcard label (e.g. "*.foo.com").
652+
// The wildcard character '*' must appear by itself as the first DNS label and
653+
// matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*").
654+
// Requests will be matched against the Host field in the following way:
655+
// 1. If Host is precise, the request matches this rule if the http host header is equal to Host.
656+
// 2. If Host is a wildcard, then the request matches this rule if the http host header
657+
// is to equal to the suffix (removing the first label) of the wildcard rule.
648658
// +optional
649659
Host string `json:"host,omitempty" protobuf:"bytes,1,opt,name=host"`
650660
// IngressRuleValue represents a rule to route requests for this IngressRule.

staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/api/networking/v1beta1/generated.proto

Lines changed: 18 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)