snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / vet-proto (push) Failing after 1s
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
Stale bot / stale (push) Failing after 0s
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / vet-proto (push) Failing after 1s
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
Stale bot / stale (push) Failing after 0s
This commit is contained in:
164
internal/xds/xdsclient/xdsresource/metadata.go
Normal file
164
internal/xds/xdsclient/xdsresource/metadata.go
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2025 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package xdsresource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
|
||||
"google.golang.org/grpc/internal/envconfig"
|
||||
"google.golang.org/grpc/internal/xds/xdsclient/xdsresource/version"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
v3gcpauthnpb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/gcp_authn/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if envconfig.XDSHTTPConnectEnabled {
|
||||
registerMetadataConverter(version.V3AddressURL, proxyAddressConverter{})
|
||||
}
|
||||
if envconfig.GCPAuthenticationFilterEnabled {
|
||||
registerMetadataConverter(version.V3AudienceURL, audienceConverter{})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// metadataRegistry is a map from proto type to metadataConverter.
|
||||
metadataRegistry = make(map[string]metadataConverter)
|
||||
)
|
||||
|
||||
// metadataConverter converts xds metadata entries in
|
||||
// Metadata.typed_filter_metadata into an internal form with the fields relevant
|
||||
// to gRPC.
|
||||
type metadataConverter interface {
|
||||
// convert parses the Any proto into a concrete struct.
|
||||
convert(*anypb.Any) (any, error)
|
||||
}
|
||||
|
||||
// registerMetadataConverter registers the converter to the map keyed on a proto
|
||||
// type_url. Must be called at init time. Not thread safe.
|
||||
func registerMetadataConverter(protoType string, c metadataConverter) {
|
||||
metadataRegistry[protoType] = c
|
||||
}
|
||||
|
||||
// metadataConverterForType retrieves a converter based on key given.
|
||||
func metadataConverterForType(typeURL string) metadataConverter {
|
||||
return metadataRegistry[typeURL]
|
||||
}
|
||||
|
||||
// RegisterMetadataConverterForTesting registers the converter for testing
|
||||
// purposes and returns a cleanup function to restore the registry to its
|
||||
// previous state.
|
||||
func RegisterMetadataConverterForTesting(typeURL string) (func(), error) {
|
||||
var conv metadataConverter
|
||||
switch typeURL {
|
||||
case version.V3AddressURL:
|
||||
conv = proxyAddressConverter{}
|
||||
case version.V3AudienceURL:
|
||||
conv = audienceConverter{}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown typeURL for testing: %s", typeURL)
|
||||
}
|
||||
curConverter, found := metadataRegistry[typeURL]
|
||||
registerMetadataConverter(typeURL, conv)
|
||||
return func() {
|
||||
if found {
|
||||
metadataRegistry[typeURL] = curConverter
|
||||
return
|
||||
}
|
||||
delete(metadataRegistry, typeURL)
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UnregisterMetadataConverterForTesting unregisters the converter for testing
|
||||
// purposes and returns a cleanup function to restore the registry to its
|
||||
// previous state.
|
||||
func UnregisterMetadataConverterForTesting(typeURL string) func() {
|
||||
curConverter, found := metadataRegistry[typeURL]
|
||||
delete(metadataRegistry, typeURL)
|
||||
return func() {
|
||||
if found {
|
||||
metadataRegistry[typeURL] = curConverter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StructMetadataValue stores the values in a google.protobuf.Struct from
|
||||
// FilterMetadata.
|
||||
type StructMetadataValue struct {
|
||||
// Data stores the parsed JSON representation of a google.protobuf.Struct.
|
||||
Data map[string]any
|
||||
}
|
||||
|
||||
// ProxyAddressMetadataValue holds the address parsed from the
|
||||
// envoy.config.core.v3.Address proto message, as specified in gRFC A86.
|
||||
type ProxyAddressMetadataValue struct {
|
||||
// Address stores the proxy address configured (A86). It will be in the form
|
||||
// of host:port. It has to be either IPv6 or IPv4.
|
||||
Address string
|
||||
}
|
||||
|
||||
// proxyAddressConvertor implements the metadataConverter interface to handle
|
||||
// the conversion of envoy.config.core.v3.Address protobuf messages into an
|
||||
// internal representation.
|
||||
type proxyAddressConverter struct{}
|
||||
|
||||
func (proxyAddressConverter) convert(anyProto *anypb.Any) (any, error) {
|
||||
addressProto := &v3corepb.Address{}
|
||||
if err := anyProto.UnmarshalTo(addressProto); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal resource from Any proto: %v", err)
|
||||
}
|
||||
socketaddress := addressProto.GetSocketAddress()
|
||||
if socketaddress == nil {
|
||||
return nil, fmt.Errorf("no socket_address field in metadata")
|
||||
}
|
||||
if _, err := netip.ParseAddr(socketaddress.GetAddress()); err != nil {
|
||||
return nil, fmt.Errorf("address field is not a valid IPv4 or IPv6 address: %q", socketaddress.GetAddress())
|
||||
}
|
||||
portvalue := socketaddress.GetPortValue()
|
||||
if portvalue == 0 {
|
||||
return nil, fmt.Errorf("port value not set in socket_address")
|
||||
}
|
||||
return ProxyAddressMetadataValue{Address: parseAddress(socketaddress)}, nil
|
||||
}
|
||||
|
||||
// AudienceMetadataValue holds the audience parsed from the
|
||||
// envoy.extensions.filters.http.gcp_authn.v3.Audience proto message, as
|
||||
// specified in gRFC A83.
|
||||
type AudienceMetadataValue struct {
|
||||
// Audience is the URL of the receiving service that performs token
|
||||
// authentication.
|
||||
Audience string
|
||||
}
|
||||
|
||||
// audienceConverter implements the metadataConverter interface to
|
||||
// handle the conversion of envoy.extensions.filters.http.gcp_authn.v3.Audience
|
||||
// protobuf messages into an internal representation.
|
||||
type audienceConverter struct{}
|
||||
|
||||
func (audienceConverter) convert(anyProto *anypb.Any) (any, error) {
|
||||
audienceProto := &v3gcpauthnpb.Audience{}
|
||||
if err := anyProto.UnmarshalTo(audienceProto); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal the envoy.extensions.filters.http.gcp_authn.v3.Audience resource from Any proto: %v", err)
|
||||
}
|
||||
if audienceProto.GetUrl() == "" {
|
||||
return nil, fmt.Errorf("empty url field in audience metadata")
|
||||
}
|
||||
return AudienceMetadataValue{Audience: audienceProto.GetUrl()}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user