inject gateway addons to destination clusters (#13951)

This commit is contained in:
Dhia Ayachi 2022-07-28 15:17:35 -04:00 committed by GitHub
parent 08b94640bc
commit 09340a846c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 167 additions and 4 deletions

View File

@ -328,10 +328,11 @@ func TestConfigSnapshotTerminatingGatewayDestinations(t testing.T, populateDesti
roots, _ := TestCerts(t)
var (
externalIPTCP = structs.NewServiceName("external-IP-TCP", nil)
externalHostnameTCP = structs.NewServiceName("external-hostname-TCP", nil)
externalIPHTTP = structs.NewServiceName("external-IP-HTTP", nil)
externalHostnameHTTP = structs.NewServiceName("external-hostname-HTTP", nil)
externalIPTCP = structs.NewServiceName("external-IP-TCP", nil)
externalHostnameTCP = structs.NewServiceName("external-hostname-TCP", nil)
externalIPHTTP = structs.NewServiceName("external-IP-HTTP", nil)
externalHostnameHTTP = structs.NewServiceName("external-hostname-HTTP", nil)
externalHostnameWithSNI = structs.NewServiceName("external-hostname-with-SNI", nil)
)
baseEvents := []UpdateEvent{
@ -367,6 +368,12 @@ func TestConfigSnapshotTerminatingGatewayDestinations(t testing.T, populateDesti
Service: externalHostnameHTTP,
ServiceKind: structs.GatewayServiceKindDestination,
},
&structs.GatewayService{
Service: externalHostnameWithSNI,
ServiceKind: structs.GatewayServiceKindDestination,
CAFile: "cert.pem",
SNI: "api.test.com",
},
)
baseEvents = testSpliceEvents(baseEvents, []UpdateEvent{
@ -393,6 +400,10 @@ func TestConfigSnapshotTerminatingGatewayDestinations(t testing.T, populateDesti
CorrelationID: serviceIntentionsIDPrefix + externalHostnameHTTP.String(),
Result: structs.Intentions{},
},
{
CorrelationID: serviceIntentionsIDPrefix + externalHostnameWithSNI.String(),
Result: structs.Intentions{},
},
// ========
{
CorrelationID: serviceLeafIDPrefix + externalIPTCP.String(),
@ -422,6 +433,13 @@ func TestConfigSnapshotTerminatingGatewayDestinations(t testing.T, populateDesti
PrivateKeyPEM: "placeholder.key",
},
},
{
CorrelationID: serviceLeafIDPrefix + externalHostnameWithSNI.String(),
Result: &structs.IssuedCert{
CertPEM: "placeholder.crt",
PrivateKeyPEM: "placeholder.key",
},
},
// ========
{
CorrelationID: serviceConfigIDPrefix + externalIPTCP.String(),
@ -474,6 +492,17 @@ func TestConfigSnapshotTerminatingGatewayDestinations(t testing.T, populateDesti
},
},
},
{
CorrelationID: serviceConfigIDPrefix + externalHostnameWithSNI.String(),
Result: &structs.ServiceConfigResponse{
Mode: structs.ProxyModeTransparent,
ProxyConfig: map[string]interface{}{"protocol": "tcp"},
Destination: structs.DestinationConfig{
Addresses: []string{"api.test.com"},
Port: 80,
},
},
},
})
}

View File

@ -559,6 +559,9 @@ func (s *ResourceGenerator) makeDestinationClusters(cfgSnap *proxycfg.ConfigSnap
} else {
cluster = s.makeTerminatingHostnameCluster(cfgSnap, opts)
}
if err := s.injectGatewayDestinationAddons(cfgSnap, cluster, svcName); err != nil {
return nil, err
}
clusters = append(clusters, cluster)
}
}
@ -602,6 +605,32 @@ func (s *ResourceGenerator) injectGatewayServiceAddons(cfgSnap *proxycfg.ConfigS
return nil
}
func (s *ResourceGenerator) injectGatewayDestinationAddons(cfgSnap *proxycfg.ConfigSnapshot, c *envoy_cluster_v3.Cluster, svc structs.ServiceName) error {
switch cfgSnap.Kind {
case structs.ServiceKindTerminatingGateway:
// Context used for TLS origination to the cluster
if mapping, ok := cfgSnap.TerminatingGateway.DestinationServices[svc]; ok && mapping.CAFile != "" {
tlsContext := &envoy_tls_v3.UpstreamTlsContext{
CommonTlsContext: makeCommonTLSContextFromFiles(mapping.CAFile, mapping.CertFile, mapping.KeyFile),
}
if mapping.SNI != "" {
tlsContext.Sni = mapping.SNI
if err := injectSANMatcher(tlsContext.CommonTlsContext, mapping.SNI); err != nil {
return fmt.Errorf("failed to inject SNI matcher into TLS context: %v", err)
}
}
transportSocket, err := makeUpstreamTLSTransportSocket(tlsContext)
if err != nil {
return err
}
c.TransportSocket = transportSocket
}
}
return nil
}
func (s *ResourceGenerator) clustersFromSnapshotIngressGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
var clusters []proto.Message
createdClusters := make(map[proxycfg.UpstreamID]bool)

View File

@ -142,6 +142,57 @@
}
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"name": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"type": "LOGICAL_DNS",
"connectTimeout": "5s",
"loadAssignment": {
"clusterName": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "api.test.com",
"portValue": 80
}
}
}
}
]
}
]
},
"dnsRefreshRate": "10s",
"outlierDetection": {
},
"transportSocket": {
"name": "tls",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
"commonTlsContext": {
"tlsParams": {
},
"validationContext": {
"trustedCa": {
"filename": "cert.pem"
},
"matchSubjectAltNames": [
{
"exact": "api.test.com"
}
]
}
},
"sni": "api.test.com"
}
}
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",

View File

@ -309,6 +309,60 @@
}
}
},
{
"filterChainMatch": {
"serverNames": [
"destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
]
},
"filters": [
{
"name": "envoy.filters.network.rbac",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC",
"rules": {
},
"statPrefix": "connect_authz"
}
},
{
"name": "envoy.filters.network.tcp_proxy",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"statPrefix": "upstream.external-hostname-with-SNI.default.default.dc1",
"cluster": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
}
}
],
"transportSocket": {
"name": "tls",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
"commonTlsContext": {
"tlsParams": {
},
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "placeholder.crt\n"
},
"privateKey": {
"inlineString": "placeholder.key\n"
}
}
],
"validationContext": {
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"requireClientCertificate": true
}
}
},
{
"filterChainMatch": {
"serverNames": [