Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: James Peach <jpeach@vmware.com>
  • Loading branch information
jpeach committed Oct 30, 2020
1 parent 68a6754 commit 0f0ba79
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 162 deletions.
15 changes: 15 additions & 0 deletions internal/protobuf/convert.go
Expand Up @@ -21,6 +21,16 @@ import (
"github.com/golang/protobuf/proto"
)

func AsJSONString(msg proto.Message) string {
marshaller := jsonpb.Marshaler{}
str, err := marshaller.MarshalToString(msg)
if err != nil {
panic(fmt.Sprintf("failed to marshall %T to JSON: %v", msg, err))
}

return str
}

// ConvertTo converts the messge src to the dst by reserializing through JSON.
func ConvertTo(src proto.Message, dst proto.Message) error {
marshaller := jsonpb.Marshaler{}
Expand All @@ -44,3 +54,8 @@ func MustConvertTo(src proto.Message, dst proto.Message) {
panic(err.Error())
}
}

func AnyMessageNameOf(msg proto.Message) string {
a := MustMarshalAny(msg)
return a.TypeUrl
}
199 changes: 97 additions & 102 deletions internal/xds/util.go
Expand Up @@ -18,10 +18,11 @@ import (
"log"
"strings"

envoy_api_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
envoy_api_auth_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2/auth"
envoy_api_core_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
envoy_config_accesslog_v2 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v2"
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_config_filter_http_ext_authz_v2 "github.com/envoyproxy/go-control-plane/envoy/config/filter/http/ext_authz/v2"
envoy_config_filter_http_lua_v2 "github.com/envoyproxy/go-control-plane/envoy/config/filter/http/lua/v2"
Expand Down Expand Up @@ -61,153 +62,147 @@ func ClusterLoadAssignmentName(service types.NamespacedName, portName string) st
return strings.Join(name, "/")
}

