// Copyright 2020 Envoyproxy 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 example import ( "time" "github.com/golang/protobuf/ptypes" cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" router "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3" hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "github.com/envoyproxy/go-control-plane/pkg/cache/types" "github.com/envoyproxy/go-control-plane/pkg/cache/v3" "github.com/envoyproxy/go-control-plane/pkg/resource/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" ) const ( ClusterName = "example_proxy_cluster" RouteName = "local_route" ListenerName = "listener_0" ListenerPort = 10000 UpstreamHost = "service1" UpstreamPort = 8080 ) func makeCluster(clusterName string) *cluster.Cluster { return &cluster.Cluster{ Name: clusterName, ConnectTimeout: ptypes.DurationProto(5 * time.Second), ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_LOGICAL_DNS}, LbPolicy: cluster.Cluster_ROUND_ROBIN, LoadAssignment: makeEndpoint(clusterName), DnsLookupFamily: cluster.Cluster_V4_ONLY, } } func makeEndpoint(clusterName string) *endpoint.ClusterLoadAssignment { return &endpoint.ClusterLoadAssignment{ ClusterName: clusterName, Endpoints: []*endpoint.LocalityLbEndpoints{{ LbEndpoints: []*endpoint.LbEndpoint{{ HostIdentifier: &endpoint.LbEndpoint_Endpoint{ Endpoint: &endpoint.Endpoint{ Address: &core.Address{ Address: &core.Address_SocketAddress{ SocketAddress: &core.SocketAddress{ Protocol: core.SocketAddress_TCP, Address: UpstreamHost, PortSpecifier: &core.SocketAddress_PortValue{ PortValue: UpstreamPort, }, }, }, }, }, }, }}, }}, } } func makeRoute(routeName string, clusterName string) *route.RouteConfiguration { return &route.RouteConfiguration{ Name: routeName, VirtualHosts: []*route.VirtualHost{{ Name: "local_service", Domains: []string{"*"}, Routes: []*route.Route{{ Match: &route.RouteMatch{ PathSpecifier: &route.RouteMatch_Prefix{ Prefix: "/", }, }, Action: &route.Route_Route{ Route: &route.RouteAction{ ClusterSpecifier: &route.RouteAction_Cluster{ Cluster: clusterName, }, }, }, }}, }}, } } func makeHTTPListener(listenerName string, route string) *listener.Listener { router := &router.Router{} routerpb, err := ptypes.MarshalAny(router) if err != nil { panic(err) } // HTTP filter configuration manager := &hcm.HttpConnectionManager{ CodecType: hcm.HttpConnectionManager_AUTO, StatPrefix: "http", RouteSpecifier: &hcm.HttpConnectionManager_Rds{ Rds: &hcm.Rds{ ConfigSource: makeConfigSource(), RouteConfigName: route, }, }, HttpFilters: []*hcm.HttpFilter{{ Name: wellknown.Router, ConfigType: &hcm.HttpFilter_TypedConfig{ TypedConfig: routerpb, }, }}, } pbst, err := ptypes.MarshalAny(manager) if err != nil { panic(err) } return &listener.Listener{ Name: listenerName, Address: &core.Address{ Address: &core.Address_SocketAddress{ SocketAddress: &core.SocketAddress{ Protocol: core.SocketAddress_TCP, Address: "0.0.0.0", PortSpecifier: &core.SocketAddress_PortValue{ PortValue: ListenerPort, }, }, }, }, FilterChains: []*listener.FilterChain{{ Filters: []*listener.Filter{{ Name: wellknown.HTTPConnectionManager, ConfigType: &listener.Filter_TypedConfig{ TypedConfig: pbst, }, }}, }}, } } func makeConfigSource() *core.ConfigSource { source := &core.ConfigSource{} source.ResourceApiVersion = resource.DefaultAPIVersion source.ConfigSourceSpecifier = &core.ConfigSource_ApiConfigSource{ ApiConfigSource: &core.ApiConfigSource{ TransportApiVersion: resource.DefaultAPIVersion, ApiType: core.ApiConfigSource_GRPC, SetNodeOnFirstMessageOnly: true, GrpcServices: []*core.GrpcService{{ TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "xds_cluster"}, }, }}, }, } return source } func GenerateSnapshot() cache.Snapshot { return cache.NewSnapshot( "1", []types.Resource{}, // endpoints []types.Resource{makeCluster(ClusterName)}, []types.Resource{makeRoute(RouteName, ClusterName)}, []types.Resource{makeHTTPListener(ListenerName, RouteName)}, []types.Resource{}, // runtimes []types.Resource{}, // secrets []types.Resource{}, // extensions configs ) }