Skip to content

Commit

Permalink
internal: Copy/paste all files from internal/envoy/v2 to internal/env…
Browse files Browse the repository at this point in the history
…oy/v3

Signed-off-by: Steve Sloka <slokas@vmware.com>
  • Loading branch information
stevesloka committed Nov 11, 2020
1 parent 2885e38 commit 34ea6d2
Show file tree
Hide file tree
Showing 22 changed files with 4,866 additions and 0 deletions.
70 changes: 70 additions & 0 deletions internal/envoy/v3/accesslog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright Project Contour 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 v3

import (
accesslogv2 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v2"
accesslog "github.com/envoyproxy/go-control-plane/envoy/config/filter/accesslog/v2"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
_struct "github.com/golang/protobuf/ptypes/struct"
"github.com/projectcontour/contour/internal/protobuf"
"github.com/projectcontour/contour/pkg/config"
)

// FileAccessLogEnvoy returns a new file based access log filter
// that will output Envoy's default access logs.
func FileAccessLogEnvoy(path string) []*accesslog.AccessLog {
return []*accesslog.AccessLog{{
Name: wellknown.FileAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&accesslogv2.FileAccessLog{
Path: path,
// AccessLogFormat left blank to defer to Envoy's default log format.
}),
},
}}
}

// FileAccessLogJSON returns a new file based access log filter
// that will log in JSON format
func FileAccessLogJSON(path string, fields config.AccessLogFields) []*accesslog.AccessLog {

jsonformat := &_struct.Struct{
Fields: make(map[string]*_struct.Value),
}

for k, v := range fields.AsFieldMap() {
jsonformat.Fields[k] = sv(v)
}

return []*accesslog.AccessLog{{
Name: wellknown.FileAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&accesslogv2.FileAccessLog{
Path: path,
AccessLogFormat: &accesslogv2.FileAccessLog_JsonFormat{
JsonFormat: jsonformat,
},
}),
},
}}
}

func sv(s string) *_struct.Value {
return &_struct.Value{
Kind: &_struct.Value_StringValue{
StringValue: s,
},
}
}
115 changes: 115 additions & 0 deletions internal/envoy/v3/accesslog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright Project Contour 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 v3

import (
"testing"

accesslog_v2 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v2"
envoy_accesslog "github.com/envoyproxy/go-control-plane/envoy/config/filter/accesslog/v2"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
_struct "github.com/golang/protobuf/ptypes/struct"
"github.com/projectcontour/contour/internal/protobuf"
"github.com/projectcontour/contour/pkg/config"
)

func TestFileAccessLog(t *testing.T) {
tests := map[string]struct {
path string
want []*envoy_accesslog.AccessLog
}{
"stdout": {
path: "/dev/stdout",
want: []*envoy_accesslog.AccessLog{{
Name: wellknown.FileAccessLog,
ConfigType: &envoy_accesslog.AccessLog_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&accesslog_v2.FileAccessLog{
Path: "/dev/stdout",
}),
},
}},
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
got := FileAccessLogEnvoy(tc.path)
protobuf.ExpectEqual(t, tc.want, got)
})
}
}

func TestJSONFileAccessLog(t *testing.T) {
tests := map[string]struct {
path string
headers config.AccessLogFields
want []*envoy_accesslog.AccessLog
}{
"only timestamp": {
path: "/dev/stdout",
headers: config.AccessLogFields([]string{"@timestamp"}),
want: []*envoy_accesslog.AccessLog{{
Name: wellknown.FileAccessLog,
ConfigType: &envoy_accesslog.AccessLog_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&accesslog_v2.FileAccessLog{
Path: "/dev/stdout",
AccessLogFormat: &accesslog_v2.FileAccessLog_JsonFormat{
JsonFormat: &_struct.Struct{
Fields: map[string]*_struct.Value{
"@timestamp": sv("%START_TIME%"),
},
},
},
}),
},
},
},
},
"custom fields should appear": {
path: "/dev/stdout",
headers: config.AccessLogFields([]string{
"@timestamp",
"method",
"custom1=%REQ(X-CUSTOM-HEADER)%",
"custom2=%DURATION%.0",
"custom3=ST=%START_TIME(%s.%6f)%",
}),
want: []*envoy_accesslog.AccessLog{{
Name: wellknown.FileAccessLog,
ConfigType: &envoy_accesslog.AccessLog_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&accesslog_v2.FileAccessLog{
Path: "/dev/stdout",
AccessLogFormat: &accesslog_v2.FileAccessLog_JsonFormat{
JsonFormat: &_struct.Struct{
Fields: map[string]*_struct.Value{
"@timestamp": sv("%START_TIME%"),
"method": sv("%REQ(:METHOD)%"),
"custom1": sv("%REQ(X-CUSTOM-HEADER)%"),
"custom2": sv("%DURATION%.0"),
"custom3": sv("ST=%START_TIME(%s.%6f)%"),
},
},
},
}),
},
},
},
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
got := FileAccessLogJSON(tc.path, tc.headers)
protobuf.ExpectEqual(t, tc.want, got)
})
}
}
110 changes: 110 additions & 0 deletions internal/envoy/v3/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright Project Contour 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 v3