// Fixup takes a xDS v3 resource and upgrades any embedded resources
// to xDS v3. This only takes care of resource types that Contour will
// generate.
func Fixup(in proto.Message) proto.Message {
switch msg := in.(type) {
case *envoy_config_listener_v3.Listener:
for i := range msg.ListenerFilters {
msg.ListenerFilters[i] = Fixup(msg.ListenerFilters[i]).(*envoy_config_listener_v3.ListenerFilter)
}
var TypeMapping map[string]string

for _, chain := range msg.FilterChains {
for i := range chain.Filters {
chain.Filters[i].ConfigType = &envoy_config_listener_v3.Filter_TypedConfig{
TypedConfig: Fixup(chain.Filters[i].GetTypedConfig()).(*any.Any),
}
}
func init() {
TypeMapping = make(map[string]string)

if t := chain.GetTransportSocket(); t != nil {
chain.TransportSocket.ConfigType = &envoy_config_core_v3.TransportSocket_TypedConfig{
TypedConfig: Fixup(t.GetTypedConfig()).(*any.Any),
}
}
}
entry := func(from proto.Message, to proto.Message) {
TypeMapping[protobuf.AnyMessageNameOf(from)] = protobuf.AnyMessageNameOf(to)
}

// Fundamental xDS resource types.
entry(&envoy_api_v2.Listener{}, &envoy_config_listener_v3.Listener{})
entry(&envoy_api_v2.Cluster{}, &envoy_config_cluster_v3.Cluster{})
entry(&envoy_api_v2.RouteConfiguration{}, &envoy_config_route_v3.RouteConfiguration{})
entry(&envoy_api_v2.ClusterLoadAssignment{}, &envoy_config_endpoint_v3.ClusterLoadAssignment{})
entry(&envoy_api_auth_v2.Secret{}, &envoy_extensions_transport_sockets_tls_v3.Secret{})

// Other embedded resources used by Contour.
entry(&envoy_config_accesslog_v2.FileAccessLog{},
&envoy_extensions_access_loggers_file_v3.FileAccessLog{})

entry(&envoy_config_filter_http_ext_authz_v2.ExtAuthzPerRoute{},
&envoy_extensions_filters_http_ext_authz_v3.ExtAuthzPerRoute{})

entry(&envoy_config_filter_http_ext_authz_v2.ExtAuthz{},
&envoy_extensions_filters_http_ext_authz_v3.ExtAuthz{})

entry(&envoy_config_filter_http_lua_v2.Lua{},
&envoy_extensions_filters_http_lua_v3.Lua{})

return in
entry(&envoy_api_auth_v2.UpstreamTlsContext{},
&envoy_extensions_transport_sockets_tls_v3.UpstreamTlsContext{})

case *any.Any:
entry(&envoy_api_auth_v2.DownstreamTlsContext{},
&envoy_extensions_transport_sockets_tls_v3.DownstreamTlsContext{})

entry(&envoy_config_filter_network_http_connection_manager_v2.HttpConnectionManager{},
&envoy_extensions_filters_network_http_connection_manager_v3.HttpConnectionManager{})
}

func rewriteAnyMessage(a *any.Any) {
if a != nil {
anyval := ptypes.DynamicAny{}
if err := ptypes.UnmarshalAny(msg, &anyval); err != nil {
panic(fmt.Sprintf("failed to unmarshal %T: %s", msg, err.Error()))
if err := ptypes.UnmarshalAny(a, &anyval); err != nil {
panic(fmt.Sprintf("failed to unmarshal %T: %s", a, err.Error()))
}

return protobuf.MustMarshalAny(Fixup(anyval.Message))

case *envoy_config_listener_v3.Filter:
if c := msg.GetTypedConfig(); c != nil {
msg.ConfigType = &envoy_config_listener_v3.Filter_TypedConfig{
TypedConfig: Fixup(c).(*any.Any),
}
newMsg := protobuf.MustMarshalAny(Rewrite(anyval.Message))
if replacement, ok := TypeMapping[newMsg.TypeUrl]; ok {
newMsg.TypeUrl = replacement
}

return msg
a.TypeUrl = newMsg.TypeUrl
a.Value = newMsg.Value
}
}

case *envoy_config_listener_v3.ListenerFilter:
if c := msg.GetTypedConfig(); c != nil {
msg.ConfigType = &envoy_config_listener_v3.ListenerFilter_TypedConfig{
TypedConfig: Fixup(c).(*any.Any),
}
}
func rewriteConfigSource(s *envoy_api_core_v2.ConfigSource) {
if s != nil {
s.ResourceApiVersion = envoy_api_core_v2.ApiVersion_V3
s.GetApiConfigSource().TransportApiVersion = envoy_api_core_v2.ApiVersion_V3
}
}

func Rewrite(in proto.Message) proto.Message {
switch msg := in.(type) {
case *envoy_api_v2.ClusterLoadAssignment:
return msg
case *envoy_api_auth_v2.Secret:
return msg

case *envoy_config_cluster_v3.Cluster:
case *envoy_api_v2.Cluster:
if e := msg.GetEdsClusterConfig(); e != nil {
e.GetEdsConfig().ResourceApiVersion = envoy_config_core_v3.ApiVersion_V3
e.GetEdsConfig().GetApiConfigSource().TransportApiVersion = envoy_config_core_v3.ApiVersion_V3
rewriteConfigSource(e.GetEdsConfig())
}

if t := msg.GetTransportSocket(); t != nil {
t.ConfigType = &envoy_config_core_v3.TransportSocket_TypedConfig{
TypedConfig: Fixup(t.GetTypedConfig()).(*any.Any),
}
rewriteAnyMessage(t.GetTypedConfig())
}

return msg

case *envoy_config_route_v3.RouteConfiguration:
case *envoy_api_v2.RouteConfiguration:
for _, v := range msg.GetVirtualHosts() {
for _, r := range v.GetRoutes() {
for name, conf := range r.GetTypedPerFilterConfig() {
r.TypedPerFilterConfig[name] = Fixup(conf).(*any.Any)
for _, conf := range r.GetTypedPerFilterConfig() {
rewriteAnyMessage(conf)
}
}
}

return msg

case *envoy_extensions_transport_sockets_tls_v3.Secret:
return msg
case *envoy_api_v2.Listener:
for _, filter := range msg.ListenerFilters {
rewriteAnyMessage(filter.GetTypedConfig())
}

for _, chain := range msg.FilterChains {
for _, filter := range chain.Filters {
rewriteAnyMessage(filter.GetTypedConfig())
}

if t := chain.GetTransportSocket(); t != nil {
rewriteAnyMessage(t.GetTypedConfig())
}
}

for _, a := range msg.AccessLog {
rewriteAnyMessage(a.GetTypedConfig())
}

case *envoy_config_endpoint_v3.ClusterLoadAssignment:
return msg

case *envoy_config_filter_network_http_connection_manager_v2.HttpConnectionManager:
v3 := envoy_extensions_filters_network_http_connection_manager_v3.HttpConnectionManager{}
protobuf.MustConvertTo(msg, &v3)
if r := msg.GetRds(); r != nil {
rewriteConfigSource(r.GetConfigSource())
}

if r := v3.GetRds(); r != nil {
r.GetConfigSource().ResourceApiVersion = envoy_config_core_v3.ApiVersion_V3
r.GetConfigSource().GetApiConfigSource().TransportApiVersion = envoy_config_core_v3.ApiVersion_V3
for _, f := range msg.HttpFilters {
rewriteAnyMessage(f.GetTypedConfig())
}

for _, f := range v3.HttpFilters {
if c := f.GetTypedConfig(); c != nil {
f.ConfigType = &envoy_extensions_filters_network_http_connection_manager_v3.HttpFilter_TypedConfig{
TypedConfig: Fixup(c).(*any.Any),
}
}
for _, l := range msg.AccessLog {
rewriteAnyMessage(l.GetTypedConfig())
}

return &v3
return msg

case *envoy_api_auth_v2.DownstreamTlsContext:
v3 := envoy_extensions_transport_sockets_tls_v3.DownstreamTlsContext{}
protobuf.MustConvertTo(msg, &v3)

for _, s := range v3.GetCommonTlsContext().TlsCertificateSdsSecretConfigs {
s.GetSdsConfig().ResourceApiVersion = envoy_config_core_v3.ApiVersion_V3
s.GetSdsConfig().GetApiConfigSource().TransportApiVersion = envoy_config_core_v3.ApiVersion_V3
for _, s := range msg.GetCommonTlsContext().TlsCertificateSdsSecretConfigs {
rewriteConfigSource(s.GetSdsConfig())
}

return &v3
return msg

case *envoy_api_auth_v2.UpstreamTlsContext:
v3 := envoy_extensions_transport_sockets_tls_v3.UpstreamTlsContext{}
protobuf.MustConvertTo(msg, &v3)

for _, s := range v3.GetCommonTlsContext().TlsCertificateSdsSecretConfigs {
s.GetSdsConfig().ResourceApiVersion = envoy_config_core_v3.ApiVersion_V3
s.GetSdsConfig().GetApiConfigSource().TransportApiVersion = envoy_config_core_v3.ApiVersion_V3
for _, s := range msg.GetCommonTlsContext().TlsCertificateSdsSecretConfigs {
rewriteConfigSource(s.GetSdsConfig())
}

return &v3

case *envoy_config_filter_http_lua_v2.Lua:
v3 := envoy_extensions_filters_http_lua_v3.Lua{}
protobuf.MustConvertTo(msg, &v3)

return &v3

case *envoy_config_filter_http_ext_authz_v2.ExtAuthz:
v3 := envoy_extensions_filters_http_ext_authz_v3.ExtAuthz{}
protobuf.MustConvertTo(msg, &v3)

return &v3

case *envoy_config_filter_http_ext_authz_v2.ExtAuthzPerRoute:
v3 := envoy_extensions_filters_http_ext_authz_v3.ExtAuthzPerRoute{}
protobuf.MustConvertTo(msg, &v3)

return &v3

case *envoy_config_accesslog_v2.FileAccessLog:
v3 := envoy_extensions_access_loggers_file_v3.FileAccessLog{}
protobuf.MustConvertTo(msg, &v3)

return &v3
return msg

default:
log.Printf("missing conversion for %T, good luck", msg)
Expand Down
2 changes: 1 addition & 1 deletion internal/xds/v2/contour.go
Expand Up @@ -118,7 +118,7 @@ func (s *contourServer) stream(st grpcStream) error {
}

log = log.WithField("resource_names", req.ResourceNames).WithField("type_url", req.TypeUrl)
log.Info("handling xDS resource request")
log.Info("handling v2 xDS resource request")

// now we wait for a notification, if this is the first request received on this
// connection last will be less than zero and that will trigger a response immediately.
Expand Down

0 comments on commit 0f0ba79

Please sign in to comment.