Skip to content

Commit

Permalink
Handle the case when ingress name has dot (#532)
Browse files Browse the repository at this point in the history
* handle the case when ingress name has dot

* address comment

* fix typo
  • Loading branch information
Zhimin Xiang committed Mar 6, 2021
1 parent 1f5e664 commit eebb4e6
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
38 changes: 32 additions & 6 deletions pkg/reconciler/ingress/resources/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"hash/adler32"
"regexp"
"sort"
"strings"

Expand All @@ -41,7 +42,11 @@ import (
)

// GatewayHTTPPort is the HTTP port the gateways listen on.
const GatewayHTTPPort = 80
const (
GatewayHTTPPort = 80
dns1123LabelMaxLength = 63 // Public for testing only.
dns1123LabelFmt = "[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?"
)

var httpServerPortName = "http-server"

Expand All @@ -58,6 +63,8 @@ var placeholderServer = istiov1alpha3.Server{
},
}

var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")

// GetServers gets the `Servers` from `Gateway` that belongs to the given Ingress.
func GetServers(gateway *v1alpha3.Gateway, ing *v1alpha1.Ingress) []*istiov1alpha3.Server {
servers := []*istiov1alpha3.Server{}
Expand Down Expand Up @@ -87,7 +94,7 @@ func belongsToIngress(server *istiov1alpha3.Server, ing *v1alpha1.Ingress) bool
if len(portNameSplits) != 2 {
return false
}
return portNameSplits[0] == ing.GetNamespace()+"/"+ing.GetName()
return portNameSplits[0] == portNamePrefix(ing.GetNamespace(), ing.GetName())
}

// SortServers sorts `Server` according to its port name.
Expand Down Expand Up @@ -189,6 +196,16 @@ func makeWildcardGateways(ctx context.Context, originWildcardSecrets map[string]
return gateways, nil
}

// IsDNS1123Label tests for a string that conforms to the definition of a label in
// DNS (RFC 1123).
// This function is copied from https://github.com/istio/istio/blob/806fb24bc121bf93ea06f6a38b7ccb3d78d1f326/pkg/config/labels/instance.go#L97
// We directly copy this function instead of importing it into vendor and using it because
// if this function is changed in the upstream (for example, Istio allows the dot in the future), we don't want to
// import the change without awareness because it could break the compatibility of Gateway name generation.
func isDNS1123Label(value string) bool {
return len(value) <= dns1123LabelMaxLength && dns1123LabelRegexp.MatchString(value)
}

// WildcardGatewayName creates the name of wildcard Gateway.
func WildcardGatewayName(secretName, gatewayServiceNamespace, gatewayServiceName string) string {
return fmt.Sprintf("wildcard-%x", adler32.Checksum([]byte(secretName+"-"+gatewayServiceNamespace+"-"+gatewayServiceName)))
Expand Down Expand Up @@ -263,8 +280,12 @@ func getGatewayServices(ctx context.Context, svcLister corev1listers.ServiceList
// GatewayName create a name for the Gateway that is built based on the given Ingress and bonds to the
// given ingress gateway service.
func GatewayName(accessor kmeta.Accessor, gatewaySvc *corev1.Service) string {
prefix := accessor.GetName()
if !isDNS1123Label(prefix) {
prefix = fmt.Sprint(adler32.Checksum([]byte(prefix)))
}
gatewayServiceKey := fmt.Sprintf("%s/%s", gatewaySvc.Namespace, gatewaySvc.Name)
return fmt.Sprint(accessor.GetName()+"-", adler32.Checksum([]byte(gatewayServiceKey)))
return fmt.Sprint(prefix+"-", adler32.Checksum([]byte(gatewayServiceKey)))
}

// MakeTLSServers creates the expected Gateway TLS `Servers` based on the given IngressTLS.
Expand All @@ -284,12 +305,10 @@ func MakeTLSServers(ing *v1alpha1.Ingress, ingressTLS []v1alpha1.IngressTLS, gat
credentialName = targetSecret(originSecret, ing)
}

port := ing.GetNamespace() + "/" + ing.GetName()

servers[i] = &istiov1alpha3.Server{
Hosts: tls.Hosts,
Port: &istiov1alpha3.Port{
Name: fmt.Sprintf("%s:%d", port, i),
Name: fmt.Sprintf(portNamePrefix(ing.GetNamespace(), ing.GetName())+":%d", i),
Number: 443,
Protocol: "HTTPS",
},
Expand All @@ -304,6 +323,13 @@ func MakeTLSServers(ing *v1alpha1.Ingress, ingressTLS []v1alpha1.IngressTLS, gat
return SortServers(servers), nil
}

func portNamePrefix(prefix, suffix string) string {
if !isDNS1123Label(suffix) {
suffix = fmt.Sprint(adler32.Checksum([]byte(suffix)))
}
return prefix + "/" + suffix
}

// MakeHTTPServer creates a HTTP Gateway `Server` based on the HTTPProtocol
// configuration.
func MakeHTTPServer(httpProtocol network.HTTPProtocol, hosts []string) *istiov1alpha3.Server {
Expand Down
49 changes: 49 additions & 0 deletions pkg/reconciler/ingress/resources/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ var ingressResource = v1alpha1.Ingress{
Spec: ingressSpec,
}

var ingressResourceWithDotName = v1alpha1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "ingress.com",
Namespace: "test-ns",
},
Spec: ingressSpec,
}

func TestGetServers(t *testing.T) {
servers := GetServers(&gateway, &ingressResource)
expected := []*istiov1alpha3.Server{{
Expand Down Expand Up @@ -799,6 +807,47 @@ func TestMakeIngressTLSGateways(t *testing.T) {
}},
},
}},
}, {
name: "ingress name has dot",

ia: &ingressResourceWithDotName,
originSecrets: originSecrets,
gatewayService: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "istio-ingressgateway",
Namespace: "istio-system",
},
Spec: corev1.ServiceSpec{
Selector: selector,
},
},
want: []*v1alpha3.Gateway{{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%d-%d", adler32.Checksum([]byte("ingress.com")), adler32.Checksum([]byte("istio-system/istio-ingressgateway"))),
Namespace: "test-ns",
OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(&ingressResourceWithDotName)},
Labels: map[string]string{
networking.IngressLabelKey: "ingress.com",
},
},
Spec: istiov1alpha3.Gateway{
Selector: selector,
Servers: []*istiov1alpha3.Server{{
Hosts: []string{"host1.example.com"},
Port: &istiov1alpha3.Port{
Name: fmt.Sprintf("test-ns/%d:0", adler32.Checksum([]byte("ingress.com"))),
Number: 443,
Protocol: "HTTPS",
},
Tls: &istiov1alpha3.ServerTLSSettings{
Mode: istiov1alpha3.ServerTLSSettings_SIMPLE,
ServerCertificate: corev1.TLSCertKey,
PrivateKey: corev1.TLSPrivateKeyKey,
CredentialName: targetSecret(&secret, &ingressResourceWithDotName),
},
}},
},
}},
}, {
name: "error to make gateway because of incorrect originSecrets",
ia: &ingressResource,
Expand Down

0 comments on commit eebb4e6

Please sign in to comment.