import (
envoy_api_v2_auth "github.com/envoyproxy/go-control-plane/envoy/api/v2/auth"
envoy_api_v2_core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
matcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher"
"github.com/projectcontour/contour/internal/dag"
"github.com/projectcontour/contour/internal/envoy"
"github.com/projectcontour/contour/internal/protobuf"
)

// UpstreamTLSContext creates an envoy_api_v2_auth.UpstreamTlsContext. By default
// UpstreamTLSContext returns a HTTP/1.1 TLS enabled context. A list of
// additional ALPN protocols can be provided.
func UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni string, clientSecret *dag.Secret, alpnProtocols ...string) *envoy_api_v2_auth.UpstreamTlsContext {
var clientSecretConfigs []*envoy_api_v2_auth.SdsSecretConfig
if clientSecret != nil {
clientSecretConfigs = []*envoy_api_v2_auth.SdsSecretConfig{{
Name: envoy.Secretname(clientSecret),
SdsConfig: ConfigSource("contour"),
}}
}

context := &envoy_api_v2_auth.UpstreamTlsContext{
CommonTlsContext: &envoy_api_v2_auth.CommonTlsContext{
AlpnProtocols: alpnProtocols,
TlsCertificateSdsSecretConfigs: clientSecretConfigs,
},
Sni: sni,
}

if peerValidationContext.GetCACertificate() != nil && len(peerValidationContext.GetSubjectName()) > 0 {
// We have to explicitly assign the value from validationContext
// to context.CommonTlsContext.ValidationContextType because the
// latter is an interface. Returning nil from validationContext
// directly into this field boxes the nil into the unexported
// type of this grpc OneOf field which causes proto marshaling
// to explode later on.
vc := validationContext(peerValidationContext.GetCACertificate(), peerValidationContext.GetSubjectName())
if vc != nil {
context.CommonTlsContext.ValidationContextType = vc
}
}

return context
}

func validationContext(ca []byte, subjectName string) *envoy_api_v2_auth.CommonTlsContext_ValidationContext {
vc := &envoy_api_v2_auth.CommonTlsContext_ValidationContext{
ValidationContext: &envoy_api_v2_auth.CertificateValidationContext{
TrustedCa: &envoy_api_v2_core.DataSource{
// TODO(dfc) update this for SDS
Specifier: &envoy_api_v2_core.DataSource_InlineBytes{
InlineBytes: ca,
},
},
},
}

if len(subjectName) > 0 {
vc.ValidationContext.MatchSubjectAltNames = []*matcher.StringMatcher{{
MatchPattern: &matcher.StringMatcher_Exact{
Exact: subjectName,
}},
}
}

return vc
}

// DownstreamTLSContext creates a new DownstreamTlsContext.
func DownstreamTLSContext(serverSecret *dag.Secret, tlsMinProtoVersion envoy_api_v2_auth.TlsParameters_TlsProtocol, peerValidationContext *dag.PeerValidationContext, alpnProtos ...string) *envoy_api_v2_auth.DownstreamTlsContext {
context := &envoy_api_v2_auth.DownstreamTlsContext{
CommonTlsContext: &envoy_api_v2_auth.CommonTlsContext{
TlsParams: &envoy_api_v2_auth.TlsParameters{
TlsMinimumProtocolVersion: tlsMinProtoVersion,
TlsMaximumProtocolVersion: envoy_api_v2_auth.TlsParameters_TLSv1_3,
CipherSuites: envoy.Ciphers,
},
TlsCertificateSdsSecretConfigs: []*envoy_api_v2_auth.SdsSecretConfig{{
Name: envoy.Secretname(serverSecret),
SdsConfig: ConfigSource("contour"),
}},
AlpnProtocols: alpnProtos,
},
}

if peerValidationContext.GetCACertificate() != nil {
vc := validationContext(peerValidationContext.GetCACertificate(), "")
if vc != nil {
context.CommonTlsContext.ValidationContextType = vc
context.RequireClientCertificate = protobuf.Bool(true)
}
}

return context
}
Loading

0 comments on commit 34ea6d2

Please sign in to comment.