istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/grpcgen/grpcgen.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package grpcgen
    16  
    17  import (
    18  	tls "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
    19  	matcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
    20  
    21  	"istio.io/istio/pilot/pkg/model"
    22  	"istio.io/istio/pilot/pkg/networking/util"
    23  	v3 "istio.io/istio/pilot/pkg/xds/v3"
    24  	"istio.io/istio/pkg/config/host"
    25  	istiolog "istio.io/istio/pkg/log"
    26  )
    27  
    28  // Support generation of 'ApiListener' LDS responses, used for native support of gRPC.
    29  // The same response can also be used by other apps using XDS directly.
    30  
    31  // GRPC proposal:
    32  // https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md
    33  //
    34  // Note that this implementation is tested against gRPC, but it is generic - any other framework can
    35  // use this XDS mode to get load balancing info from Istio, including MC/VM/etc.
    36  
    37  // The corresponding RDS response is also generated - currently gRPC has special differences
    38  // and can't understand normal Istio RDS - in particular expects "" instead of "/" as
    39  // default prefix, and is expects just the route for one host.
    40  // handleAck will detect if the message is an ACK or NACK, and update/log/count
    41  // using the generic structures. "Classical" CDS/LDS/RDS/EDS use separate logic -
    42  // this is used for the API-based LDS and generic messages.
    43  
    44  var log = istiolog.RegisterScope("grpcgen", "xDS Generator for Proxyless gRPC")
    45  
    46  type GrpcConfigGenerator struct{}
    47  
    48  func clusterKey(hostname string, port int) string {
    49  	return subsetClusterKey("", hostname, port)
    50  }
    51  
    52  func subsetClusterKey(subset, hostname string, port int) string {
    53  	return model.BuildSubsetKey(model.TrafficDirectionOutbound, subset, host.Name(hostname), port)
    54  }
    55  
    56  func (g *GrpcConfigGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
    57  	switch w.TypeUrl {
    58  	case v3.ListenerType:
    59  		return g.BuildListeners(proxy, req.Push, w.ResourceNames), model.DefaultXdsLogDetails, nil
    60  	case v3.ClusterType:
    61  		return g.BuildClusters(proxy, req.Push, w.ResourceNames), model.DefaultXdsLogDetails, nil
    62  	case v3.RouteType:
    63  		return g.BuildHTTPRoutes(proxy, req.Push, w.ResourceNames), model.DefaultXdsLogDetails, nil
    64  	}
    65  
    66  	return nil, model.DefaultXdsLogDetails, nil
    67  }
    68  
    69  // buildCommonTLSContext creates a TLS context that assumes 'default' name, and credentials/tls/certprovider/pemfile
    70  // (see grpc/xds/internal/client/xds.go securityConfigFromCluster).
    71  func buildCommonTLSContext(sans []string) *tls.CommonTlsContext {
    72  	var sanMatch []*matcher.StringMatcher
    73  	if len(sans) > 0 {
    74  		sanMatch = util.StringToExactMatch(sans)
    75  	}
    76  	return &tls.CommonTlsContext{
    77  		TlsCertificateCertificateProviderInstance: &tls.CommonTlsContext_CertificateProviderInstance{
    78  			InstanceName:    "default",
    79  			CertificateName: "default",
    80  		},
    81  		ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{
    82  			CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{
    83  				ValidationContextCertificateProviderInstance: &tls.CommonTlsContext_CertificateProviderInstance{
    84  					InstanceName:    "default",
    85  					CertificateName: "ROOTCA",
    86  				},
    87  				DefaultValidationContext: &tls.CertificateValidationContext{
    88  					MatchSubjectAltNames: sanMatch,
    89  				},
    90  			},
    91  		},
    92  	}
    93  }