istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/config/xds/xds.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 xds 16 17 import ( 18 "errors" 19 "fmt" 20 21 bootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3" 22 cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 23 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 24 listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" 25 route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" 26 hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" 27 "google.golang.org/protobuf/proto" 28 "google.golang.org/protobuf/types/known/structpb" 29 30 networking "istio.io/api/networking/v1alpha3" 31 "istio.io/istio/pkg/util/protomarshal" 32 ) 33 34 // nolint: interfacer 35 func BuildXDSObjectFromStruct(applyTo networking.EnvoyFilter_ApplyTo, value *structpb.Struct, strict bool) (proto.Message, error) { 36 if value == nil { 37 // for remove ops 38 return nil, nil 39 } 40 var obj proto.Message 41 switch applyTo { 42 case networking.EnvoyFilter_CLUSTER: 43 obj = &cluster.Cluster{} 44 case networking.EnvoyFilter_LISTENER: 45 obj = &listener.Listener{} 46 case networking.EnvoyFilter_ROUTE_CONFIGURATION: 47 obj = &route.RouteConfiguration{} 48 case networking.EnvoyFilter_FILTER_CHAIN: 49 obj = &listener.FilterChain{} 50 case networking.EnvoyFilter_HTTP_FILTER: 51 obj = &hcm.HttpFilter{} 52 case networking.EnvoyFilter_NETWORK_FILTER: 53 obj = &listener.Filter{} 54 case networking.EnvoyFilter_VIRTUAL_HOST: 55 obj = &route.VirtualHost{} 56 case networking.EnvoyFilter_HTTP_ROUTE: 57 obj = &route.Route{} 58 case networking.EnvoyFilter_EXTENSION_CONFIG: 59 obj = &core.TypedExtensionConfig{} 60 case networking.EnvoyFilter_BOOTSTRAP: 61 obj = &bootstrap.Bootstrap{} 62 case networking.EnvoyFilter_LISTENER_FILTER: 63 obj = &listener.ListenerFilter{} 64 default: 65 return nil, fmt.Errorf("Envoy filter: unknown object type for applyTo %s", applyTo.String()) // nolint: stylecheck 66 } 67 68 if err := StructToMessage(value, obj, strict); err != nil { 69 return nil, fmt.Errorf("Envoy filter: %v", err) // nolint: stylecheck 70 } 71 return obj, nil 72 } 73 74 func StructToMessage(pbst *structpb.Struct, out proto.Message, strict bool) error { 75 if pbst == nil { 76 return errors.New("nil struct") 77 } 78 79 buf, err := protomarshal.MarshalProtoNames(pbst) 80 if err != nil { 81 return err 82 } 83 84 // If strict is not set, ignore unknown fields as they may be sending versions of 85 // the proto we are not internally using 86 if strict { 87 return protomarshal.Unmarshal(buf, out) 88 } 89 return protomarshal.UnmarshalAllowUnknown(buf, out) 90 }