Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-1.22] xds: push CDS on AUTO_PASSTHROUGH Gateway change #50981

11 changes: 11 additions & 0 deletions pilot/pkg/model/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ type Proxy struct {
// The merged gateways associated with the proxy if this is a Router
MergedGateway *MergedGateway

// PrevMergedGateway contains information about merged gateway associated with the proxy previously
PrevMergedGateway *PrevMergedGateway

// ServiceTargets contains a list of all Services associated with the proxy, contextualized for this particular proxy.
// These are unique to this proxy, as the port information is specific to it - while a ServicePort is shared with the
// service, the target port may be distinct per-endpoint. So this maintains a view specific to this proxy.
Expand Down Expand Up @@ -560,7 +563,15 @@ func (node *Proxy) SetGatewaysForProxy(ps *PushContext) {
if node.Type != Router {
return
}
var prevMergedGateway MergedGateway
if node.MergedGateway != nil {
prevMergedGateway = *node.MergedGateway
}
node.MergedGateway = ps.mergeGateways(node)
node.PrevMergedGateway = &PrevMergedGateway{
ContainsAutoPassthroughGateways: prevMergedGateway.ContainsAutoPassthroughGateways,
AutoPassthroughSNIHosts: prevMergedGateway.GetAutoPassthrughGatewaySNIHosts(),
}
}

func (node *Proxy) SetServiceTargets(serviceDiscovery ServiceDiscovery) {
Expand Down
45 changes: 45 additions & 0 deletions pilot/pkg/model/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,34 @@ type MergedGateway struct {
VerifiedCertificateReferences sets.String
}

func (g *MergedGateway) HasAutoPassthroughGateways() bool {
if g != nil {
return g.ContainsAutoPassthroughGateways
}
return false
}

// PrevMergedGateway describes previous state of the gateway.
// Currently, it only contains information relevant for CDS.
type PrevMergedGateway struct {
ContainsAutoPassthroughGateways bool
AutoPassthroughSNIHosts sets.Set[string]
}

func (g *PrevMergedGateway) HasAutoPassthroughGateway() bool {
if g != nil {
return g.ContainsAutoPassthroughGateways
}
return false
}

func (g *PrevMergedGateway) GetAutoPassthroughSNIHosts() sets.Set[string] {
if g != nil {
return g.AutoPassthroughSNIHosts
}
return sets.Set[string]{}
}

var (
typeTag = monitoring.CreateLabel("type")
nameTag = monitoring.CreateLabel("name")
Expand Down Expand Up @@ -348,6 +376,23 @@ func MergeGateways(gateways []gatewayWithInstances, proxy *Proxy, ps *PushContex
}
}

func (g *MergedGateway) GetAutoPassthrughGatewaySNIHosts() sets.Set[string] {
hosts := sets.Set[string]{}
if g == nil {
return hosts
}
if g.ContainsAutoPassthroughGateways {
for _, tls := range g.MergedServers {
for _, s := range tls.Servers {
if s.GetTls().GetMode() == networking.ServerTLSSettings_AUTO_PASSTHROUGH {
hosts.InsertAll(s.Hosts...)
}
}
}
}
return hosts
}

func udpSupportedPort(number uint32, instances []ServiceTarget) bool {
for _, w := range instances {
if int(number) == w.Port.Port && w.Port.Protocol == protocol.UDP {
Expand Down
65 changes: 65 additions & 0 deletions pilot/pkg/model/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

networking "istio.io/api/networking/v1alpha3"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/util/sets"
)

// nolint lll
Expand Down Expand Up @@ -160,6 +161,70 @@ func TestMergeGateways(t *testing.T) {
}
}

func TestGetAutoPassthroughSNIHosts(t *testing.T) {
gateway := config.Config{
Meta: config.Meta{
Name: "gateway",
Namespace: "istio-system",
},
Spec: &networking.Gateway{
Selector: map[string]string{"istio": "ingressgateway"},
Servers: []*networking.Server{
{
Hosts: []string{"static.example.com"},
Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
},
{
Hosts: []string{"www.example.com"},
Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_SIMPLE},
},
{
Hosts: []string{"a.apps.svc.cluster.local", "b.apps.svc.cluster.local"},
Port: &networking.Port{Name: "tls", Number: 15443, Protocol: "TLS"},
Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_AUTO_PASSTHROUGH},
},
},
},
}
svc := &Service{
Attributes: ServiceAttributes{
Labels: map[string]string{},
},
}
gatewayServiceTargets := []ServiceTarget{
{
Service: svc,
Port: ServiceInstancePort{
ServicePort: &Port{Port: 80},
TargetPort: 80,
},
},
{
Service: svc,
Port: ServiceInstancePort{
ServicePort: &Port{Port: 443},
TargetPort: 443,
},
},
{
Service: svc,
Port: ServiceInstancePort{
ServicePort: &Port{Port: 15443},
TargetPort: 15443,
},
},
}
instances := []gatewayWithInstances{{gateway: gateway, instances: gatewayServiceTargets}}
mgw := MergeGateways(instances, &Proxy{}, nil)
hosts := mgw.GetAutoPassthrughGatewaySNIHosts()
expectedHosts := sets.Set[string]{}
expectedHosts.InsertAll("a.apps.svc.cluster.local", "b.apps.svc.cluster.local")
if !hosts.Equals(expectedHosts) {
t.Errorf("expected to get: [a.apps.svc.cluster.local,b.apps.svc.cluster.local], got: %s", hosts.String())
}
}

func makeConfig(name, namespace, host, portName, portProtocol string, portNumber uint32, gw string, bind string,
mode networking.ServerTLSSettings_TLSmode,
) config.Config {
Expand Down
12 changes: 10 additions & 2 deletions pilot/pkg/xds/cds.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@ func cdsNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool {
if len(req.ConfigsUpdated) == 0 {
return true
}

autoPassthroughModeChanged := proxy.MergedGateway.HasAutoPassthroughGateways() != proxy.PrevMergedGateway.HasAutoPassthroughGateway()
autoPassthroughHostsChanged := !proxy.MergedGateway.GetAutoPassthrughGatewaySNIHosts().Equals(proxy.PrevMergedGateway.GetAutoPassthroughSNIHosts())
for config := range req.ConfigsUpdated {
if features.FilterGatewayClusterConfig && proxy.Type == model.Router {
if _, f := pushCdsGatewayConfig[config.Kind]; f {
if proxy.Type == model.Router {
if features.FilterGatewayClusterConfig {
if _, f := pushCdsGatewayConfig[config.Kind]; f {
return true
}
}
if config.Kind == kind.Gateway && (autoPassthroughModeChanged || autoPassthroughHostsChanged) {
return true
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: release-notes/v2
kind: bug-fix
area: traffic-management
releaseNotes:
- |
**Fixed** returning 503 errors by auto-passthrough gateways created after enabling mTLS.