From 43f195f54313fd99df1a9fce18f3c717cd89fd67 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Tue, 6 Aug 2024 10:30:00 -0400 Subject: [PATCH 01/39] update api and code --- .../api/grpc/validation/gloo_validation.proto | 16 ++++++++++++++++ projects/gloo/pkg/translator/clusters.go | 2 +- projects/gloo/pkg/translator/filter_chain.go | 2 +- .../pkg/utils/validation/proxy_validation.go | 7 +++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/projects/gloo/api/grpc/validation/gloo_validation.proto b/projects/gloo/api/grpc/validation/gloo_validation.proto index 27e7711df81..388e347de2d 100644 --- a/projects/gloo/api/grpc/validation/gloo_validation.proto +++ b/projects/gloo/api/grpc/validation/gloo_validation.proto @@ -121,9 +121,25 @@ message ListenerReport { string reason = 2; } + // warning types for the given listener config + message Warning { + enum Type { + SSLConfigWarning = 0; + } + + // the type of the error + Type type = 1; + // any extra info as a string + string reason = 2; + } + + // errors on top-level config of the listener repeated Error errors = 2; + // warnings on the top-levelconfig of the listener + repeated Warning warnings = 7; + oneof listener_type_report { // report for the http listener HttpListenerReport http_listener_report = 3; diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index b4cec2d83d1..750845be546 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -122,7 +122,7 @@ func (t *translatorInstance) initializeCluster( applyDefaultsToUpstreamSslConfig(sslConfig, t.settings.GetUpstreamOptions()) cfg, err := utils.NewSslConfigTranslator().ResolveUpstreamSslConfig(*secrets, sslConfig) if err != nil { - reports.AddError(upstream, err) + reports.AddWarning(upstream, err.Error()) } else { typedConfig, err := utils.MessageToAny(cfg) if err != nil { diff --git a/projects/gloo/pkg/translator/filter_chain.go b/projects/gloo/pkg/translator/filter_chain.go index 40f78bc0ef1..00740bc9a1e 100644 --- a/projects/gloo/pkg/translator/filter_chain.go +++ b/projects/gloo/pkg/translator/filter_chain.go @@ -294,7 +294,7 @@ func (h *httpFilterChainTranslator) createFilterChainsFromSslConfiguration( // get secrets downstreamTlsContext, err := h.sslConfigTranslator.ResolveDownstreamSslConfig(snap.Secrets, sslConfig) if err != nil { - validation.AppendListenerError(h.parentReport, validationapi.ListenerReport_Error_SSLConfigError, err.Error()) + validation.AppendListenerWarning(h.parentReport, validationapi.ListenerReport_Warning_SSLConfigWarning, err.Error()) continue } diff --git a/projects/gloo/pkg/utils/validation/proxy_validation.go b/projects/gloo/pkg/utils/validation/proxy_validation.go index 7bb77bf2052..8cc4f9800ce 100644 --- a/projects/gloo/pkg/utils/validation/proxy_validation.go +++ b/projects/gloo/pkg/utils/validation/proxy_validation.go @@ -382,6 +382,13 @@ func AppendListenerError(listenerReport *validation.ListenerReport, errType vali }) } +func AppendListenerWarning(listenerReport *validation.ListenerReport, errType validation.ListenerReport_Warning_Type, reason string) { + listenerReport.Warnings = append(listenerReport.GetWarnings(), &validation.ListenerReport_Warning{ + Type: errType, + Reason: reason, + }) +} + func AppendVirtualHostError(virtualHostReport *validation.VirtualHostReport, errType validation.VirtualHostReport_Error_Type, reason string) { virtualHostReport.Errors = append(virtualHostReport.GetErrors(), &validation.VirtualHostReport_Error{ Type: errType, From bb44d44935dd11f2032c2807d3f49958feab636c Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Tue, 6 Aug 2024 10:36:19 -0400 Subject: [PATCH 02/39] codegen --- .../validation/gloo_validation.proto.sk.md | 36 + .../validation/gloo_validation.pb.clone.go | 28 + .../validation/gloo_validation.pb.equal.go | 49 + .../api/grpc/validation/gloo_validation.pb.go | 872 ++++++++++-------- .../validation/gloo_validation.pb.hash.go | 49 + 5 files changed, 667 insertions(+), 367 deletions(-) diff --git a/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/grpc/validation/gloo_validation.proto.sk.md b/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/grpc/validation/gloo_validation.proto.sk.md index 98f26eb9c10..1ef543f61fe 100644 --- a/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/grpc/validation/gloo_validation.proto.sk.md +++ b/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/grpc/validation/gloo_validation.proto.sk.md @@ -23,6 +23,8 @@ weight: 5 - [ListenerReport](#listenerreport) - [Error](#error) - [Type](#type) +- [Warning](#warning) +- [Type](#type) - [HttpListenerReport](#httplistenerreport) - [Error](#error) - [Type](#type) @@ -232,6 +234,7 @@ If the report contains no errors, the (sub-)resource is valid. ```yaml "errors": []gloo.solo.io.ListenerReport.Error +"warnings": []gloo.solo.io.ListenerReport.Warning "httpListenerReport": .gloo.solo.io.HttpListenerReport "tcpListenerReport": .gloo.solo.io.TcpListenerReport "hybridListenerReport": .gloo.solo.io.HybridListenerReport @@ -242,6 +245,7 @@ If the report contains no errors, the (sub-)resource is valid. | Field | Type | Description | | ----- | ---- | ----------- | | `errors` | [[]gloo.solo.io.ListenerReport.Error](../gloo_validation.proto.sk/#error) | errors on top-level config of the listener. | +| `warnings` | [[]gloo.solo.io.ListenerReport.Warning](../gloo_validation.proto.sk/#warning) | warnings on the top-levelconfig of the listener. | | `httpListenerReport` | [.gloo.solo.io.HttpListenerReport](../gloo_validation.proto.sk/#httplistenerreport) | report for the http listener. Only one of `httpListenerReport`, `tcpListenerReport`, `hybridListenerReport`, or `aggregateListenerReport` can be set. | | `tcpListenerReport` | [.gloo.solo.io.TcpListenerReport](../gloo_validation.proto.sk/#tcplistenerreport) | report for the tcp listener. Only one of `tcpListenerReport`, `httpListenerReport`, `hybridListenerReport`, or `aggregateListenerReport` can be set. | | `hybridListenerReport` | [.gloo.solo.io.HybridListenerReport](../gloo_validation.proto.sk/#hybridlistenerreport) | report for the hybrid listener. Only one of `hybridListenerReport`, `httpListenerReport`, `tcpListenerReport`, or `aggregateListenerReport` can be set. | @@ -285,6 +289,38 @@ error types for top-level listener config +--- +### Warning + + +warning types for the given listener config + +```yaml +"type": .gloo.solo.io.ListenerReport.Warning.Type +"reason": string + +``` + +| Field | Type | Description | +| ----- | ---- | ----------- | +| `type` | [.gloo.solo.io.ListenerReport.Warning.Type](../gloo_validation.proto.sk/#type) | the type of the error. | +| `reason` | `string` | any extra info as a string. | + + + + +--- +### Type + + + +| Name | Description | +| ----- | ----------- | +| `SSLConfigWarning` | | + + + + --- ### HttpListenerReport diff --git a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.clone.go b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.clone.go index 737ef28d1e1..19e7d89fcac 100644 --- a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.clone.go +++ b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.clone.go @@ -297,6 +297,19 @@ func (m *ListenerReport) Clone() proto.Message { } } + if m.GetWarnings() != nil { + target.Warnings = make([]*ListenerReport_Warning, len(m.GetWarnings())) + for idx, v := range m.GetWarnings() { + + if h, ok := interface{}(v).(clone.Cloner); ok { + target.Warnings[idx] = h.Clone().(*ListenerReport_Warning) + } else { + target.Warnings[idx] = proto.Clone(v).(*ListenerReport_Warning) + } + + } + } + switch m.ListenerTypeReport.(type) { case *ListenerReport_HttpListenerReport: @@ -652,6 +665,21 @@ func (m *ListenerReport_Error) Clone() proto.Message { return target } +// Clone function +func (m *ListenerReport_Warning) Clone() proto.Message { + var target *ListenerReport_Warning + if m == nil { + return target + } + target = &ListenerReport_Warning{} + + target.Type = m.GetType() + + target.Reason = m.GetReason() + + return target +} + // Clone function func (m *HttpListenerReport_Error) Clone() proto.Message { var target *HttpListenerReport_Error diff --git a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.equal.go b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.equal.go index 36c2d12af87..88e78fae10d 100644 --- a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.equal.go +++ b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.equal.go @@ -482,6 +482,23 @@ func (m *ListenerReport) Equal(that interface{}) bool { } + if len(m.GetWarnings()) != len(target.GetWarnings()) { + return false + } + for idx, v := range m.GetWarnings() { + + if h, ok := interface{}(v).(equality.Equalizer); ok { + if !h.Equal(target.GetWarnings()[idx]) { + return false + } + } else { + if !proto.Equal(v, target.GetWarnings()[idx]) { + return false + } + } + + } + switch m.ListenerTypeReport.(type) { case *ListenerReport_HttpListenerReport: @@ -1038,6 +1055,38 @@ func (m *ListenerReport_Error) Equal(that interface{}) bool { return true } +// Equal function +func (m *ListenerReport_Warning) Equal(that interface{}) bool { + if that == nil { + return m == nil + } + + target, ok := that.(*ListenerReport_Warning) + if !ok { + that2, ok := that.(ListenerReport_Warning) + if ok { + target = &that2 + } else { + return false + } + } + if target == nil { + return m == nil + } else if m == nil { + return false + } + + if m.GetType() != target.GetType() { + return false + } + + if strings.Compare(m.GetReason(), target.GetReason()) != 0 { + return false + } + + return true +} + // Equal function func (m *HttpListenerReport_Error) Equal(that interface{}) bool { if that == nil { diff --git a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.go b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.go index 9bc1b3edd14..12c0a90d788 100644 --- a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.go +++ b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.go @@ -80,6 +80,49 @@ func (ListenerReport_Error_Type) EnumDescriptor() ([]byte, []int) { return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_rawDescGZIP(), []int{9, 0, 0} } +type ListenerReport_Warning_Type int32 + +const ( + ListenerReport_Warning_SSLConfigWarning ListenerReport_Warning_Type = 0 +) + +// Enum value maps for ListenerReport_Warning_Type. +var ( + ListenerReport_Warning_Type_name = map[int32]string{ + 0: "SSLConfigWarning", + } + ListenerReport_Warning_Type_value = map[string]int32{ + "SSLConfigWarning": 0, + } +) + +func (x ListenerReport_Warning_Type) Enum() *ListenerReport_Warning_Type { + p := new(ListenerReport_Warning_Type) + *p = x + return p +} + +func (x ListenerReport_Warning_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListenerReport_Warning_Type) Descriptor() protoreflect.EnumDescriptor { + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[1].Descriptor() +} + +func (ListenerReport_Warning_Type) Type() protoreflect.EnumType { + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[1] +} + +func (x ListenerReport_Warning_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ListenerReport_Warning_Type.Descriptor instead. +func (ListenerReport_Warning_Type) EnumDescriptor() ([]byte, []int) { + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_rawDescGZIP(), []int{9, 1, 0} +} + type HttpListenerReport_Error_Type int32 const ( @@ -107,11 +150,11 @@ func (x HttpListenerReport_Error_Type) String() string { } func (HttpListenerReport_Error_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[1].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[2].Descriptor() } func (HttpListenerReport_Error_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[1] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[2] } func (x HttpListenerReport_Error_Type) Number() protoreflect.EnumNumber { @@ -159,11 +202,11 @@ func (x VirtualHostReport_Error_Type) String() string { } func (VirtualHostReport_Error_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[2].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[3].Descriptor() } func (VirtualHostReport_Error_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[2] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[3] } func (x VirtualHostReport_Error_Type) Number() protoreflect.EnumNumber { @@ -205,11 +248,11 @@ func (x RouteReport_Error_Type) String() string { } func (RouteReport_Error_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[3].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[4].Descriptor() } func (RouteReport_Error_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[3] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[4] } func (x RouteReport_Error_Type) Number() protoreflect.EnumNumber { @@ -248,11 +291,11 @@ func (x RouteReport_Warning_Type) String() string { } func (RouteReport_Warning_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[4].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[5].Descriptor() } func (RouteReport_Warning_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[4] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[5] } func (x RouteReport_Warning_Type) Number() protoreflect.EnumNumber { @@ -300,11 +343,11 @@ func (x TcpListenerReport_Error_Type) String() string { } func (TcpListenerReport_Error_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[5].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[6].Descriptor() } func (TcpListenerReport_Error_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[5] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[6] } func (x TcpListenerReport_Error_Type) Number() protoreflect.EnumNumber { @@ -350,11 +393,11 @@ func (x TcpHostReport_Error_Type) String() string { } func (TcpHostReport_Error_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[6].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[7].Descriptor() } func (TcpHostReport_Error_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[6] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[7] } func (x TcpHostReport_Error_Type) Number() protoreflect.EnumNumber { @@ -396,11 +439,11 @@ func (x TcpHostReport_Warning_Type) String() string { } func (TcpHostReport_Warning_Type) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[7].Descriptor() + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[8].Descriptor() } func (TcpHostReport_Warning_Type) Type() protoreflect.EnumType { - return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[7] + return &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes[8] } func (x TcpHostReport_Warning_Type) Number() protoreflect.EnumNumber { @@ -935,6 +978,8 @@ type ListenerReport struct { // errors on top-level config of the listener Errors []*ListenerReport_Error `protobuf:"bytes,2,rep,name=errors,proto3" json:"errors,omitempty"` + // warnings on the top-levelconfig of the listener + Warnings []*ListenerReport_Warning `protobuf:"bytes,7,rep,name=warnings,proto3" json:"warnings,omitempty"` // Types that are assignable to ListenerTypeReport: // // *ListenerReport_HttpListenerReport @@ -983,6 +1028,13 @@ func (x *ListenerReport) GetErrors() []*ListenerReport_Error { return nil } +func (x *ListenerReport) GetWarnings() []*ListenerReport_Warning { + if x != nil { + return x.Warnings + } + return nil +} + func (m *ListenerReport) GetListenerTypeReport() isListenerReport_ListenerTypeReport { if m != nil { return m.ListenerTypeReport @@ -1575,6 +1627,64 @@ func (x *ListenerReport_Error) GetReason() string { return "" } +// warning types for the given listener config +type ListenerReport_Warning struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the type of the error + Type ListenerReport_Warning_Type `protobuf:"varint,1,opt,name=type,proto3,enum=gloo.solo.io.ListenerReport_Warning_Type" json:"type,omitempty"` + // any extra info as a string + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *ListenerReport_Warning) Reset() { + *x = ListenerReport_Warning{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListenerReport_Warning) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListenerReport_Warning) ProtoMessage() {} + +func (x *ListenerReport_Warning) ProtoReflect() protoreflect.Message { + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListenerReport_Warning.ProtoReflect.Descriptor instead. +func (*ListenerReport_Warning) Descriptor() ([]byte, []int) { + return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *ListenerReport_Warning) GetType() ListenerReport_Warning_Type { + if x != nil { + return x.Type + } + return ListenerReport_Warning_SSLConfigWarning +} + +func (x *ListenerReport_Warning) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + // error types for top-level http listener config type HttpListenerReport_Error struct { state protoimpl.MessageState @@ -1592,7 +1702,7 @@ type HttpListenerReport_Error struct { func (x *HttpListenerReport_Error) Reset() { *x = HttpListenerReport_Error{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[19] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1605,7 +1715,7 @@ func (x *HttpListenerReport_Error) String() string { func (*HttpListenerReport_Error) ProtoMessage() {} func (x *HttpListenerReport_Error) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[19] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1659,7 +1769,7 @@ type VirtualHostReport_Error struct { func (x *VirtualHostReport_Error) Reset() { *x = VirtualHostReport_Error{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[20] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1672,7 +1782,7 @@ func (x *VirtualHostReport_Error) String() string { func (*VirtualHostReport_Error) ProtoMessage() {} func (x *VirtualHostReport_Error) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[20] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1726,7 +1836,7 @@ type RouteReport_Error struct { func (x *RouteReport_Error) Reset() { *x = RouteReport_Error{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[21] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1739,7 +1849,7 @@ func (x *RouteReport_Error) String() string { func (*RouteReport_Error) ProtoMessage() {} func (x *RouteReport_Error) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[21] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1791,7 +1901,7 @@ type RouteReport_Warning struct { func (x *RouteReport_Warning) Reset() { *x = RouteReport_Warning{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[22] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1804,7 +1914,7 @@ func (x *RouteReport_Warning) String() string { func (*RouteReport_Warning) ProtoMessage() {} func (x *RouteReport_Warning) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[22] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1849,7 +1959,7 @@ type TcpListenerReport_Error struct { func (x *TcpListenerReport_Error) Reset() { *x = TcpListenerReport_Error{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[23] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1862,7 +1972,7 @@ func (x *TcpListenerReport_Error) String() string { func (*TcpListenerReport_Error) ProtoMessage() {} func (x *TcpListenerReport_Error) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[23] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1907,7 +2017,7 @@ type TcpHostReport_Error struct { func (x *TcpHostReport_Error) Reset() { *x = TcpHostReport_Error{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[24] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1920,7 +2030,7 @@ func (x *TcpHostReport_Error) String() string { func (*TcpHostReport_Error) ProtoMessage() {} func (x *TcpHostReport_Error) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[24] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1965,7 +2075,7 @@ type TcpHostReport_Warning struct { func (x *TcpHostReport_Warning) Reset() { *x = TcpHostReport_Warning{} if protoimpl.UnsafeEnabled { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[25] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1978,7 +2088,7 @@ func (x *TcpHostReport_Warning) String() string { func (*TcpHostReport_Warning) ProtoMessage() {} func (x *TcpHostReport_Warning) ProtoReflect() protoreflect.Message { - mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[25] + mi := &file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2094,256 +2204,268 @@ var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validati 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x92, 0x05, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0xd4, 0x06, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x14, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, - 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x12, 0x68, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x51, 0x0a, 0x13, 0x74, 0x63, - 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, - 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x11, 0x74, 0x63, 0x70, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x5a, 0x0a, - 0x16, 0x68, 0x79, 0x62, 0x72, 0x69, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x79, 0x62, - 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x48, 0x00, 0x52, 0x14, 0x68, 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x63, 0x0a, 0x19, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, - 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x17, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0xc1, - 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, + 0x72, 0x6f, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x63, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x4e, 0x6f, 0x74, - 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x1a, 0x0a, - 0x16, 0x42, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, - 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x53, 0x4c, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x12, 0x13, 0x0a, - 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x10, 0x03, 0x42, 0x16, 0x0a, 0x14, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0xe1, 0x02, 0x0a, 0x12, 0x48, - 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, - 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x12, 0x51, 0x0a, 0x14, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x6f, 0x73, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x56, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x12, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x1a, 0xb7, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3f, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, - 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, - 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0x1b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x22, 0x94, - 0x03, 0x0a, 0x11, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, - 0x2e, 0x69, 0x6f, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6c, 0x6f, - 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x1a, 0xff, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3e, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6c, - 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, - 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, - 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x64, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x4e, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x14, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, + 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x12, 0x68, 0x74, 0x74, 0x70, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x51, 0x0a, 0x13, + 0x74, 0x63, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, + 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x11, 0x74, 0x63, + 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x5a, 0x0a, 0x16, 0x68, 0x79, 0x62, 0x72, 0x69, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, + 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x14, 0x68, 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x63, 0x0a, 0x19, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x17, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x1a, 0xc1, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, + 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, + 0x63, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, - 0x19, 0x0a, 0x15, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, - 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x12, - 0x14, 0x0a, 0x10, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x10, 0x03, 0x22, 0xd8, 0x03, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, - 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x3d, - 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, 0x61, 0x72, 0x6e, - 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0xc9, 0x01, - 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, - 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x1a, 0x0a, 0x16, 0x42, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x55, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, + 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x12, + 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0x03, 0x1a, 0x7e, 0x0a, 0x07, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, + 0x3d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, + 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, + 0x0a, 0x10, 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x57, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x10, 0x00, 0x42, 0x16, 0x0a, 0x14, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0xe1, 0x02, 0x0a, + 0x12, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, + 0x69, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x14, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, + 0x6f, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, + 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x12, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0xb7, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, + 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, + 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x1a, 0x84, 0x01, 0x0a, 0x07, 0x57, 0x61, - 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, - 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, - 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x25, 0x0a, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x00, - 0x22, 0xe0, 0x02, 0x0a, 0x11, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x61, 0x22, 0x1b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, + 0x22, 0x94, 0x03, 0x0a, 0x11, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, - 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x6f, 0x73, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, - 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x74, 0x63, - 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0xc4, 0x01, 0x0a, - 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, - 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x63, - 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x4e, 0x6f, - 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x1a, - 0x0a, 0x16, 0x42, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, - 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x53, - 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x12, 0x13, - 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x10, 0x03, 0x22, 0xdc, 0x03, 0x0a, 0x0d, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, - 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x12, 0x3f, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, - 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x73, 0x1a, 0xb1, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3a, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, - 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, - 0x54, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x4e, - 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, - 0x1f, 0x0a, 0x17, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x1a, 0x02, 0x08, 0x01, - 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x10, 0x02, 0x1a, 0x9a, 0x01, 0x0a, 0x07, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, - 0x67, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x28, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, - 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, 0x61, 0x72, - 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0xff, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, + 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x56, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x39, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, - 0x67, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x44, 0x65, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, + 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x64, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, + 0x65, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x4e, 0x6f, 0x74, 0x55, + 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0x02, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, 0x22, 0xd8, 0x03, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, + 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, + 0x12, 0x3d, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, + 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x1a, + 0xc9, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, + 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, + 0x13, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x1a, 0x84, 0x01, 0x0a, 0x07, + 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, + 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x25, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x10, 0x01, 0x22, 0x80, 0x02, 0x0a, 0x14, 0x48, 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x78, 0x0a, 0x18, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, - 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x79, 0x62, - 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x16, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x6e, 0x0a, 0x1b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, - 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x54, 0x0a, 0x14, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, 0x74, - 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, - 0x00, 0x52, 0x12, 0x68, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x51, 0x0a, 0x13, 0x74, 0x63, 0x70, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, - 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x11, 0x74, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xd0, - 0x03, 0x0a, 0x17, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x72, 0x0a, 0x15, 0x68, 0x74, - 0x74, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, - 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x68, 0x74, 0x74, 0x70, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x6f, - 0x0a, 0x14, 0x74, 0x63, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, - 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x74, 0x63, 0x70, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, - 0x68, 0x0a, 0x18, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, - 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x66, 0x0a, 0x17, 0x54, 0x63, 0x70, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, - 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x32, 0xdf, 0x01, 0x0a, 0x15, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0e, 0x4e, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x23, 0x2e, - 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, - 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x65, 0x0a, 0x08, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, - 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, - 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x4b, 0xb8, 0xf5, 0x04, 0x01, 0xc0, 0xf5, 0x04, 0x01, 0xd0, 0xf5, 0x04, - 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, - 0x6c, 0x6f, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x10, 0x00, 0x22, 0xe0, 0x02, 0x0a, 0x11, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, + 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x74, 0x63, 0x70, 0x5f, 0x68, + 0x6f, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, + 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0e, + 0x74, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0xc4, + 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, + 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x22, 0x63, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, + 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, + 0x12, 0x1a, 0x0a, 0x16, 0x42, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x55, + 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, + 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, + 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x10, 0x03, 0x22, 0xdc, 0x03, 0x0a, 0x0d, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, + 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, + 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x73, 0x1a, 0xb1, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3a, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6c, + 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x22, 0x54, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x61, 0x6d, + 0x65, 0x4e, 0x6f, 0x74, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0x00, 0x12, 0x1f, 0x0a, 0x17, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x44, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x01, 0x1a, 0x02, + 0x08, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x1a, 0x9a, 0x01, 0x0a, 0x07, 0x57, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x28, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, + 0x2e, 0x54, 0x63, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x57, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x39, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x57, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x10, 0x01, 0x22, 0x80, 0x02, 0x0a, 0x14, 0x48, 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x78, 0x0a, + 0x18, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3e, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, + 0x79, 0x62, 0x72, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x16, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x6e, 0x0a, 0x1b, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, + 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x54, 0x0a, 0x14, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, + 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x48, 0x00, 0x52, 0x12, 0x68, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x51, 0x0a, 0x13, 0x74, 0x63, 0x70, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, + 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x11, 0x74, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x14, 0x0a, 0x12, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x22, 0xd0, 0x03, 0x0a, 0x17, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x72, 0x0a, 0x15, + 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6c, + 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x68, 0x74, 0x74, + 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x12, 0x6f, 0x0a, 0x14, 0x74, 0x63, 0x70, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, + 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x41, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x74, + 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x1a, 0x68, 0x0a, 0x18, 0x48, 0x74, 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x48, 0x74, + 0x74, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x66, 0x0a, 0x17, 0x54, + 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, + 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x54, 0x63, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x32, 0xdf, 0x01, 0x0a, 0x15, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, + 0x0e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x12, + 0x23, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, + 0x2e, 0x69, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x73, 0x79, + 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x65, + 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x67, 0x6c, 0x6f, + 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, + 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x6c, 0x6f, 0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4b, 0xb8, 0xf5, 0x04, 0x01, 0xc0, 0xf5, 0x04, 0x01, 0xd0, + 0xf5, 0x04, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x73, 0x6f, 0x6c, 0x6f, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2358,107 +2480,111 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat return file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_rawDescData } -var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes = make([]protoimpl.MessageInfo, 29) +var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_enumTypes = make([]protoimpl.EnumInfo, 9) +var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_goTypes = []interface{}{ (ListenerReport_Error_Type)(0), // 0: gloo.solo.io.ListenerReport.Error.Type - (HttpListenerReport_Error_Type)(0), // 1: gloo.solo.io.HttpListenerReport.Error.Type - (VirtualHostReport_Error_Type)(0), // 2: gloo.solo.io.VirtualHostReport.Error.Type - (RouteReport_Error_Type)(0), // 3: gloo.solo.io.RouteReport.Error.Type - (RouteReport_Warning_Type)(0), // 4: gloo.solo.io.RouteReport.Warning.Type - (TcpListenerReport_Error_Type)(0), // 5: gloo.solo.io.TcpListenerReport.Error.Type - (TcpHostReport_Error_Type)(0), // 6: gloo.solo.io.TcpHostReport.Error.Type - (TcpHostReport_Warning_Type)(0), // 7: gloo.solo.io.TcpHostReport.Warning.Type - (*GlooValidationServiceRequest)(nil), // 8: gloo.solo.io.GlooValidationServiceRequest - (*GlooValidationServiceResponse)(nil), // 9: gloo.solo.io.GlooValidationServiceResponse - (*ModifiedResources)(nil), // 10: gloo.solo.io.ModifiedResources - (*DeletedResources)(nil), // 11: gloo.solo.io.DeletedResources - (*ValidationReport)(nil), // 12: gloo.solo.io.ValidationReport - (*ResourceReport)(nil), // 13: gloo.solo.io.ResourceReport - (*NotifyOnResyncRequest)(nil), // 14: gloo.solo.io.NotifyOnResyncRequest - (*NotifyOnResyncResponse)(nil), // 15: gloo.solo.io.NotifyOnResyncResponse - (*ProxyReport)(nil), // 16: gloo.solo.io.ProxyReport - (*ListenerReport)(nil), // 17: gloo.solo.io.ListenerReport - (*HttpListenerReport)(nil), // 18: gloo.solo.io.HttpListenerReport - (*VirtualHostReport)(nil), // 19: gloo.solo.io.VirtualHostReport - (*RouteReport)(nil), // 20: gloo.solo.io.RouteReport - (*TcpListenerReport)(nil), // 21: gloo.solo.io.TcpListenerReport - (*TcpHostReport)(nil), // 22: gloo.solo.io.TcpHostReport - (*HybridListenerReport)(nil), // 23: gloo.solo.io.HybridListenerReport - (*MatchedListenerReport)(nil), // 24: gloo.solo.io.MatchedListenerReport - (*AggregateListenerReport)(nil), // 25: gloo.solo.io.AggregateListenerReport - (*ListenerReport_Error)(nil), // 26: gloo.solo.io.ListenerReport.Error - (*HttpListenerReport_Error)(nil), // 27: gloo.solo.io.HttpListenerReport.Error - (*VirtualHostReport_Error)(nil), // 28: gloo.solo.io.VirtualHostReport.Error - (*RouteReport_Error)(nil), // 29: gloo.solo.io.RouteReport.Error - (*RouteReport_Warning)(nil), // 30: gloo.solo.io.RouteReport.Warning - (*TcpListenerReport_Error)(nil), // 31: gloo.solo.io.TcpListenerReport.Error - (*TcpHostReport_Error)(nil), // 32: gloo.solo.io.TcpHostReport.Error - (*TcpHostReport_Warning)(nil), // 33: gloo.solo.io.TcpHostReport.Warning - nil, // 34: gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry - nil, // 35: gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry - nil, // 36: gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry - (*v1.Proxy)(nil), // 37: gloo.solo.io.Proxy - (*v1.Upstream)(nil), // 38: gloo.solo.io.Upstream - (*core.ResourceRef)(nil), // 39: core.solo.io.ResourceRef - (*v1.SourceMetadata)(nil), // 40: gloo.solo.io.SourceMetadata + (ListenerReport_Warning_Type)(0), // 1: gloo.solo.io.ListenerReport.Warning.Type + (HttpListenerReport_Error_Type)(0), // 2: gloo.solo.io.HttpListenerReport.Error.Type + (VirtualHostReport_Error_Type)(0), // 3: gloo.solo.io.VirtualHostReport.Error.Type + (RouteReport_Error_Type)(0), // 4: gloo.solo.io.RouteReport.Error.Type + (RouteReport_Warning_Type)(0), // 5: gloo.solo.io.RouteReport.Warning.Type + (TcpListenerReport_Error_Type)(0), // 6: gloo.solo.io.TcpListenerReport.Error.Type + (TcpHostReport_Error_Type)(0), // 7: gloo.solo.io.TcpHostReport.Error.Type + (TcpHostReport_Warning_Type)(0), // 8: gloo.solo.io.TcpHostReport.Warning.Type + (*GlooValidationServiceRequest)(nil), // 9: gloo.solo.io.GlooValidationServiceRequest + (*GlooValidationServiceResponse)(nil), // 10: gloo.solo.io.GlooValidationServiceResponse + (*ModifiedResources)(nil), // 11: gloo.solo.io.ModifiedResources + (*DeletedResources)(nil), // 12: gloo.solo.io.DeletedResources + (*ValidationReport)(nil), // 13: gloo.solo.io.ValidationReport + (*ResourceReport)(nil), // 14: gloo.solo.io.ResourceReport + (*NotifyOnResyncRequest)(nil), // 15: gloo.solo.io.NotifyOnResyncRequest + (*NotifyOnResyncResponse)(nil), // 16: gloo.solo.io.NotifyOnResyncResponse + (*ProxyReport)(nil), // 17: gloo.solo.io.ProxyReport + (*ListenerReport)(nil), // 18: gloo.solo.io.ListenerReport + (*HttpListenerReport)(nil), // 19: gloo.solo.io.HttpListenerReport + (*VirtualHostReport)(nil), // 20: gloo.solo.io.VirtualHostReport + (*RouteReport)(nil), // 21: gloo.solo.io.RouteReport + (*TcpListenerReport)(nil), // 22: gloo.solo.io.TcpListenerReport + (*TcpHostReport)(nil), // 23: gloo.solo.io.TcpHostReport + (*HybridListenerReport)(nil), // 24: gloo.solo.io.HybridListenerReport + (*MatchedListenerReport)(nil), // 25: gloo.solo.io.MatchedListenerReport + (*AggregateListenerReport)(nil), // 26: gloo.solo.io.AggregateListenerReport + (*ListenerReport_Error)(nil), // 27: gloo.solo.io.ListenerReport.Error + (*ListenerReport_Warning)(nil), // 28: gloo.solo.io.ListenerReport.Warning + (*HttpListenerReport_Error)(nil), // 29: gloo.solo.io.HttpListenerReport.Error + (*VirtualHostReport_Error)(nil), // 30: gloo.solo.io.VirtualHostReport.Error + (*RouteReport_Error)(nil), // 31: gloo.solo.io.RouteReport.Error + (*RouteReport_Warning)(nil), // 32: gloo.solo.io.RouteReport.Warning + (*TcpListenerReport_Error)(nil), // 33: gloo.solo.io.TcpListenerReport.Error + (*TcpHostReport_Error)(nil), // 34: gloo.solo.io.TcpHostReport.Error + (*TcpHostReport_Warning)(nil), // 35: gloo.solo.io.TcpHostReport.Warning + nil, // 36: gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry + nil, // 37: gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry + nil, // 38: gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry + (*v1.Proxy)(nil), // 39: gloo.solo.io.Proxy + (*v1.Upstream)(nil), // 40: gloo.solo.io.Upstream + (*core.ResourceRef)(nil), // 41: core.solo.io.ResourceRef + (*v1.SourceMetadata)(nil), // 42: gloo.solo.io.SourceMetadata } var file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_depIdxs = []int32{ - 37, // 0: gloo.solo.io.GlooValidationServiceRequest.proxy:type_name -> gloo.solo.io.Proxy - 10, // 1: gloo.solo.io.GlooValidationServiceRequest.modified_resources:type_name -> gloo.solo.io.ModifiedResources - 11, // 2: gloo.solo.io.GlooValidationServiceRequest.deleted_resources:type_name -> gloo.solo.io.DeletedResources - 12, // 3: gloo.solo.io.GlooValidationServiceResponse.validation_reports:type_name -> gloo.solo.io.ValidationReport - 38, // 4: gloo.solo.io.ModifiedResources.upstreams:type_name -> gloo.solo.io.Upstream - 39, // 5: gloo.solo.io.DeletedResources.upstream_refs:type_name -> core.solo.io.ResourceRef - 39, // 6: gloo.solo.io.DeletedResources.secret_refs:type_name -> core.solo.io.ResourceRef - 16, // 7: gloo.solo.io.ValidationReport.proxy_report:type_name -> gloo.solo.io.ProxyReport - 13, // 8: gloo.solo.io.ValidationReport.upstream_reports:type_name -> gloo.solo.io.ResourceReport - 37, // 9: gloo.solo.io.ValidationReport.proxy:type_name -> gloo.solo.io.Proxy - 39, // 10: gloo.solo.io.ResourceReport.resource_ref:type_name -> core.solo.io.ResourceRef - 17, // 11: gloo.solo.io.ProxyReport.listener_reports:type_name -> gloo.solo.io.ListenerReport - 26, // 12: gloo.solo.io.ListenerReport.errors:type_name -> gloo.solo.io.ListenerReport.Error - 18, // 13: gloo.solo.io.ListenerReport.http_listener_report:type_name -> gloo.solo.io.HttpListenerReport - 21, // 14: gloo.solo.io.ListenerReport.tcp_listener_report:type_name -> gloo.solo.io.TcpListenerReport - 23, // 15: gloo.solo.io.ListenerReport.hybrid_listener_report:type_name -> gloo.solo.io.HybridListenerReport - 25, // 16: gloo.solo.io.ListenerReport.aggregate_listener_report:type_name -> gloo.solo.io.AggregateListenerReport - 27, // 17: gloo.solo.io.HttpListenerReport.errors:type_name -> gloo.solo.io.HttpListenerReport.Error - 19, // 18: gloo.solo.io.HttpListenerReport.virtual_host_reports:type_name -> gloo.solo.io.VirtualHostReport - 28, // 19: gloo.solo.io.VirtualHostReport.errors:type_name -> gloo.solo.io.VirtualHostReport.Error - 20, // 20: gloo.solo.io.VirtualHostReport.route_reports:type_name -> gloo.solo.io.RouteReport - 29, // 21: gloo.solo.io.RouteReport.errors:type_name -> gloo.solo.io.RouteReport.Error - 30, // 22: gloo.solo.io.RouteReport.warnings:type_name -> gloo.solo.io.RouteReport.Warning - 31, // 23: gloo.solo.io.TcpListenerReport.errors:type_name -> gloo.solo.io.TcpListenerReport.Error - 22, // 24: gloo.solo.io.TcpListenerReport.tcp_host_reports:type_name -> gloo.solo.io.TcpHostReport - 32, // 25: gloo.solo.io.TcpHostReport.errors:type_name -> gloo.solo.io.TcpHostReport.Error - 33, // 26: gloo.solo.io.TcpHostReport.warnings:type_name -> gloo.solo.io.TcpHostReport.Warning - 34, // 27: gloo.solo.io.HybridListenerReport.matched_listener_reports:type_name -> gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry - 18, // 28: gloo.solo.io.MatchedListenerReport.http_listener_report:type_name -> gloo.solo.io.HttpListenerReport - 21, // 29: gloo.solo.io.MatchedListenerReport.tcp_listener_report:type_name -> gloo.solo.io.TcpListenerReport - 35, // 30: gloo.solo.io.AggregateListenerReport.http_listener_reports:type_name -> gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry - 36, // 31: gloo.solo.io.AggregateListenerReport.tcp_listener_reports:type_name -> gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry - 0, // 32: gloo.solo.io.ListenerReport.Error.type:type_name -> gloo.solo.io.ListenerReport.Error.Type - 1, // 33: gloo.solo.io.HttpListenerReport.Error.type:type_name -> gloo.solo.io.HttpListenerReport.Error.Type - 40, // 34: gloo.solo.io.HttpListenerReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata - 2, // 35: gloo.solo.io.VirtualHostReport.Error.type:type_name -> gloo.solo.io.VirtualHostReport.Error.Type - 40, // 36: gloo.solo.io.VirtualHostReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata - 3, // 37: gloo.solo.io.RouteReport.Error.type:type_name -> gloo.solo.io.RouteReport.Error.Type - 40, // 38: gloo.solo.io.RouteReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata - 4, // 39: gloo.solo.io.RouteReport.Warning.type:type_name -> gloo.solo.io.RouteReport.Warning.Type - 5, // 40: gloo.solo.io.TcpListenerReport.Error.type:type_name -> gloo.solo.io.TcpListenerReport.Error.Type - 6, // 41: gloo.solo.io.TcpHostReport.Error.type:type_name -> gloo.solo.io.TcpHostReport.Error.Type - 7, // 42: gloo.solo.io.TcpHostReport.Warning.type:type_name -> gloo.solo.io.TcpHostReport.Warning.Type - 24, // 43: gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry.value:type_name -> gloo.solo.io.MatchedListenerReport - 18, // 44: gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry.value:type_name -> gloo.solo.io.HttpListenerReport - 21, // 45: gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry.value:type_name -> gloo.solo.io.TcpListenerReport - 14, // 46: gloo.solo.io.GlooValidationService.NotifyOnResync:input_type -> gloo.solo.io.NotifyOnResyncRequest - 8, // 47: gloo.solo.io.GlooValidationService.Validate:input_type -> gloo.solo.io.GlooValidationServiceRequest - 15, // 48: gloo.solo.io.GlooValidationService.NotifyOnResync:output_type -> gloo.solo.io.NotifyOnResyncResponse - 9, // 49: gloo.solo.io.GlooValidationService.Validate:output_type -> gloo.solo.io.GlooValidationServiceResponse - 48, // [48:50] is the sub-list for method output_type - 46, // [46:48] is the sub-list for method input_type - 46, // [46:46] is the sub-list for extension type_name - 46, // [46:46] is the sub-list for extension extendee - 0, // [0:46] is the sub-list for field type_name + 39, // 0: gloo.solo.io.GlooValidationServiceRequest.proxy:type_name -> gloo.solo.io.Proxy + 11, // 1: gloo.solo.io.GlooValidationServiceRequest.modified_resources:type_name -> gloo.solo.io.ModifiedResources + 12, // 2: gloo.solo.io.GlooValidationServiceRequest.deleted_resources:type_name -> gloo.solo.io.DeletedResources + 13, // 3: gloo.solo.io.GlooValidationServiceResponse.validation_reports:type_name -> gloo.solo.io.ValidationReport + 40, // 4: gloo.solo.io.ModifiedResources.upstreams:type_name -> gloo.solo.io.Upstream + 41, // 5: gloo.solo.io.DeletedResources.upstream_refs:type_name -> core.solo.io.ResourceRef + 41, // 6: gloo.solo.io.DeletedResources.secret_refs:type_name -> core.solo.io.ResourceRef + 17, // 7: gloo.solo.io.ValidationReport.proxy_report:type_name -> gloo.solo.io.ProxyReport + 14, // 8: gloo.solo.io.ValidationReport.upstream_reports:type_name -> gloo.solo.io.ResourceReport + 39, // 9: gloo.solo.io.ValidationReport.proxy:type_name -> gloo.solo.io.Proxy + 41, // 10: gloo.solo.io.ResourceReport.resource_ref:type_name -> core.solo.io.ResourceRef + 18, // 11: gloo.solo.io.ProxyReport.listener_reports:type_name -> gloo.solo.io.ListenerReport + 27, // 12: gloo.solo.io.ListenerReport.errors:type_name -> gloo.solo.io.ListenerReport.Error + 28, // 13: gloo.solo.io.ListenerReport.warnings:type_name -> gloo.solo.io.ListenerReport.Warning + 19, // 14: gloo.solo.io.ListenerReport.http_listener_report:type_name -> gloo.solo.io.HttpListenerReport + 22, // 15: gloo.solo.io.ListenerReport.tcp_listener_report:type_name -> gloo.solo.io.TcpListenerReport + 24, // 16: gloo.solo.io.ListenerReport.hybrid_listener_report:type_name -> gloo.solo.io.HybridListenerReport + 26, // 17: gloo.solo.io.ListenerReport.aggregate_listener_report:type_name -> gloo.solo.io.AggregateListenerReport + 29, // 18: gloo.solo.io.HttpListenerReport.errors:type_name -> gloo.solo.io.HttpListenerReport.Error + 20, // 19: gloo.solo.io.HttpListenerReport.virtual_host_reports:type_name -> gloo.solo.io.VirtualHostReport + 30, // 20: gloo.solo.io.VirtualHostReport.errors:type_name -> gloo.solo.io.VirtualHostReport.Error + 21, // 21: gloo.solo.io.VirtualHostReport.route_reports:type_name -> gloo.solo.io.RouteReport + 31, // 22: gloo.solo.io.RouteReport.errors:type_name -> gloo.solo.io.RouteReport.Error + 32, // 23: gloo.solo.io.RouteReport.warnings:type_name -> gloo.solo.io.RouteReport.Warning + 33, // 24: gloo.solo.io.TcpListenerReport.errors:type_name -> gloo.solo.io.TcpListenerReport.Error + 23, // 25: gloo.solo.io.TcpListenerReport.tcp_host_reports:type_name -> gloo.solo.io.TcpHostReport + 34, // 26: gloo.solo.io.TcpHostReport.errors:type_name -> gloo.solo.io.TcpHostReport.Error + 35, // 27: gloo.solo.io.TcpHostReport.warnings:type_name -> gloo.solo.io.TcpHostReport.Warning + 36, // 28: gloo.solo.io.HybridListenerReport.matched_listener_reports:type_name -> gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry + 19, // 29: gloo.solo.io.MatchedListenerReport.http_listener_report:type_name -> gloo.solo.io.HttpListenerReport + 22, // 30: gloo.solo.io.MatchedListenerReport.tcp_listener_report:type_name -> gloo.solo.io.TcpListenerReport + 37, // 31: gloo.solo.io.AggregateListenerReport.http_listener_reports:type_name -> gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry + 38, // 32: gloo.solo.io.AggregateListenerReport.tcp_listener_reports:type_name -> gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry + 0, // 33: gloo.solo.io.ListenerReport.Error.type:type_name -> gloo.solo.io.ListenerReport.Error.Type + 1, // 34: gloo.solo.io.ListenerReport.Warning.type:type_name -> gloo.solo.io.ListenerReport.Warning.Type + 2, // 35: gloo.solo.io.HttpListenerReport.Error.type:type_name -> gloo.solo.io.HttpListenerReport.Error.Type + 42, // 36: gloo.solo.io.HttpListenerReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata + 3, // 37: gloo.solo.io.VirtualHostReport.Error.type:type_name -> gloo.solo.io.VirtualHostReport.Error.Type + 42, // 38: gloo.solo.io.VirtualHostReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata + 4, // 39: gloo.solo.io.RouteReport.Error.type:type_name -> gloo.solo.io.RouteReport.Error.Type + 42, // 40: gloo.solo.io.RouteReport.Error.metadata:type_name -> gloo.solo.io.SourceMetadata + 5, // 41: gloo.solo.io.RouteReport.Warning.type:type_name -> gloo.solo.io.RouteReport.Warning.Type + 6, // 42: gloo.solo.io.TcpListenerReport.Error.type:type_name -> gloo.solo.io.TcpListenerReport.Error.Type + 7, // 43: gloo.solo.io.TcpHostReport.Error.type:type_name -> gloo.solo.io.TcpHostReport.Error.Type + 8, // 44: gloo.solo.io.TcpHostReport.Warning.type:type_name -> gloo.solo.io.TcpHostReport.Warning.Type + 25, // 45: gloo.solo.io.HybridListenerReport.MatchedListenerReportsEntry.value:type_name -> gloo.solo.io.MatchedListenerReport + 19, // 46: gloo.solo.io.AggregateListenerReport.HttpListenerReportsEntry.value:type_name -> gloo.solo.io.HttpListenerReport + 22, // 47: gloo.solo.io.AggregateListenerReport.TcpListenerReportsEntry.value:type_name -> gloo.solo.io.TcpListenerReport + 15, // 48: gloo.solo.io.GlooValidationService.NotifyOnResync:input_type -> gloo.solo.io.NotifyOnResyncRequest + 9, // 49: gloo.solo.io.GlooValidationService.Validate:input_type -> gloo.solo.io.GlooValidationServiceRequest + 16, // 50: gloo.solo.io.GlooValidationService.NotifyOnResync:output_type -> gloo.solo.io.NotifyOnResyncResponse + 10, // 51: gloo.solo.io.GlooValidationService.Validate:output_type -> gloo.solo.io.GlooValidationServiceResponse + 50, // [50:52] is the sub-list for method output_type + 48, // [48:50] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { @@ -2698,7 +2824,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HttpListenerReport_Error); i { + switch v := v.(*ListenerReport_Warning); i { case 0: return &v.state case 1: @@ -2710,7 +2836,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VirtualHostReport_Error); i { + switch v := v.(*HttpListenerReport_Error); i { case 0: return &v.state case 1: @@ -2722,7 +2848,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouteReport_Error); i { + switch v := v.(*VirtualHostReport_Error); i { case 0: return &v.state case 1: @@ -2734,7 +2860,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouteReport_Warning); i { + switch v := v.(*RouteReport_Error); i { case 0: return &v.state case 1: @@ -2746,7 +2872,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TcpListenerReport_Error); i { + switch v := v.(*RouteReport_Warning); i { case 0: return &v.state case 1: @@ -2758,7 +2884,7 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TcpHostReport_Error); i { + switch v := v.(*TcpListenerReport_Error); i { case 0: return &v.state case 1: @@ -2770,6 +2896,18 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat } } file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TcpHostReport_Error); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TcpHostReport_Warning); i { case 0: return &v.state @@ -2801,8 +2939,8 @@ func file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validat File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_github_com_solo_io_gloo_projects_gloo_api_grpc_validation_gloo_validation_proto_rawDesc, - NumEnums: 8, - NumMessages: 29, + NumEnums: 9, + NumMessages: 30, NumExtensions: 0, NumServices: 1, }, diff --git a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.hash.go b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.hash.go index 0d69930da6f..31947eb14be 100644 --- a/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.hash.go +++ b/projects/gloo/pkg/api/grpc/validation/gloo_validation.pb.hash.go @@ -494,6 +494,30 @@ func (m *ListenerReport) Hash(hasher hash.Hash64) (uint64, error) { } + for _, v := range m.GetWarnings() { + + if h, ok := interface{}(v).(safe_hasher.SafeHasher); ok { + if _, err = hasher.Write([]byte("")); err != nil { + return 0, err + } + if _, err = h.Hash(hasher); err != nil { + return 0, err + } + } else { + if fieldValue, err := hashstructure.Hash(v, nil); err != nil { + return 0, err + } else { + if _, err = hasher.Write([]byte("")); err != nil { + return 0, err + } + if err := binary.Write(hasher, binary.LittleEndian, fieldValue); err != nil { + return 0, err + } + } + } + + } + switch m.ListenerTypeReport.(type) { case *ListenerReport_HttpListenerReport: @@ -1147,6 +1171,31 @@ func (m *ListenerReport_Error) Hash(hasher hash.Hash64) (uint64, error) { return hasher.Sum64(), nil } +// Hash function +func (m *ListenerReport_Warning) Hash(hasher hash.Hash64) (uint64, error) { + if m == nil { + return 0, nil + } + if hasher == nil { + hasher = fnv.New64() + } + var err error + if _, err = hasher.Write([]byte("gloo.solo.io.github.com/solo-io/gloo/projects/gloo/pkg/api/grpc/validation.ListenerReport_Warning")); err != nil { + return 0, err + } + + err = binary.Write(hasher, binary.LittleEndian, m.GetType()) + if err != nil { + return 0, err + } + + if _, err = hasher.Write([]byte(m.GetReason())); err != nil { + return 0, err + } + + return hasher.Sum64(), nil +} + // Hash function func (m *HttpListenerReport_Error) Hash(hasher hash.Hash64) (uint64, error) { if m == nil { From 304b6d444aaa1073bfdbe0ef553346c3bf6f742d Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 8 Aug 2024 10:32:22 -0400 Subject: [PATCH 03/39] kubernetes e2e --- pkg/utils/kubeutils/kubectl/cli.go | 17 ++ .../reporting/add_proxy_validation_result.go | 10 + projects/gloo/pkg/translator/filter_chain.go | 6 +- .../pkg/utils/validation/proxy_validation.go | 38 +-- .../e2e/features/server_tls/suite.go | 262 ++++++++++++++++++ .../server_tls/testdata/tls-secret-1.yaml | 9 + .../server_tls/testdata/tls-secret-2.yaml | 9 + .../testdata/tls-secret-with-ca.yaml | 10 + .../features/server_tls/testdata/vs-1.yaml | 18 ++ .../features/server_tls/testdata/vs-2.yaml | 18 ++ .../server_tls/testdata/vs-with-oneway.yaml | 19 ++ .../testdata/vs-without-oneway.yaml | 18 ++ .../e2e/features/server_tls/types.go | 120 ++++++++ 13 files changed, 535 insertions(+), 19 deletions(-) create mode 100644 test/kubernetes/e2e/features/server_tls/suite.go create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/tls-secret-1.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/tls-secret-2.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/tls-secret-with-ca.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml create mode 100644 test/kubernetes/e2e/features/server_tls/types.go diff --git a/pkg/utils/kubeutils/kubectl/cli.go b/pkg/utils/kubeutils/kubectl/cli.go index e9a7b212027..7dfef922289 100644 --- a/pkg/utils/kubeutils/kubectl/cli.go +++ b/pkg/utils/kubeutils/kubectl/cli.go @@ -297,6 +297,23 @@ func (c *Cli) Scale(ctx context.Context, namespace string, resource string, repl return c.RunCommand(ctx, "wait", "-n", namespace, "--for=condition=available", resource, "--timeout=300s") } +// RestartDeployment restarts a deployment. It does not wait for the deployment to be ready. +func (c *Cli) RestartDeployment(ctx context.Context, name string, extraArgs ...string) error { + return c.RunCommand(ctx, + "rollout", + "restart", + fmt.Sprintf("deployment/%s", name), + ) +} + +// RestartDeploymentAndWait restarts a deployment and waits for it to become healthy. +func (c *Cli) RestartDeploymentAndWait(ctx context.Context, name string, extraArgs ...string) error { + if err := c.RestartDeployment(ctx, name, extraArgs...); err != nil { + return err + } + return c.DeploymentRolloutStatus(ctx, name, extraArgs...) +} + // GetContainerLogs retrieves the logs for the specified container func (c *Cli) GetContainerLogs(ctx context.Context, namespace string, name string) (string, error) { stdout, stderr, err := c.Execute(ctx, "-n", namespace, "logs", name) diff --git a/projects/gateway/pkg/reporting/add_proxy_validation_result.go b/projects/gateway/pkg/reporting/add_proxy_validation_result.go index da104a8181e..c3e18b51062 100644 --- a/projects/gateway/pkg/reporting/add_proxy_validation_result.go +++ b/projects/gateway/pkg/reporting/add_proxy_validation_result.go @@ -116,6 +116,7 @@ func AddProxyValidationResult(resourceReports reporter.ResourceReports, proxy *g func addListenerResult(resourceReports reporter.ResourceReports, listener *gloov1.Listener, listenerReport *validation.ListenerReport) error { listenerErrs := getListenerLevelErrors(listenerReport) + listenerWarnings := getListenerLevelWarnings(listenerReport) return translator.ForEachSource(listener, func(src translator.SourceRef) error { srcResource, _ := resourceReports.Find(src.ResourceKind, &core.ResourceRef{Name: src.Name, Namespace: src.Namespace}) @@ -123,6 +124,7 @@ func addListenerResult(resourceReports reporter.ResourceReports, listener *gloov return missingReportForSourceErr } resourceReports.AddErrors(srcResource, listenerErrs...) + resourceReports.AddWarnings(srcResource, listenerWarnings...) return nil }) } @@ -180,6 +182,14 @@ func getListenerLevelErrors(listenerReport *validation.ListenerReport) []error { return listenerErrs } +func getListenerLevelWarnings(listenerReport *validation.ListenerReport) []string { + listenerWarnings := validationutils.GetListenerWarning(listenerReport) + + // TODO(jbohanon) implement warnings on various listener types and account for them here + // similarly to the errors aggregation func above. + + return listenerWarnings +} // get errors that can be caused by virtual services func getVirtualHostLevelErrorsAndWarnings(vhReport *validation.VirtualHostReport) ([]error, []string) { diff --git a/projects/gloo/pkg/translator/filter_chain.go b/projects/gloo/pkg/translator/filter_chain.go index 00740bc9a1e..30c609b874b 100644 --- a/projects/gloo/pkg/translator/filter_chain.go +++ b/projects/gloo/pkg/translator/filter_chain.go @@ -294,6 +294,9 @@ func (h *httpFilterChainTranslator) createFilterChainsFromSslConfiguration( // get secrets downstreamTlsContext, err := h.sslConfigTranslator.ResolveDownstreamSslConfig(snap.Secrets, sslConfig) if err != nil { + // We add this as a warning to support eventual consistency with TLS Secret resources. In this way, + // the Proxy producing this will not be considered Rejected, and the HTTPS Listener will still operate + // as expected with a VirtualService in error. validation.AppendListenerWarning(h.parentReport, validationapi.ListenerReport_Warning_SSLConfigWarning, err.Error()) continue } @@ -308,7 +311,8 @@ func (h *httpFilterChainTranslator) createFilterChainsFromSslConfiguration( continue } secureFilterChains = append(secureFilterChains, &plugins.ExtendedFilterChain{ - FilterChain: filterChain, TerminatingCipherSuites: sslConfig.GetParameters().GetCipherSuites(), + FilterChain: filterChain, + TerminatingCipherSuites: sslConfig.GetParameters().GetCipherSuites(), }) } return secureFilterChains diff --git a/projects/gloo/pkg/utils/validation/proxy_validation.go b/projects/gloo/pkg/utils/validation/proxy_validation.go index 8cc4f9800ce..34a2bc809a6 100644 --- a/projects/gloo/pkg/utils/validation/proxy_validation.go +++ b/projects/gloo/pkg/utils/validation/proxy_validation.go @@ -185,22 +185,34 @@ func makeTcpHostReports(tcpHosts []*v1.TcpHost) []*validation.TcpHostReport { return tcpHostReports } -func mkErr(level, errType, reason string) error { +func formattedError(level, errType, reason string) error { return errors.Errorf("%v Error: %v. Reason: %v", level, errType, reason) } +func formattedWarning(level, errType, reason string) string { + return fmt.Sprintf("%v Warning: %v. Reason: %v", level, errType, reason) +} + func GetListenerErr(listener *validation.ListenerReport) []error { var errs []error for _, errReport := range listener.GetErrors() { - errs = append(errs, mkErr("Listener", errReport.GetType().String(), errReport.GetReason())) + errs = append(errs, formattedError("Listener", errReport.GetType().String(), errReport.GetReason())) } return errs } +func GetListenerWarning(listener *validation.ListenerReport) []string { + var warnings []string + for _, warning := range listener.GetWarnings() { + warnings = append(warnings, formattedWarning("Listener", warning.GetType().String(), warning.GetReason())) + } + return warnings +} + func GetHttpListenerErr(httpListener *validation.HttpListenerReport) []error { var errs []error for _, errReport := range httpListener.GetErrors() { - errs = append(errs, mkErr("HttpListener", errReport.GetType().String(), errReport.GetReason())) + errs = append(errs, formattedError("HttpListener", errReport.GetType().String(), errReport.GetReason())) } return errs } @@ -208,7 +220,7 @@ func GetHttpListenerErr(httpListener *validation.HttpListenerReport) []error { func GetVirtualHostErr(virtualHost *validation.VirtualHostReport) []error { var errs []error for _, errReport := range virtualHost.GetErrors() { - errs = append(errs, mkErr("VirtualHost", errReport.GetType().String(), errReport.GetReason())) + errs = append(errs, formattedError("VirtualHost", errReport.GetType().String(), errReport.GetReason())) } return errs } @@ -224,21 +236,16 @@ func GetRouteErr(route *validation.RouteReport) []error { func GetRouteWarning(route *validation.RouteReport) []string { var warnings []string - appendWarning := func(level, errType, reason string) { - warnings = append(warnings, fmt.Sprintf("%v Warning: %v. Reason: %v", level, errType, reason)) - } - for _, warning := range route.GetWarnings() { - appendWarning("Route", warning.GetType().String(), warning.GetReason()) + warnings = append(warnings, formattedWarning("Route", warning.GetType().String(), warning.GetReason())) } - return warnings } func GetTcpListenerErr(tcpListener *validation.TcpListenerReport) []error { var errs []error for _, errReport := range tcpListener.GetErrors() { - errs = append(errs, mkErr("TcpListener", errReport.GetType().String(), errReport.GetReason())) + errs = append(errs, formattedError("TcpListener", errReport.GetType().String(), errReport.GetReason())) } return errs } @@ -246,7 +253,7 @@ func GetTcpListenerErr(tcpListener *validation.TcpListenerReport) []error { func GetTcpHostErr(tcpHost *validation.TcpHostReport) []error { var errs []error for _, errReport := range tcpHost.GetErrors() { - errs = append(errs, mkErr("TcpHost", errReport.GetType().String(), errReport.GetReason())) + errs = append(errs, formattedError("TcpHost", errReport.GetType().String(), errReport.GetReason())) } return errs } @@ -255,14 +262,9 @@ func GetTcpHostErr(tcpHost *validation.TcpHostReport) []error { // of strings func GetTcpHostWarning(tcpHost *validation.TcpHostReport) []string { var warnings []string - appendWarning := func(level, errType, reason string) { - warnings = append(warnings, fmt.Sprintf("%v Warning: %v. Reason: %v", level, errType, reason)) - } - for _, warning := range tcpHost.GetWarnings() { - appendWarning("TcpHost", warning.GetType().String(), warning.GetReason()) + warnings = append(warnings, formattedWarning("TcpHost", warning.GetType().String(), warning.GetReason())) } - return warnings } diff --git a/test/kubernetes/e2e/features/server_tls/suite.go b/test/kubernetes/e2e/features/server_tls/suite.go new file mode 100644 index 00000000000..6d489634caf --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/suite.go @@ -0,0 +1,262 @@ +package client_tls + +import ( + "context" + "time" + + "github.com/solo-io/gloo/projects/gateway/pkg/defaults" + "github.com/solo-io/gloo/test/gomega/matchers" + "github.com/solo-io/gloo/test/kube2e/helper" + testdefaults "github.com/solo-io/gloo/test/kubernetes/e2e/defaults" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/solo-io/gloo/pkg/utils/kubeutils" + "github.com/solo-io/gloo/pkg/utils/requestutils/curl" + "github.com/solo-io/gloo/test/kubernetes/e2e" +) + +var _ e2e.NewSuiteFunc = NewTestingSuite + +// serverTlsTestingSuite is the entire Suite of tests for the "Gloo mtls" cases +type serverTlsTestingSuite struct { + suite.Suite + + ctx context.Context + + // testInstallation contains all the metadata/utilities necessary to execute a series of tests + // against an installation of Gloo Gateway + testInstallation *e2e.TestInstallation + + // ns is the namespace in which the feature suite is being executed. + ns string +} + +func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite.TestingSuite { + return &serverTlsTestingSuite{ + ctx: ctx, + testInstallation: testInst, + ns: testInst.Metadata.InstallNamespace, + } +} + +func (s *serverTlsTestingSuite) SetupSuite() { + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.CurlPodManifest) + s.NoError(err, "can apply Curl setup manifest") + +} + +func (s *serverTlsTestingSuite) TearDownSuite() { + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, testdefaults.CurlPodManifest) + s.NoError(err, "can delete Curl setup manifest") +} + +// TestServerTls validates the happy path that a VirtualService referencing an existent TLS secret +// terminates TLS and responds appropriately. +func (s *serverTlsTestingSuite) TestServerTls() { + vs1 := vs1(s.ns) + s.T().Cleanup(func() { + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs1 manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1) + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can delete tls secret manifest file") + // tlsSecret2 is deleted in the process of the test. + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns)) + }) + + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret 1 manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns)) + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs1 manifest file") + + // Assert that we have traffic working on both VS. + s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) +} + +// TestServerTls validates the happy path that two VirtualServices referencing existent TLS secrets +// terminate TLS and respond appropriately. +func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { + vs1 := vs1(s.ns) + vs2 := vs2(s.ns) + s.T().Cleanup(func() { + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs1 manifest file") + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs2ManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs2 manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can delete tls secret manifest file") + // tlsSecret2 is deleted in the process of the test. + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + }) + + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret 1 manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret 2 manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs1 manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs2ManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs2 manifest file") + + // Assert that we have traffic working on both VS. + s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) + s.assertEventualResponse(vs2.GetName(), expectedHealthyResponse2) +} + +// TestServerTls validates that when we have two VirtualServices referencing TLS secrets, but one secret +// is missing, the traffic routing defined by the other VirtualService is not affected. In order to test +// this properly, we require persistProxySpec to be off, validating that both VS are working correctly, +// then we delete the secret for one of the VS and restart the Gloo pod. This ensures that we are still +// serving on the other VS. +func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecret() { + vs1 := vs1(s.ns) + vs2 := vs2(s.ns) + s.T().Cleanup(func() { + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs1 manifest file") + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs2ManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs2 manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can delete tls secret manifest file") + // tlsSecret2 is deleted in the process of the test. + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + }) + + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret 1 manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret 2 manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs1 manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs2ManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs2 manifest file") + + // Assert that we have traffic working on both VS. + s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) + s.assertEventualResponse(vs2.GetName(), expectedHealthyResponse2) + + // Delete the secret referenced by VS 1. + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret2ManifestFile) + s.NoError(err, "can delete tls secret 2 manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret2(s.ns)) + + // Assert that we have traffic working on VS 1 but failed traffic on VS 2. + s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) + s.assertEventualResponse(vs2.GetName(), expectedNoFilterChainFailedResponse) + + // Restart the Gloo deployment + err = s.testInstallation.Actions.Kubectl().RestartDeploymentAndWait(s.ctx, "gloo", "-n", s.ns) + s.NoError(err, "can restart gloo deployment") + + timeout, polling := helper.GetTimeouts(time.Second*10, time.Second) + + // Assert that we have traffic working on VS 1 but failed traffic on VS 2. + s.assertEventuallyConsistentResponse(vs1.GetName(), expectedHealthyResponse1, timeout, polling) + s.assertEventuallyConsistentResponse(vs2.GetName(), expectedNoFilterChainFailedResponse, timeout, polling) + +} + +// TestOneWayServerTlsFailsWithoutOneWayTls validates that one-way server TLS traffic fails when CA data +// is provided in the TLS secret. This is because the Gloo translation loop assumes that mTLS is desired +// if the secret contains a CA cert. +func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { + vs := vsWithoutOneWay(s.ns) + s.T().Cleanup(func() { + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecretWithCaManifestFile) + s.NoError(err, "can delete tls secret manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) + }) + + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecretWithCaManifestFile) + s.NoError(err, "can apply tls secret manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs manifest file") + + s.assertEventualResponse(vs.GetName(), expectedCertVerifyFailedResponse) +} + +// TestOneWayServerTlsWorksWithOneWayTls validates that one-way server TLS traffic succeeds when CA data +// is provided in the TLS secret IF oneWayTls is set on the sslConfig. This is because the Gloo translation +// loop assumes that mTLS is desired if the secret contains a CA cert unless oneWayTls is set. +func (s *serverTlsTestingSuite) TestOneWayServerTlsWorksWithOneWayTls() { + vs := vsWithOneWay(s.ns) + s.T().Cleanup(func() { + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vsWithOneWayManifestFile, "-n", s.ns) + s.NoError(err, "can delete vs manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecretWithCaManifestFile) + s.NoError(err, "can delete tls secret manifest file") + s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) + }) + + // ordering here matters if strict validation enabled + err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + s.NoError(err, "can apply tls secret manifest file") + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + s.NoError(err, "can apply vs manifest file") + + s.assertEventualResponse(vs.GetName(), expectedHealthyResponseWithOneWay) +} + +func (s *serverTlsTestingSuite) assertEventualResponse(hostHeaderValue string, matcher *matchers.HttpResponse) { + + // Make sure our proxy pod is running + listOpts := metav1.ListOptions{ + LabelSelector: "gloo=gateway-proxy", + } + s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, s.testInstallation.Metadata.InstallNamespace, listOpts, time.Minute*2) + + // Check curl works against expected response + s.testInstallation.Assertions.AssertEventualCurlResponse( + s.ctx, + testdefaults.CurlPodExecOpt, + []curl.Option{ + curl.WithHost(kubeutils.ServiceFQDN(metav1.ObjectMeta{Name: defaults.GatewayProxyName, Namespace: s.testInstallation.Metadata.InstallNamespace})), + // The host header must match the domain in the VirtualService + curl.WithHostHeader(hostHeaderValue), + curl.WithPort(443), + curl.IgnoreServerCert(), + }, + matcher) +} + +func (s *serverTlsTestingSuite) assertEventuallyConsistentResponse(hostHeaderValue string, matcher *matchers.HttpResponse, timeouts ...time.Duration) { + + // Make sure our proxy pod is running + listOpts := metav1.ListOptions{ + LabelSelector: "gloo=gateway-proxy", + } + s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, s.testInstallation.Metadata.InstallNamespace, listOpts, time.Minute*2) + + // Check curl works against expected response + s.testInstallation.Assertions.AssertEventuallyConsistentCurlResponse( + s.ctx, + testdefaults.CurlPodExecOpt, + []curl.Option{ + curl.WithHost(kubeutils.ServiceFQDN(metav1.ObjectMeta{Name: defaults.GatewayProxyName, Namespace: s.testInstallation.Metadata.InstallNamespace})), + // The host header must match the domain in the VirtualService + curl.WithHostHeader(hostHeaderValue), + curl.WithPort(443), + curl.IgnoreServerCert(), + }, + matcher, + timeouts...) +} diff --git a/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-1.yaml b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-1.yaml new file mode 100644 index 00000000000..a1921ca3442 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-1.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + name: tls-secret-1 + namespace: ${INSTALL_NAMESPACE} +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVQVENDQWlXZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFiTVFvd0NBWURWUVFEREFFcU1RMHcKQ3dZRFZRUUtEQVJ5YjI5ME1CNFhEVEl6TVRFd09ERTJORFExTjFvWERUTXpNVEV3TlRFMk5EUTFOMW93SGpFSwpNQWdHQTFVRUF3d0JLakVRTUE0R0ExVUVDZ3dIWjJGMFpYZGhlVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTit0V2hoa3QvNVFQTUw4UGorZ1JScUM1blp5TG9Sem5iK3hPazdQTVozRndtYUcKNThvbVhPRm16ZmJlK0VaaGE0UlBhK1BpdFhFbitjZkM5allYRU42dGM1WExWUjlKK1dCRXRhSUpoZlh2VzAvbgpraEg0MWFZa2NCQVMyTEh1U3l4WWd3VERMRzI1OUxVdVJFT3VGSVhtWUZJaGVlZTZ6V3dRMXk0Ujk1VzRoVGFzCi9JVk9wYmttbSsyM0ZVQ1Q3RTcvNzN0RFh3Q1dpekc3UnUyZ1p2aS9tK0ZRVUJCZmFPTGxzelQvVHNwNTB3YmUKY0hxY29UbWJNWUJpWDk1RFBYTWtnZ2g5M1R2bnBWb0taYVZhWDNOdHlGRGJOZnEyLzZaT2daNFlNZVgzb0VMUgpiVllpY01rU3lZRHJWbW9jeHZBMWdQQUsxd2NkVE1OcjlnY0F1b0VDQXdFQUFhT0JpRENCaFRBSkJnTlZIUk1FCkFqQUFNQXNHQTFVZER3UUVBd0lGNERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKREFZRFZSMFJCQVV3QTRJQktqQWRCZ05WSFE0RUZnUVVxaW40SEhXN08wR3NLbGgwUEJ2SFFZSzRQT013SHdZRApWUjBqQkJnd0ZvQVVZb3l3TXpJN1BpWGtJd3FMSTdkNzA5SmJnVmN3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCCkFCQ3p2NUUrb3hYT3RBUi9UWWE2YWJMVm94WENPWFZVeVFRell5VFJoekJOY0Vjbk1NeDBHc2V1NHRXeUlmem8KNmQ5LzRkOWdmdDlRNnVTS1RZUkhYU0VIQUFsMmlEWGdQTTZoSk0vNmpxQlE2N1ErVkVrUTJWVUMySDZEYjF1Qwo2VGdldk9MdlA1eDhrS2FjZVNnYTdmSHZJcW95OHVmbm1BSzlhd2ZobE9hajBjUWcxQXV6aW14blhzTVQvdkNVCm9Xa2xPZSt0TDA2OEd3LytIMFJQMTJ6N2t6VGJDbXZuRWU4bk1QSXNrU21NZTcvUnZLcUFuYTd0NHFDOVdyRXgKWlFZK0NlOVhrTnI3RGJaZnprTmpqUFV2OEozdHN2dzY5Zm1HcVBEWVpHMm1HQjRzeGFyNy9mZG4rbGd3MDVsRwpBbEhhaWpXTlVGTWtmcXgvUzZnampEL0NPZVpRcVltM1hLY3RCWkFSUjNJRUR0RWNEUkRzNllvczhCUTBzbS9ECkhnNG1XWWR4Y283WlpnUzF6ZWlhdkNwRWxDaXEzWnB5c0EvS1NLS056Y1RIRk5acXBxYWFNdVQvaTBuaUI1MmEKZmpFSDUzdk1wYXhUK1IvcFIxQ1NMREZ6VDI3OTFMaEprZkJWVWwzQkdnOVY2VCt6bkl1Nkk1aVU1RlZZbVl3UApubS9EYitncE9JalEyU0w5Wm1nVkNvdjFvNTBTU3ZLN1RYSFVIaXFoZXlucDAyR1ZYYXpFT295ODBWcG04dW9JCklvS2NFOS9IUldOT0F5Uk41cWtYRDBnalpJOWM1aUtjV25kQ1B1cnBFZENNZUdiems1cWRUNGhZSFFsM2RKeW8KNHJoZm9MN051R1VUa0o1ZCtGdFBwaXRISkNEVGdUb05LTVNGcTcxbzRoMXkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1d0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktVd2dnU2hBZ0VBQW9JQkFRRGZyVm9ZWkxmK1VEekMKL0Q0L29FVWFndVoyY2k2RWM1Mi9zVHBPenpHZHhjSm1odWZLSmx6aFpzMzIzdmhHWVd1RVQydmo0clZ4Si9uSAp3dlkyRnhEZXJYT1Z5MVVmU2ZsZ1JMV2lDWVgxNzF0UDU1SVIrTldtSkhBUUV0aXg3a3NzV0lNRXd5eHR1ZlMxCkxrUkRyaFNGNW1CU0lYbm51czFzRU5jdUVmZVZ1SVUyclB5RlRxVzVKcHZ0dHhWQWsreE8vKzk3UTE4QWxvc3gKdTBidG9HYjR2NXZoVUZBUVgyamk1Yk0wLzA3S2VkTUczbkI2bktFNW16R0FZbC9lUXoxekpJSUlmZDA3NTZWYQpDbVdsV2w5emJjaFEyelg2dHYrbVRvR2VHREhsOTZCQzBXMVdJbkRKRXNtQTYxWnFITWJ3TllEd0N0Y0hIVXpECmEvWUhBTHFCQWdNQkFBRUNnZjhQVjFhUUwxaEVteTl0amc1WkR0SFFxRGFJZGZ0UUhwVmdCY0ZtMVVyZzBnSzAKWjZHa204V0REZ2ZqYlNlTlZ1RXhlRnFqV2RwWDkyeFhHbGNJdUV4SFgvZStsTXNRdnBWUllMcGhQblRuQU1YVgp0MG9rN1NYTFBVRll4OC8vcUcvWkZHTzA0UHJYNmFMRFNuZ0NBYXhxOFpNbFpFUkMyaUJKaTAwVXhGNHNKR25WCklJeHFLeVRnbWpBcFV6c1BDWXF5ci9aNmJTRkVnbVNxNzJobmt2Rm1PV3NYcldzRlZLY05iUUplWTRMMEJuWUsKWk5xODNmemt6ekpxbVh3OEVncWFPNlhWMmJtVmYrM1hSL3ViMDRGeXRya0Y5bE1JU0pWOUhkQmtRaGV2VzZhVApoSG5pblV6VkgyUlh4M1piYWw3ck1ZL0lOMWNmaFVlWm9BZDQ0ZGtDZ1lFQTh1bHorbXpPWXg0QVNnWUo0eVNICkdmc1VQeXpJUU9vaEVJQmtxMWNrUHJlbVhsdEdoWTcrRmtYYmh5cnVuOTRIREJJZWR0RWt0YjlZSDkvT0xNME8KK056TlhTYnlaQ3ZTa1U1ZlNNeUpDc3E3L01JTlVpNUxGN1FLQVF1ZXk3WDgvUGU3NHhFQ29hN1AvSlJkTnYrdgpjUnkyUEZOSlNGbTJGdkxGeDA4TDFWa0NnWUVBNjdxV3Q5dENpQ24zRXVPM2hEeFptZ3VSWU55Tk9TWkowdjR5Cm9zaXZ0WFl2ZGVYWGxGZWFWSEJtZG5vZUYrVTZ6TXpUQUY0d09jNmZpenpCMjlGVkxjWjJmTE5tWXc0RmxENFEKR0wzMHVJckQ5WXJraGZWZm85TW9aVHo2cWJnc0xQQnNZTXljelpFOThyb3dmZVp2MkUzQ1lRaDhOL1lGbXRmOQptWTViNFdrQ2dZQkQyc2pHQkl6bWpTUGhpYXhMWWhISFJTYlR1dXU1am0xc0VhR05aMHM5cGNsNGhDREFBRUNqCjhpR3ZzV04xRHUyREJyQ3gyaHhhRkxoR054dDkwazVEWUZLUm1lYU42dHZvTVM5V3c2UG9ldGRtZE1LSjJWcXEKcFdWQ0EzLzVRYjRJNEI4QS8raHZSOGpic29vVGFmc1ZLc01ST09hNHFpNitYRlM1SnpDVUNRS0JnRmZLN2tjYgpTZlFjYlFDRC90MG8vTlg2YVBLQ01iYVBJLytJM0tMenl6engvMHNSaHZDZ2o4SFMrdFkxTlBBQlY1emV5OWJmClBXYktKWEZkOTNVK3lWSjdEN1h4dXJnNWlLcGxVdWxrRmJpRk5lWkZERWMzMDU3WURidG1zcFJ6RzBEQmFodkQKR01NV3pOT1J0RzJ2WFFoYUxZS2wvbDE1S3kwNE5DTDBlaFBCQW9HQkFMK2RmaVFmUjhYVGMwMzF6R0xwQm1kdQpOMU81aDM1cUdIT0s4M25MY1VQSnhzc0JTSGVxNTZEVHBic3VMRjY0V1c2bk5KSWRwckdRLzNpOFZldzhDa05ZCmtXY2ZGWkdUTGM4b2g4Tkw4bWpiZGtITCs3M3ZuVy9FbEZRRDlWZTE3WWN0cEZKbUcwcVBSaFVWQzhkSG5RYnAKWXRMTTQxb01qQlQ3NUdjRjBZZ2wKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= diff --git a/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-2.yaml b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-2.yaml new file mode 100644 index 00000000000..95e02e27319 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-2.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + name: tls-secret-2 + namespace: ${INSTALL_NAMESPACE} +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVQVENDQWlXZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFiTVFvd0NBWURWUVFEREFFcU1RMHcKQ3dZRFZRUUtEQVJ5YjI5ME1CNFhEVEl6TVRFd09ERTJORFExTjFvWERUTXpNVEV3TlRFMk5EUTFOMW93SGpFSwpNQWdHQTFVRUF3d0JLakVRTUE0R0ExVUVDZ3dIWjJGMFpYZGhlVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTit0V2hoa3QvNVFQTUw4UGorZ1JScUM1blp5TG9Sem5iK3hPazdQTVozRndtYUcKNThvbVhPRm16ZmJlK0VaaGE0UlBhK1BpdFhFbitjZkM5allYRU42dGM1WExWUjlKK1dCRXRhSUpoZlh2VzAvbgpraEg0MWFZa2NCQVMyTEh1U3l4WWd3VERMRzI1OUxVdVJFT3VGSVhtWUZJaGVlZTZ6V3dRMXk0Ujk1VzRoVGFzCi9JVk9wYmttbSsyM0ZVQ1Q3RTcvNzN0RFh3Q1dpekc3UnUyZ1p2aS9tK0ZRVUJCZmFPTGxzelQvVHNwNTB3YmUKY0hxY29UbWJNWUJpWDk1RFBYTWtnZ2g5M1R2bnBWb0taYVZhWDNOdHlGRGJOZnEyLzZaT2daNFlNZVgzb0VMUgpiVllpY01rU3lZRHJWbW9jeHZBMWdQQUsxd2NkVE1OcjlnY0F1b0VDQXdFQUFhT0JpRENCaFRBSkJnTlZIUk1FCkFqQUFNQXNHQTFVZER3UUVBd0lGNERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKREFZRFZSMFJCQVV3QTRJQktqQWRCZ05WSFE0RUZnUVVxaW40SEhXN08wR3NLbGgwUEJ2SFFZSzRQT013SHdZRApWUjBqQkJnd0ZvQVVZb3l3TXpJN1BpWGtJd3FMSTdkNzA5SmJnVmN3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCCkFCQ3p2NUUrb3hYT3RBUi9UWWE2YWJMVm94WENPWFZVeVFRell5VFJoekJOY0Vjbk1NeDBHc2V1NHRXeUlmem8KNmQ5LzRkOWdmdDlRNnVTS1RZUkhYU0VIQUFsMmlEWGdQTTZoSk0vNmpxQlE2N1ErVkVrUTJWVUMySDZEYjF1Qwo2VGdldk9MdlA1eDhrS2FjZVNnYTdmSHZJcW95OHVmbm1BSzlhd2ZobE9hajBjUWcxQXV6aW14blhzTVQvdkNVCm9Xa2xPZSt0TDA2OEd3LytIMFJQMTJ6N2t6VGJDbXZuRWU4bk1QSXNrU21NZTcvUnZLcUFuYTd0NHFDOVdyRXgKWlFZK0NlOVhrTnI3RGJaZnprTmpqUFV2OEozdHN2dzY5Zm1HcVBEWVpHMm1HQjRzeGFyNy9mZG4rbGd3MDVsRwpBbEhhaWpXTlVGTWtmcXgvUzZnampEL0NPZVpRcVltM1hLY3RCWkFSUjNJRUR0RWNEUkRzNllvczhCUTBzbS9ECkhnNG1XWWR4Y283WlpnUzF6ZWlhdkNwRWxDaXEzWnB5c0EvS1NLS056Y1RIRk5acXBxYWFNdVQvaTBuaUI1MmEKZmpFSDUzdk1wYXhUK1IvcFIxQ1NMREZ6VDI3OTFMaEprZkJWVWwzQkdnOVY2VCt6bkl1Nkk1aVU1RlZZbVl3UApubS9EYitncE9JalEyU0w5Wm1nVkNvdjFvNTBTU3ZLN1RYSFVIaXFoZXlucDAyR1ZYYXpFT295ODBWcG04dW9JCklvS2NFOS9IUldOT0F5Uk41cWtYRDBnalpJOWM1aUtjV25kQ1B1cnBFZENNZUdiems1cWRUNGhZSFFsM2RKeW8KNHJoZm9MN051R1VUa0o1ZCtGdFBwaXRISkNEVGdUb05LTVNGcTcxbzRoMXkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1d0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktVd2dnU2hBZ0VBQW9JQkFRRGZyVm9ZWkxmK1VEekMKL0Q0L29FVWFndVoyY2k2RWM1Mi9zVHBPenpHZHhjSm1odWZLSmx6aFpzMzIzdmhHWVd1RVQydmo0clZ4Si9uSAp3dlkyRnhEZXJYT1Z5MVVmU2ZsZ1JMV2lDWVgxNzF0UDU1SVIrTldtSkhBUUV0aXg3a3NzV0lNRXd5eHR1ZlMxCkxrUkRyaFNGNW1CU0lYbm51czFzRU5jdUVmZVZ1SVUyclB5RlRxVzVKcHZ0dHhWQWsreE8vKzk3UTE4QWxvc3gKdTBidG9HYjR2NXZoVUZBUVgyamk1Yk0wLzA3S2VkTUczbkI2bktFNW16R0FZbC9lUXoxekpJSUlmZDA3NTZWYQpDbVdsV2w5emJjaFEyelg2dHYrbVRvR2VHREhsOTZCQzBXMVdJbkRKRXNtQTYxWnFITWJ3TllEd0N0Y0hIVXpECmEvWUhBTHFCQWdNQkFBRUNnZjhQVjFhUUwxaEVteTl0amc1WkR0SFFxRGFJZGZ0UUhwVmdCY0ZtMVVyZzBnSzAKWjZHa204V0REZ2ZqYlNlTlZ1RXhlRnFqV2RwWDkyeFhHbGNJdUV4SFgvZStsTXNRdnBWUllMcGhQblRuQU1YVgp0MG9rN1NYTFBVRll4OC8vcUcvWkZHTzA0UHJYNmFMRFNuZ0NBYXhxOFpNbFpFUkMyaUJKaTAwVXhGNHNKR25WCklJeHFLeVRnbWpBcFV6c1BDWXF5ci9aNmJTRkVnbVNxNzJobmt2Rm1PV3NYcldzRlZLY05iUUplWTRMMEJuWUsKWk5xODNmemt6ekpxbVh3OEVncWFPNlhWMmJtVmYrM1hSL3ViMDRGeXRya0Y5bE1JU0pWOUhkQmtRaGV2VzZhVApoSG5pblV6VkgyUlh4M1piYWw3ck1ZL0lOMWNmaFVlWm9BZDQ0ZGtDZ1lFQTh1bHorbXpPWXg0QVNnWUo0eVNICkdmc1VQeXpJUU9vaEVJQmtxMWNrUHJlbVhsdEdoWTcrRmtYYmh5cnVuOTRIREJJZWR0RWt0YjlZSDkvT0xNME8KK056TlhTYnlaQ3ZTa1U1ZlNNeUpDc3E3L01JTlVpNUxGN1FLQVF1ZXk3WDgvUGU3NHhFQ29hN1AvSlJkTnYrdgpjUnkyUEZOSlNGbTJGdkxGeDA4TDFWa0NnWUVBNjdxV3Q5dENpQ24zRXVPM2hEeFptZ3VSWU55Tk9TWkowdjR5Cm9zaXZ0WFl2ZGVYWGxGZWFWSEJtZG5vZUYrVTZ6TXpUQUY0d09jNmZpenpCMjlGVkxjWjJmTE5tWXc0RmxENFEKR0wzMHVJckQ5WXJraGZWZm85TW9aVHo2cWJnc0xQQnNZTXljelpFOThyb3dmZVp2MkUzQ1lRaDhOL1lGbXRmOQptWTViNFdrQ2dZQkQyc2pHQkl6bWpTUGhpYXhMWWhISFJTYlR1dXU1am0xc0VhR05aMHM5cGNsNGhDREFBRUNqCjhpR3ZzV04xRHUyREJyQ3gyaHhhRkxoR054dDkwazVEWUZLUm1lYU42dHZvTVM5V3c2UG9ldGRtZE1LSjJWcXEKcFdWQ0EzLzVRYjRJNEI4QS8raHZSOGpic29vVGFmc1ZLc01ST09hNHFpNitYRlM1SnpDVUNRS0JnRmZLN2tjYgpTZlFjYlFDRC90MG8vTlg2YVBLQ01iYVBJLytJM0tMenl6engvMHNSaHZDZ2o4SFMrdFkxTlBBQlY1emV5OWJmClBXYktKWEZkOTNVK3lWSjdEN1h4dXJnNWlLcGxVdWxrRmJpRk5lWkZERWMzMDU3WURidG1zcFJ6RzBEQmFodkQKR01NV3pOT1J0RzJ2WFFoYUxZS2wvbDE1S3kwNE5DTDBlaFBCQW9HQkFMK2RmaVFmUjhYVGMwMzF6R0xwQm1kdQpOMU81aDM1cUdIT0s4M25MY1VQSnhzc0JTSGVxNTZEVHBic3VMRjY0V1c2bk5KSWRwckdRLzNpOFZldzhDa05ZCmtXY2ZGWkdUTGM4b2g4Tkw4bWpiZGtITCs3M3ZuVy9FbEZRRDlWZTE3WWN0cEZKbUcwcVBSaFVWQzhkSG5RYnAKWXRMTTQxb01qQlQ3NUdjRjBZZ2wKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= diff --git a/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-with-ca.yaml b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-with-ca.yaml new file mode 100644 index 00000000000..6c082460e11 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/tls-secret-with-ca.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + name: tls-secret-with-ca + namespace: ${INSTALL_NAMESPACE} +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVQVENDQWlXZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFiTVFvd0NBWURWUVFEREFFcU1RMHcKQ3dZRFZRUUtEQVJ5YjI5ME1CNFhEVEl6TVRFd09ERTJORFExTjFvWERUTXpNVEV3TlRFMk5EUTFOMW93SGpFSwpNQWdHQTFVRUF3d0JLakVRTUE0R0ExVUVDZ3dIWjJGMFpYZGhlVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTit0V2hoa3QvNVFQTUw4UGorZ1JScUM1blp5TG9Sem5iK3hPazdQTVozRndtYUcKNThvbVhPRm16ZmJlK0VaaGE0UlBhK1BpdFhFbitjZkM5allYRU42dGM1WExWUjlKK1dCRXRhSUpoZlh2VzAvbgpraEg0MWFZa2NCQVMyTEh1U3l4WWd3VERMRzI1OUxVdVJFT3VGSVhtWUZJaGVlZTZ6V3dRMXk0Ujk1VzRoVGFzCi9JVk9wYmttbSsyM0ZVQ1Q3RTcvNzN0RFh3Q1dpekc3UnUyZ1p2aS9tK0ZRVUJCZmFPTGxzelQvVHNwNTB3YmUKY0hxY29UbWJNWUJpWDk1RFBYTWtnZ2g5M1R2bnBWb0taYVZhWDNOdHlGRGJOZnEyLzZaT2daNFlNZVgzb0VMUgpiVllpY01rU3lZRHJWbW9jeHZBMWdQQUsxd2NkVE1OcjlnY0F1b0VDQXdFQUFhT0JpRENCaFRBSkJnTlZIUk1FCkFqQUFNQXNHQTFVZER3UUVBd0lGNERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKREFZRFZSMFJCQVV3QTRJQktqQWRCZ05WSFE0RUZnUVVxaW40SEhXN08wR3NLbGgwUEJ2SFFZSzRQT013SHdZRApWUjBqQkJnd0ZvQVVZb3l3TXpJN1BpWGtJd3FMSTdkNzA5SmJnVmN3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCCkFCQ3p2NUUrb3hYT3RBUi9UWWE2YWJMVm94WENPWFZVeVFRell5VFJoekJOY0Vjbk1NeDBHc2V1NHRXeUlmem8KNmQ5LzRkOWdmdDlRNnVTS1RZUkhYU0VIQUFsMmlEWGdQTTZoSk0vNmpxQlE2N1ErVkVrUTJWVUMySDZEYjF1Qwo2VGdldk9MdlA1eDhrS2FjZVNnYTdmSHZJcW95OHVmbm1BSzlhd2ZobE9hajBjUWcxQXV6aW14blhzTVQvdkNVCm9Xa2xPZSt0TDA2OEd3LytIMFJQMTJ6N2t6VGJDbXZuRWU4bk1QSXNrU21NZTcvUnZLcUFuYTd0NHFDOVdyRXgKWlFZK0NlOVhrTnI3RGJaZnprTmpqUFV2OEozdHN2dzY5Zm1HcVBEWVpHMm1HQjRzeGFyNy9mZG4rbGd3MDVsRwpBbEhhaWpXTlVGTWtmcXgvUzZnampEL0NPZVpRcVltM1hLY3RCWkFSUjNJRUR0RWNEUkRzNllvczhCUTBzbS9ECkhnNG1XWWR4Y283WlpnUzF6ZWlhdkNwRWxDaXEzWnB5c0EvS1NLS056Y1RIRk5acXBxYWFNdVQvaTBuaUI1MmEKZmpFSDUzdk1wYXhUK1IvcFIxQ1NMREZ6VDI3OTFMaEprZkJWVWwzQkdnOVY2VCt6bkl1Nkk1aVU1RlZZbVl3UApubS9EYitncE9JalEyU0w5Wm1nVkNvdjFvNTBTU3ZLN1RYSFVIaXFoZXlucDAyR1ZYYXpFT295ODBWcG04dW9JCklvS2NFOS9IUldOT0F5Uk41cWtYRDBnalpJOWM1aUtjV25kQ1B1cnBFZENNZUdiems1cWRUNGhZSFFsM2RKeW8KNHJoZm9MN051R1VUa0o1ZCtGdFBwaXRISkNEVGdUb05LTVNGcTcxbzRoMXkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1d0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktVd2dnU2hBZ0VBQW9JQkFRRGZyVm9ZWkxmK1VEekMKL0Q0L29FVWFndVoyY2k2RWM1Mi9zVHBPenpHZHhjSm1odWZLSmx6aFpzMzIzdmhHWVd1RVQydmo0clZ4Si9uSAp3dlkyRnhEZXJYT1Z5MVVmU2ZsZ1JMV2lDWVgxNzF0UDU1SVIrTldtSkhBUUV0aXg3a3NzV0lNRXd5eHR1ZlMxCkxrUkRyaFNGNW1CU0lYbm51czFzRU5jdUVmZVZ1SVUyclB5RlRxVzVKcHZ0dHhWQWsreE8vKzk3UTE4QWxvc3gKdTBidG9HYjR2NXZoVUZBUVgyamk1Yk0wLzA3S2VkTUczbkI2bktFNW16R0FZbC9lUXoxekpJSUlmZDA3NTZWYQpDbVdsV2w5emJjaFEyelg2dHYrbVRvR2VHREhsOTZCQzBXMVdJbkRKRXNtQTYxWnFITWJ3TllEd0N0Y0hIVXpECmEvWUhBTHFCQWdNQkFBRUNnZjhQVjFhUUwxaEVteTl0amc1WkR0SFFxRGFJZGZ0UUhwVmdCY0ZtMVVyZzBnSzAKWjZHa204V0REZ2ZqYlNlTlZ1RXhlRnFqV2RwWDkyeFhHbGNJdUV4SFgvZStsTXNRdnBWUllMcGhQblRuQU1YVgp0MG9rN1NYTFBVRll4OC8vcUcvWkZHTzA0UHJYNmFMRFNuZ0NBYXhxOFpNbFpFUkMyaUJKaTAwVXhGNHNKR25WCklJeHFLeVRnbWpBcFV6c1BDWXF5ci9aNmJTRkVnbVNxNzJobmt2Rm1PV3NYcldzRlZLY05iUUplWTRMMEJuWUsKWk5xODNmemt6ekpxbVh3OEVncWFPNlhWMmJtVmYrM1hSL3ViMDRGeXRya0Y5bE1JU0pWOUhkQmtRaGV2VzZhVApoSG5pblV6VkgyUlh4M1piYWw3ck1ZL0lOMWNmaFVlWm9BZDQ0ZGtDZ1lFQTh1bHorbXpPWXg0QVNnWUo0eVNICkdmc1VQeXpJUU9vaEVJQmtxMWNrUHJlbVhsdEdoWTcrRmtYYmh5cnVuOTRIREJJZWR0RWt0YjlZSDkvT0xNME8KK056TlhTYnlaQ3ZTa1U1ZlNNeUpDc3E3L01JTlVpNUxGN1FLQVF1ZXk3WDgvUGU3NHhFQ29hN1AvSlJkTnYrdgpjUnkyUEZOSlNGbTJGdkxGeDA4TDFWa0NnWUVBNjdxV3Q5dENpQ24zRXVPM2hEeFptZ3VSWU55Tk9TWkowdjR5Cm9zaXZ0WFl2ZGVYWGxGZWFWSEJtZG5vZUYrVTZ6TXpUQUY0d09jNmZpenpCMjlGVkxjWjJmTE5tWXc0RmxENFEKR0wzMHVJckQ5WXJraGZWZm85TW9aVHo2cWJnc0xQQnNZTXljelpFOThyb3dmZVp2MkUzQ1lRaDhOL1lGbXRmOQptWTViNFdrQ2dZQkQyc2pHQkl6bWpTUGhpYXhMWWhISFJTYlR1dXU1am0xc0VhR05aMHM5cGNsNGhDREFBRUNqCjhpR3ZzV04xRHUyREJyQ3gyaHhhRkxoR054dDkwazVEWUZLUm1lYU42dHZvTVM5V3c2UG9ldGRtZE1LSjJWcXEKcFdWQ0EzLzVRYjRJNEI4QS8raHZSOGpic29vVGFmc1ZLc01ST09hNHFpNitYRlM1SnpDVUNRS0JnRmZLN2tjYgpTZlFjYlFDRC90MG8vTlg2YVBLQ01iYVBJLytJM0tMenl6engvMHNSaHZDZ2o4SFMrdFkxTlBBQlY1emV5OWJmClBXYktKWEZkOTNVK3lWSjdEN1h4dXJnNWlLcGxVdWxrRmJpRk5lWkZERWMzMDU3WURidG1zcFJ6RzBEQmFodkQKR01NV3pOT1J0RzJ2WFFoYUxZS2wvbDE1S3kwNE5DTDBlaFBCQW9HQkFMK2RmaVFmUjhYVGMwMzF6R0xwQm1kdQpOMU81aDM1cUdIT0s4M25MY1VQSnhzc0JTSGVxNTZEVHBic3VMRjY0V1c2bk5KSWRwckdRLzNpOFZldzhDa05ZCmtXY2ZGWkdUTGM4b2g4Tkw4bWpiZGtITCs3M3ZuVy9FbEZRRDlWZTE3WWN0cEZKbUcwcVBSaFVWQzhkSG5RYnAKWXRMTTQxb01qQlQ3NUdjRjBZZ2wKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVQVENDQWlXZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFiTVFvd0NBWURWUVFEREFFcU1RMHcKQ3dZRFZRUUtEQVJ5YjI5ME1CNFhEVEl6TVRFd09ERTJORFExTjFvWERUTXpNVEV3TlRFMk5EUTFOMW93SGpFSwpNQWdHQTFVRUF3d0JLakVRTUE0R0ExVUVDZ3dIWjJGMFpYZGhlVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTit0V2hoa3QvNVFQTUw4UGorZ1JScUM1blp5TG9Sem5iK3hPazdQTVozRndtYUcKNThvbVhPRm16ZmJlK0VaaGE0UlBhK1BpdFhFbitjZkM5allYRU42dGM1WExWUjlKK1dCRXRhSUpoZlh2VzAvbgpraEg0MWFZa2NCQVMyTEh1U3l4WWd3VERMRzI1OUxVdVJFT3VGSVhtWUZJaGVlZTZ6V3dRMXk0Ujk1VzRoVGFzCi9JVk9wYmttbSsyM0ZVQ1Q3RTcvNzN0RFh3Q1dpekc3UnUyZ1p2aS9tK0ZRVUJCZmFPTGxzelQvVHNwNTB3YmUKY0hxY29UbWJNWUJpWDk1RFBYTWtnZ2g5M1R2bnBWb0taYVZhWDNOdHlGRGJOZnEyLzZaT2daNFlNZVgzb0VMUgpiVllpY01rU3lZRHJWbW9jeHZBMWdQQUsxd2NkVE1OcjlnY0F1b0VDQXdFQUFhT0JpRENCaFRBSkJnTlZIUk1FCkFqQUFNQXNHQTFVZER3UUVBd0lGNERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKREFZRFZSMFJCQVV3QTRJQktqQWRCZ05WSFE0RUZnUVVxaW40SEhXN08wR3NLbGgwUEJ2SFFZSzRQT013SHdZRApWUjBqQkJnd0ZvQVVZb3l3TXpJN1BpWGtJd3FMSTdkNzA5SmJnVmN3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCCkFCQ3p2NUUrb3hYT3RBUi9UWWE2YWJMVm94WENPWFZVeVFRell5VFJoekJOY0Vjbk1NeDBHc2V1NHRXeUlmem8KNmQ5LzRkOWdmdDlRNnVTS1RZUkhYU0VIQUFsMmlEWGdQTTZoSk0vNmpxQlE2N1ErVkVrUTJWVUMySDZEYjF1Qwo2VGdldk9MdlA1eDhrS2FjZVNnYTdmSHZJcW95OHVmbm1BSzlhd2ZobE9hajBjUWcxQXV6aW14blhzTVQvdkNVCm9Xa2xPZSt0TDA2OEd3LytIMFJQMTJ6N2t6VGJDbXZuRWU4bk1QSXNrU21NZTcvUnZLcUFuYTd0NHFDOVdyRXgKWlFZK0NlOVhrTnI3RGJaZnprTmpqUFV2OEozdHN2dzY5Zm1HcVBEWVpHMm1HQjRzeGFyNy9mZG4rbGd3MDVsRwpBbEhhaWpXTlVGTWtmcXgvUzZnampEL0NPZVpRcVltM1hLY3RCWkFSUjNJRUR0RWNEUkRzNllvczhCUTBzbS9ECkhnNG1XWWR4Y283WlpnUzF6ZWlhdkNwRWxDaXEzWnB5c0EvS1NLS056Y1RIRk5acXBxYWFNdVQvaTBuaUI1MmEKZmpFSDUzdk1wYXhUK1IvcFIxQ1NMREZ6VDI3OTFMaEprZkJWVWwzQkdnOVY2VCt6bkl1Nkk1aVU1RlZZbVl3UApubS9EYitncE9JalEyU0w5Wm1nVkNvdjFvNTBTU3ZLN1RYSFVIaXFoZXlucDAyR1ZYYXpFT295ODBWcG04dW9JCklvS2NFOS9IUldOT0F5Uk41cWtYRDBnalpJOWM1aUtjV25kQ1B1cnBFZENNZUdiems1cWRUNGhZSFFsM2RKeW8KNHJoZm9MN051R1VUa0o1ZCtGdFBwaXRISkNEVGdUb05LTVNGcTcxbzRoMXkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml new file mode 100644 index 00000000000..078cba343d3 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml @@ -0,0 +1,18 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +metadata: + name: vs-1 +spec: + sslConfig: + secretRef: + name: tls-secret-1 + namespace: ${INSTALL_NAMESPACE} + virtualHost: + domains: + - 'vs-1' + routes: + - matchers: + - exact: / + directResponseAction: + status: 200 + body: "success from vs-1" diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml new file mode 100644 index 00000000000..ff3f02078bd --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml @@ -0,0 +1,18 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +metadata: + name: vs-2 +spec: + sslConfig: + secretRef: + name: tls-secret-2 + namespace: ${INSTALL_NAMESPACE} + virtualHost: + domains: + - 'vs-2' + routes: + - matchers: + - exact: / + directResponseAction: + status: 200 + body: "success from vs-2" diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml new file mode 100644 index 00000000000..78cb47cb818 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml @@ -0,0 +1,19 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +metadata: + name: vs-with-oneway +spec: + sslConfig: + oneWayTls: true + secretRef: + name: tls-secret-with-ca + namespace: ${INSTALL_NAMESPACE} + virtualHost: + domains: + - 'vs-with-oneway' + routes: + - matchers: + - exact: / + directResponseAction: + status: 200 + body: "success from vs-with-oneway" diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml new file mode 100644 index 00000000000..d2afc5970b6 --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml @@ -0,0 +1,18 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +metadata: + name: vs-without-oneway +spec: + sslConfig: + secretRef: + name: tls-secret-with-ca + namespace: ${INSTALL_NAMESPACE} + virtualHost: + domains: + - 'vs-without-oneway' + routes: + - matchers: + - exact: / + directResponseAction: + status: 200 + body: "success from vs-without-oneway" diff --git a/test/kubernetes/e2e/features/server_tls/types.go b/test/kubernetes/e2e/features/server_tls/types.go new file mode 100644 index 00000000000..3f4b83d6fcf --- /dev/null +++ b/test/kubernetes/e2e/features/server_tls/types.go @@ -0,0 +1,120 @@ +package client_tls + +import ( + "net/http" + "path/filepath" + + "github.com/onsi/gomega" + kubev1 "github.com/solo-io/gloo/projects/gateway/pkg/api/v1/kube/apis/gateway.solo.io/v1" + "github.com/solo-io/gloo/test/gomega/matchers" + "github.com/solo-io/skv2/codegen/util" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + tlsSecret1ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-1.yaml") + tlsSecret2ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-2.yaml") + tlsSecretWithCaManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-with-ca.yaml") + vs1ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-1.yaml") + vs2ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-2.yaml") + vsWithOneWayManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-with-oneway.yaml") + vsWithoutOneWayManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-without-oneway.yaml") + + // When we apply the deployer-provision.yaml file, we expect resources to be created with this metadata + glooProxyObjectMeta = func(ns string) metav1.ObjectMeta { + return metav1.ObjectMeta{ + Name: "gloo-proxy-gw", + Namespace: ns, + } + } + proxyDeployment = func(ns string) *appsv1.Deployment { + return &appsv1.Deployment{ObjectMeta: glooProxyObjectMeta(ns)} + } + proxyService = func(ns string) *corev1.Service { + return &corev1.Service{ObjectMeta: glooProxyObjectMeta(ns)} + } + + vs1 = func(ns string) *kubev1.VirtualService { + return &kubev1.VirtualService{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vs-1", + Namespace: ns, + }, + } + } + vs2 = func(ns string) *kubev1.VirtualService { + return &kubev1.VirtualService{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vs-2", + Namespace: ns, + }, + } + } + vsWithOneWay = func(ns string) *kubev1.VirtualService { + return &kubev1.VirtualService{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vs-with-oneway", + Namespace: ns, + }, + } + } + vsWithoutOneWay = func(ns string) *kubev1.VirtualService { + return &kubev1.VirtualService{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vs-without-oneway", + Namespace: ns, + }, + } + } + tlsSecret1 = func(ns string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "tls-secret-1", + Namespace: ns, + }, + } + } + tlsSecret2 = func(ns string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "tls-secret-2", + Namespace: ns, + }, + } + } + tlsSecretWithCa = func(ns string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "tls-secret-with-ca", + Namespace: ns, + }, + } + } + + expectedHealthyResponse1 = &matchers.HttpResponse{ + StatusCode: http.StatusOK, + Body: gomega.ContainSubstring("success from vs-1"), + } + expectedHealthyResponse2 = &matchers.HttpResponse{ + StatusCode: http.StatusOK, + Body: gomega.ContainSubstring("success from vs-2"), + } + expectedHealthyResponseWithOneWay = &matchers.HttpResponse{ + StatusCode: http.StatusOK, + Body: gomega.ContainSubstring("success from vs-with-oneway"), + } + expectedHealthyResponseWithoutOneWay = &matchers.HttpResponse{ + StatusCode: http.StatusOK, + Body: gomega.ContainSubstring("success from vs-without-oneway"), + } + expectedCertVerifyFailedResponse = &matchers.HttpResponse{ + StatusCode: http.StatusServiceUnavailable, + Body: gomega.ContainSubstring("CERTIFICATE_VERIFY_FAILED"), + } + expectedNoFilterChainFailedResponse = &matchers.HttpResponse{ + StatusCode: http.StatusServiceUnavailable, + Body: gomega.ContainSubstring("OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection"), + } +) From 531e91d5a3ea309d27447fb798fc380827a994ed Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 8 Aug 2024 13:36:52 -0400 Subject: [PATCH 04/39] fix tests --- pkg/utils/kubeutils/kubectl/cli.go | 5 +- pkg/utils/requestutils/curl/request.go | 4 +- .../e2e/features/server_tls/suite.go | 133 +++++++++++------- .../features/server_tls/testdata/vs-1.yaml | 2 + .../features/server_tls/testdata/vs-2.yaml | 2 + .../server_tls/testdata/vs-with-oneway.yaml | 2 + .../testdata/vs-without-oneway.yaml | 2 + .../e2e/features/server_tls/types.go | 47 ++++--- test/kubernetes/e2e/tests/edge_gw_tests.go | 2 + 9 files changed, 127 insertions(+), 72 deletions(-) diff --git a/pkg/utils/kubeutils/kubectl/cli.go b/pkg/utils/kubeutils/kubectl/cli.go index 7dfef922289..749a9df0b0a 100644 --- a/pkg/utils/kubeutils/kubectl/cli.go +++ b/pkg/utils/kubeutils/kubectl/cli.go @@ -299,11 +299,12 @@ func (c *Cli) Scale(ctx context.Context, namespace string, resource string, repl // RestartDeployment restarts a deployment. It does not wait for the deployment to be ready. func (c *Cli) RestartDeployment(ctx context.Context, name string, extraArgs ...string) error { - return c.RunCommand(ctx, + args := append([]string{ "rollout", "restart", fmt.Sprintf("deployment/%s", name), - ) + }, extraArgs...) + return c.RunCommand(ctx, args...) } // RestartDeploymentAndWait restarts a deployment and waits for it to become healthy. diff --git a/pkg/utils/requestutils/curl/request.go b/pkg/utils/requestutils/curl/request.go index b913ba5bec3..b38474a2218 100644 --- a/pkg/utils/requestutils/curl/request.go +++ b/pkg/utils/requestutils/curl/request.go @@ -134,9 +134,9 @@ func (c *requestConfig) generateArgs() []string { var fullAddress string if c.sni != "" { - sniResolution := fmt.Sprintf("%s:%d:%s", c.sni, c.port, c.host) + sniResolution := fmt.Sprintf("%s:%d:%s:%d", c.sni, c.port, c.host, c.port) fullAddress = fmt.Sprintf("%s://%s:%d", c.scheme, c.sni, c.port) - args = append(args, "--resolve", sniResolution) + args = append(args, "--connect-to", sniResolution) } else { fullAddress = fmt.Sprintf("%v://%s:%v/%s", c.scheme, c.host, c.port, c.path) if len(c.queryParameters) > 0 { diff --git a/test/kubernetes/e2e/features/server_tls/suite.go b/test/kubernetes/e2e/features/server_tls/suite.go index 6d489634caf..1985add1738 100644 --- a/test/kubernetes/e2e/features/server_tls/suite.go +++ b/test/kubernetes/e2e/features/server_tls/suite.go @@ -1,4 +1,4 @@ -package client_tls +package server_tls import ( "context" @@ -30,6 +30,9 @@ type serverTlsTestingSuite struct { // ns is the namespace in which the feature suite is being executed. ns string + + tlsSecret1, tlsSecret2, tlsSecretWithCa []byte + vs1, vs2, vsWithOneWay, vsWithoutOneWay []byte } func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite.TestingSuite { @@ -41,7 +44,25 @@ func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite. } func (s *serverTlsTestingSuite) SetupSuite() { - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.CurlPodManifest) + var err error + // We are substituting our namespace via os.ExpandEnv in order to place our referenced + // resources in our NS. + s.tlsSecret1, err = tlsSecret1Manifest() + s.NoError(err, "can substitute NS in tlsSecret1") + s.tlsSecret2, err = tlsSecret2Manifest() + s.NoError(err, "can substitute NS in tlsSecret2") + s.tlsSecretWithCa, err = tlsSecretWithCaManifest() + s.NoError(err, "can substitute NS in tlsSecretWithCa") + s.vs1, err = vs1Manifest() + s.NoError(err, "can substitute NS in vs1") + s.vs2, err = vs2Manifest() + s.NoError(err, "can substitute NS in vs2") + s.vsWithOneWay, err = vsWithOneWayManifest() + s.NoError(err, "can substitute NS in vsWithOneWay") + s.vsWithoutOneWay, err = vsWithoutOneWayManifest() + s.NoError(err, "can substitute NS in vsWithoutOneWay") + + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.CurlPodManifest) s.NoError(err, "can apply Curl setup manifest") } @@ -57,23 +78,23 @@ func (s *serverTlsTestingSuite) TestServerTls() { vs1 := vs1(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can delete vs1 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1) - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret manifest file") // tlsSecret2 is deleted in the process of the test. s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns)) }) // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret1) s.NoError(err, "can apply tls secret 1 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns)) - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") - // Assert that we have traffic working on both VS. + // Assert that we have traffic working on our VS. s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) } @@ -84,26 +105,26 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { vs2 := vs2(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can delete vs1 manifest file") - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs2ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can delete vs2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret manifest file") // tlsSecret2 is deleted in the process of the test. s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) }) // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret1) s.NoError(err, "can apply tls secret 1 manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret2) s.NoError(err, "can apply tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs2ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can apply vs2 manifest file") // Assert that we have traffic working on both VS. @@ -121,40 +142,40 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecr vs2 := vs2(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can delete vs1 manifest file") - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vs2ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can delete vs2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret1ManifestFile) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret manifest file") // tlsSecret2 is deleted in the process of the test. s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) }) // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret1) s.NoError(err, "can apply tls secret 1 manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret2) s.NoError(err, "can apply tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs1ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vs2ManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can apply vs2 manifest file") // Assert that we have traffic working on both VS. s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) s.assertEventualResponse(vs2.GetName(), expectedHealthyResponse2) - // Delete the secret referenced by VS 1. - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecret2ManifestFile) + // Delete the secret referenced by VS 2. + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret2) s.NoError(err, "can delete tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret2(s.ns)) // Assert that we have traffic working on VS 1 but failed traffic on VS 2. s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) - s.assertEventualResponse(vs2.GetName(), expectedNoFilterChainFailedResponse) + s.assertEventualError(vs2.GetName(), 35) // Restart the Gloo deployment err = s.testInstallation.Actions.Kubectl().RestartDeploymentAndWait(s.ctx, "gloo", "-n", s.ns) @@ -164,7 +185,7 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecr // Assert that we have traffic working on VS 1 but failed traffic on VS 2. s.assertEventuallyConsistentResponse(vs1.GetName(), expectedHealthyResponse1, timeout, polling) - s.assertEventuallyConsistentResponse(vs2.GetName(), expectedNoFilterChainFailedResponse, timeout, polling) + s.assertEventualError(vs2.GetName(), 35) } @@ -175,21 +196,21 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { vs := vsWithoutOneWay(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can delete vs manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecretWithCaManifestFile) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can delete tls secret manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) }) // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecretWithCaManifestFile) + err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can apply tls secret manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") - s.assertEventualResponse(vs.GetName(), expectedCertVerifyFailedResponse) + s.assertEventualError(vs.GetName(), 16) } // TestOneWayServerTlsWorksWithOneWayTls validates that one-way server TLS traffic succeeds when CA data @@ -199,23 +220,35 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsWorksWithOneWayTls() { vs := vsWithOneWay(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, vsWithOneWayManifestFile, "-n", s.ns) + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vsWithOneWay, "-n", s.ns) s.NoError(err, "can delete vs manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, tlsSecretWithCaManifestFile) + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can delete tls secret manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) }) // ordering here matters if strict validation enabled - err := s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, tlsSecret1ManifestFile) + err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can apply tls secret manifest file") - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, vsWithoutOneWayManifestFile, "-n", s.ns) + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") s.assertEventualResponse(vs.GetName(), expectedHealthyResponseWithOneWay) } +func curlOptions(ns, hostHeaderValue string) []curl.Option { + return []curl.Option{ + curl.WithHost(kubeutils.ServiceFQDN(metav1.ObjectMeta{Name: defaults.GatewayProxyName, Namespace: ns})), + // The host header must match the domain in the VirtualService + curl.WithHostHeader(hostHeaderValue), + curl.WithPort(443), + curl.IgnoreServerCert(), + curl.WithScheme("https"), + curl.WithSni(hostHeaderValue), + } +} + func (s *serverTlsTestingSuite) assertEventualResponse(hostHeaderValue string, matcher *matchers.HttpResponse) { // Make sure our proxy pod is running @@ -228,13 +261,7 @@ func (s *serverTlsTestingSuite) assertEventualResponse(hostHeaderValue string, m s.testInstallation.Assertions.AssertEventualCurlResponse( s.ctx, testdefaults.CurlPodExecOpt, - []curl.Option{ - curl.WithHost(kubeutils.ServiceFQDN(metav1.ObjectMeta{Name: defaults.GatewayProxyName, Namespace: s.testInstallation.Metadata.InstallNamespace})), - // The host header must match the domain in the VirtualService - curl.WithHostHeader(hostHeaderValue), - curl.WithPort(443), - curl.IgnoreServerCert(), - }, + curlOptions(s.ns, hostHeaderValue), matcher) } @@ -250,13 +277,23 @@ func (s *serverTlsTestingSuite) assertEventuallyConsistentResponse(hostHeaderVal s.testInstallation.Assertions.AssertEventuallyConsistentCurlResponse( s.ctx, testdefaults.CurlPodExecOpt, - []curl.Option{ - curl.WithHost(kubeutils.ServiceFQDN(metav1.ObjectMeta{Name: defaults.GatewayProxyName, Namespace: s.testInstallation.Metadata.InstallNamespace})), - // The host header must match the domain in the VirtualService - curl.WithHostHeader(hostHeaderValue), - curl.WithPort(443), - curl.IgnoreServerCert(), - }, + curlOptions(s.ns, hostHeaderValue), matcher, timeouts...) } + +func (s *serverTlsTestingSuite) assertEventualError(hostHeaderValue string, code int) { + + // Make sure our proxy pod is running + listOpts := metav1.ListOptions{ + LabelSelector: "gloo=gateway-proxy", + } + s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, s.testInstallation.Metadata.InstallNamespace, listOpts, time.Minute*2) + + // Check curl works against expected response + s.testInstallation.Assertions.AssertEventualCurlError( + s.ctx, + testdefaults.CurlPodExecOpt, + curlOptions(s.ns, hostHeaderValue), + code) +} diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml index 078cba343d3..e0657f37088 100644 --- a/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-1.yaml @@ -4,6 +4,8 @@ metadata: name: vs-1 spec: sslConfig: + sniDomains: + - vs-1 secretRef: name: tls-secret-1 namespace: ${INSTALL_NAMESPACE} diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml index ff3f02078bd..20e9e075bc2 100644 --- a/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-2.yaml @@ -4,6 +4,8 @@ metadata: name: vs-2 spec: sslConfig: + sniDomains: + - vs-2 secretRef: name: tls-secret-2 namespace: ${INSTALL_NAMESPACE} diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml index 78cb47cb818..7775ed8c766 100644 --- a/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-with-oneway.yaml @@ -4,6 +4,8 @@ metadata: name: vs-with-oneway spec: sslConfig: + sniDomains: + - vs-with-oneway oneWayTls: true secretRef: name: tls-secret-with-ca diff --git a/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml b/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml index d2afc5970b6..d7537dab799 100644 --- a/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml +++ b/test/kubernetes/e2e/features/server_tls/testdata/vs-without-oneway.yaml @@ -4,6 +4,8 @@ metadata: name: vs-without-oneway spec: sslConfig: + sniDomains: + - vs-without-oneway secretRef: name: tls-secret-with-ca namespace: ${INSTALL_NAMESPACE} diff --git a/test/kubernetes/e2e/features/server_tls/types.go b/test/kubernetes/e2e/features/server_tls/types.go index 3f4b83d6fcf..8d437d515da 100644 --- a/test/kubernetes/e2e/features/server_tls/types.go +++ b/test/kubernetes/e2e/features/server_tls/types.go @@ -1,7 +1,8 @@ -package client_tls +package server_tls import ( "net/http" + "os" "path/filepath" "github.com/onsi/gomega" @@ -14,13 +15,13 @@ import ( ) var ( - tlsSecret1ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-1.yaml") - tlsSecret2ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-2.yaml") - tlsSecretWithCaManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "tls-secret-with-ca.yaml") - vs1ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-1.yaml") - vs2ManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-2.yaml") - vsWithOneWayManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-with-oneway.yaml") - vsWithoutOneWayManifestFile = filepath.Join(util.MustGetThisDir(), "testdata", "vs-without-oneway.yaml") + tlsSecret1Manifest = func() ([]byte, error) { return manifestFromFile("tls-secret-1.yaml") } + tlsSecret2Manifest = func() ([]byte, error) { return manifestFromFile("tls-secret-2.yaml") } + tlsSecretWithCaManifest = func() ([]byte, error) { return manifestFromFile("tls-secret-with-ca.yaml") } + vs1Manifest = func() ([]byte, error) { return manifestFromFile("vs-1.yaml") } + vs2Manifest = func() ([]byte, error) { return manifestFromFile("vs-2.yaml") } + vsWithOneWayManifest = func() ([]byte, error) { return manifestFromFile("vs-with-oneway.yaml") } + vsWithoutOneWayManifest = func() ([]byte, error) { return manifestFromFile("vs-without-oneway.yaml") } // When we apply the deployer-provision.yaml file, we expect resources to be created with this metadata glooProxyObjectMeta = func(ns string) metav1.ObjectMeta { @@ -105,16 +106,22 @@ var ( StatusCode: http.StatusOK, Body: gomega.ContainSubstring("success from vs-with-oneway"), } - expectedHealthyResponseWithoutOneWay = &matchers.HttpResponse{ - StatusCode: http.StatusOK, - Body: gomega.ContainSubstring("success from vs-without-oneway"), - } - expectedCertVerifyFailedResponse = &matchers.HttpResponse{ - StatusCode: http.StatusServiceUnavailable, - Body: gomega.ContainSubstring("CERTIFICATE_VERIFY_FAILED"), - } - expectedNoFilterChainFailedResponse = &matchers.HttpResponse{ - StatusCode: http.StatusServiceUnavailable, - Body: gomega.ContainSubstring("OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection"), - } + // These codes are defined at https://curl.se/libcurl/c/libcurl-errors.html. + // These were determined experimentally. + expectedFailedResponseCodeInvalidVs = 16 + expectedFailedResponseCertRequested = 35 ) + +func manifestFromFile(fname string) ([]byte, error) { + return withSubstitutions(filepath.Join(util.MustGetThisDir(), "testdata", fname)) +} +func withSubstitutions(fname string) ([]byte, error) { + // VS with secret should be accepted, need to substitute the secret ns + raw, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + + // Replace environment variables placeholders with their values + return []byte(os.ExpandEnv(string(raw))), nil +} diff --git a/test/kubernetes/e2e/tests/edge_gw_tests.go b/test/kubernetes/e2e/tests/edge_gw_tests.go index 5d3faad46db..7c719402f24 100644 --- a/test/kubernetes/e2e/tests/edge_gw_tests.go +++ b/test/kubernetes/e2e/tests/edge_gw_tests.go @@ -6,6 +6,7 @@ import ( "github.com/solo-io/gloo/test/kubernetes/e2e/features/client_tls" "github.com/solo-io/gloo/test/kubernetes/e2e/features/headless_svc" "github.com/solo-io/gloo/test/kubernetes/e2e/features/port_routing" + "github.com/solo-io/gloo/test/kubernetes/e2e/features/server_tls" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_allow_warnings" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_reject_invalid" ) @@ -19,6 +20,7 @@ func EdgeGwSuiteRunner() e2e.SuiteRunner { edgeGwSuiteRunner.Register("ValidationAllowWarnings", validation_allow_warnings.NewTestingSuite) edgeGwSuiteRunner.Register("GlooAdminServer", admin_server.NewTestingSuite) edgeGwSuiteRunner.Register("ClientTls", client_tls.NewTestingSuite) + edgeGwSuiteRunner.Register("ServerTls", server_tls.NewTestingSuite) return edgeGwSuiteRunner } From e322dcbcb34c0db9cd49ec478c705b956047f1db Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 8 Aug 2024 13:40:08 -0400 Subject: [PATCH 05/39] add changelog --- changelog/v1.18.0-beta14/missing-tls-secret.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/v1.18.0-beta14/missing-tls-secret.yaml diff --git a/changelog/v1.18.0-beta14/missing-tls-secret.yaml b/changelog/v1.18.0-beta14/missing-tls-secret.yaml new file mode 100644 index 00000000000..76ebb9afd00 --- /dev/null +++ b/changelog/v1.18.0-beta14/missing-tls-secret.yaml @@ -0,0 +1,8 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/gloo/issues/6957 + resolvesIssue: false + description: >- + Fix for issue where a missing TLS secret was treated by validation as an error, + potentially bringing down the entire HTTPS gateway if the gloo pod restarts while + in this bad state. From 3ba238076b1a3478c607fbda8fe10186f95bc826 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 9 Aug 2024 09:22:22 -0400 Subject: [PATCH 06/39] fixes add warnings to proxy report so it appears in the warnings after translation only return a warning if the error produced by ResolveCommonSslConfig is SslSecretNotFoundError --- projects/gloo/pkg/translator/clusters.go | 6 +++++- projects/gloo/pkg/translator/filter_chain.go | 14 ++++++++++---- projects/gloo/pkg/translator/translator_test.go | 5 +++-- projects/gloo/pkg/utils/ssl.go | 7 ++++--- .../gloo/pkg/utils/validation/proxy_validation.go | 5 ++--- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index 750845be546..451cbfd85a6 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -122,7 +122,11 @@ func (t *translatorInstance) initializeCluster( applyDefaultsToUpstreamSslConfig(sslConfig, t.settings.GetUpstreamOptions()) cfg, err := utils.NewSslConfigTranslator().ResolveUpstreamSslConfig(*secrets, sslConfig) if err != nil { - reports.AddWarning(upstream, err.Error()) + if errors.Is(err, utils.SslSecretNotFoundError) { + reports.AddWarning(upstream, err.Error()) + } else { + reports.AddError(upstream, err) + } } else { typedConfig, err := utils.MessageToAny(cfg) if err != nil { diff --git a/projects/gloo/pkg/translator/filter_chain.go b/projects/gloo/pkg/translator/filter_chain.go index 30c609b874b..0043ed28085 100644 --- a/projects/gloo/pkg/translator/filter_chain.go +++ b/projects/gloo/pkg/translator/filter_chain.go @@ -294,10 +294,16 @@ func (h *httpFilterChainTranslator) createFilterChainsFromSslConfiguration( // get secrets downstreamTlsContext, err := h.sslConfigTranslator.ResolveDownstreamSslConfig(snap.Secrets, sslConfig) if err != nil { - // We add this as a warning to support eventual consistency with TLS Secret resources. In this way, - // the Proxy producing this will not be considered Rejected, and the HTTPS Listener will still operate - // as expected with a VirtualService in error. - validation.AppendListenerWarning(h.parentReport, validationapi.ListenerReport_Warning_SSLConfigWarning, err.Error()) + if errors.Is(err, utils.SslSecretNotFoundError) { + // We add this as a warning to support eventual consistency with TLS Secret resources. In this way, + // the Proxy producing this will not be considered Rejected, and the HTTPS Listener will still operate + // as expected with a VirtualService in error. + validation.AppendListenerWarning(h.parentReport, validationapi.ListenerReport_Warning_SSLConfigWarning, err.Error()) + } else { + // If our error is any other than SslSecretNotFoundError, we assume it is due to a malformed secret or otherwise + // irreconcilable issue. + validation.AppendListenerError(h.parentReport, validationapi.ListenerReport_Error_SSLConfigError, err.Error()) + } continue } diff --git a/projects/gloo/pkg/translator/translator_test.go b/projects/gloo/pkg/translator/translator_test.go index 6797d06e0e6..d9bd8c418a4 100644 --- a/projects/gloo/pkg/translator/translator_test.go +++ b/projects/gloo/pkg/translator/translator_test.go @@ -2855,8 +2855,9 @@ var _ = Describe("Translator", func() { }} _, errs, _ := translator.Translate(params, proxyClone) - Expect(errs.Validate()).To(HaveOccurred()) - Expect(errs.Validate().Error()).To(ContainSubstring("Listener Error: SSLConfigError. Reason: SSL secret not found: list did not find secret")) + resultantErr := errs.ValidateStrict() + Expect(resultantErr).To(HaveOccurred()) + Expect(resultantErr.Error()).To(ContainSubstring("Listener Warning: SSLConfigWarning. Reason: SSL secret not found: list did not find secret")) }) }) diff --git a/projects/gloo/pkg/utils/ssl.go b/projects/gloo/pkg/utils/ssl.go index b4249dc54c3..d6fc79b4472 100644 --- a/projects/gloo/pkg/utils/ssl.go +++ b/projects/gloo/pkg/utils/ssl.go @@ -31,8 +31,9 @@ var ( return eris.Errorf("ocsp staple policy %v not a valid policy", p) } - SslSecretNotFoundError = func(err error) error { - return eris.Wrapf(err, "SSL secret not found") + SslSecretNotFoundError = eris.New("SSL secret not found") + sslSecretNotFoundError = func(err error) error { + return eris.Wrapf(err, SslSecretNotFoundError.Error()) } NotTlsSecretError = func(ref *core.ResourceRef) error { @@ -413,7 +414,7 @@ func (s *sslConfigTranslator) ResolveCommonSslConfig(cs CertSource, secrets v1.S func getSslSecrets(ref core.ResourceRef, secrets v1.SecretList) (string, string, string, []byte, error) { secret, err := secrets.Find(ref.Strings()) if err != nil { - return "", "", "", nil, SslSecretNotFoundError(err) + return "", "", "", nil, sslSecretNotFoundError(err) } sslSecret, ok := secret.GetKind().(*v1.Secret_Tls) diff --git a/projects/gloo/pkg/utils/validation/proxy_validation.go b/projects/gloo/pkg/utils/validation/proxy_validation.go index 34a2bc809a6..9e85478abec 100644 --- a/projects/gloo/pkg/utils/validation/proxy_validation.go +++ b/projects/gloo/pkg/utils/validation/proxy_validation.go @@ -360,12 +360,11 @@ func GetProxyWarning(proxyRpt *validation.ProxyReport) []string { var warnings []string for _, listenerReport := range proxyRpt.GetListenerReports() { + warnings = append(warnings, GetListenerWarning(listenerReport)...) vhostReports := utils.GetVhostReportsFromListenerReport(listenerReport) for _, vhReport := range vhostReports { for _, routeReport := range vhReport.GetRouteReports() { - if warns := GetRouteWarning(routeReport); len(warns) > 0 { - warnings = append(warnings, warns...) - } + warnings = append(warnings, GetRouteWarning(routeReport)...) } } for _, tcpHostReport := range utils.GetTcpHostReportsFromListenerReport(listenerReport) { From 06a599995c1a4b26dfcd84c0671f7a833b2c5767 Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Fri, 9 Aug 2024 18:02:38 +0000 Subject: [PATCH 07/39] Adding changelog file to new location --- changelog/v1.18.0-beta15/missing-tls-secret.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/v1.18.0-beta15/missing-tls-secret.yaml diff --git a/changelog/v1.18.0-beta15/missing-tls-secret.yaml b/changelog/v1.18.0-beta15/missing-tls-secret.yaml new file mode 100644 index 00000000000..76ebb9afd00 --- /dev/null +++ b/changelog/v1.18.0-beta15/missing-tls-secret.yaml @@ -0,0 +1,8 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/gloo/issues/6957 + resolvesIssue: false + description: >- + Fix for issue where a missing TLS secret was treated by validation as an error, + potentially bringing down the entire HTTPS gateway if the gloo pod restarts while + in this bad state. From b847a7e561f4b38d9e187e262dd8abd9eb59a49a Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Fri, 9 Aug 2024 18:02:39 +0000 Subject: [PATCH 08/39] Deleting changelog file from old location --- changelog/v1.18.0-beta14/missing-tls-secret.yaml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 changelog/v1.18.0-beta14/missing-tls-secret.yaml diff --git a/changelog/v1.18.0-beta14/missing-tls-secret.yaml b/changelog/v1.18.0-beta14/missing-tls-secret.yaml deleted file mode 100644 index 76ebb9afd00..00000000000 --- a/changelog/v1.18.0-beta14/missing-tls-secret.yaml +++ /dev/null @@ -1,8 +0,0 @@ -changelog: - - type: FIX - issueLink: https://github.com/solo-io/gloo/issues/6957 - resolvesIssue: false - description: >- - Fix for issue where a missing TLS secret was treated by validation as an error, - potentially bringing down the entire HTTPS gateway if the gloo pod restarts while - in this bad state. From 52c04a5f566d73e16fefcbe5ba6e57588cfb033c Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 9 Aug 2024 10:26:52 -0400 Subject: [PATCH 09/39] fix listener_subsystem_test --- .../pkg/translator/listener_subsystem_test.go | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/projects/gloo/pkg/translator/listener_subsystem_test.go b/projects/gloo/pkg/translator/listener_subsystem_test.go index 4472995e856..40d7317ebed 100644 --- a/projects/gloo/pkg/translator/listener_subsystem_test.go +++ b/projects/gloo/pkg/translator/listener_subsystem_test.go @@ -460,8 +460,19 @@ var _ = Describe("Listener Subsystem", func() { listenerReport) params := plugins.Params{ - Ctx: ctx, - Snapshot: &gloov1snap.ApiSnapshot{}, + Ctx: ctx, + Snapshot: &gloov1snap.ApiSnapshot{ + Secrets: []*v1.Secret{{ + Kind: &v1.Secret_Tls{ + // This is an invalid secret that will generate a listener error when referenced. + Tls: &v1.TlsSecret{}, + }, + Metadata: &core.Metadata{ + Name: "exists-but-invalid", + Namespace: defaults.GlooSystem, + }, + }}, + }, } _ = listenerTranslator.ComputeListener(params) _ = routeConfigurationTranslator.ComputeRouteConfiguration(params) @@ -472,6 +483,7 @@ var _ = Describe("Listener Subsystem", func() { Entry( "ListenerError", &v1.AggregateListener{ + HttpResources: &v1.AggregateListener_HttpResources{ HttpOptions: map[string]*v1.HttpListenerOptions{ "http-options-ref": { @@ -489,7 +501,7 @@ var _ = Describe("Listener Subsystem", func() { SslConfig: &ssl.SslConfig{ SslSecrets: &ssl.SslConfig_SecretRef{ SecretRef: &core.ResourceRef{ - Name: "secret-that-is-not-in-snapshot", + Name: "exists-but-invalid", Namespace: defaults.GlooSystem, }, }, @@ -505,6 +517,41 @@ var _ = Describe("Listener Subsystem", func() { Expect(proxyErr.Error()).To(ContainSubstring(validation.ListenerReport_Error_SSLConfigError.String())) }, ), + Entry( + "ListenerWarning", + &v1.AggregateListener{ + HttpResources: &v1.AggregateListener_HttpResources{ + HttpOptions: map[string]*v1.HttpListenerOptions{ + "http-options-ref": { + HttpConnectionManagerSettings: &hcm.HttpConnectionManagerSettings{}, + }, + }, + VirtualHosts: map[string]*v1.VirtualHost{ + "vhost-ref": { + Name: "virtual-host", + }, + }, + }, + HttpFilterChains: []*v1.AggregateListener_HttpFilterChain{{ + Matcher: &v1.Matcher{ + SslConfig: &ssl.SslConfig{ + SslSecrets: &ssl.SslConfig_SecretRef{ + SecretRef: &core.ResourceRef{ + Name: "secret-that-is-not-in-snapshot", + Namespace: defaults.GlooSystem, + }, + }, + }, + }, + HttpOptionsRef: "http-options-ref", + VirtualHostRefs: []string{"vhost-ref"}, + }}, + }, + func(proxyReport *validation.ProxyReport) { + proxyErr := gloovalidation.GetProxyWarning(proxyReport) + Expect(proxyErr).To(ContainElement(ContainSubstring(validation.ListenerReport_Warning_SSLConfigWarning.String()))) + }, + ), Entry( "HttpListenerError", &v1.AggregateListener{ From c3ce3eb2178c7d805ed9f240e3bdcc8a23681f3b Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 9 Aug 2024 11:02:46 -0400 Subject: [PATCH 10/39] tee gha output and grep for success/fail --- .../composite-actions/kubernetes-e2e-tests/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml index 681325eac05..f78d38b6722 100644 --- a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml +++ b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml @@ -32,10 +32,10 @@ runs: TEST_PKG: ./test/kubernetes/e2e/tests ISTIO_VERSION: ${{ inputs.istio-version }} shell: bash - run: make go-test + run: 'mkdir ./_test/test_output; make go-test | tee ./_test/test_output/${{inputs.cluster-name}}; grep -E "(--- FAIL)|(--- PASS)" ./_test/test_output/${{inputs.cluster-name}}' - name: Archive bug report directory on failure if: ${{ failure() }} uses: actions/upload-artifact@v4 with: name: bug-report-${{ inputs.cluster-name }} - path: ./_test/bug_report/${{ inputs.cluster-name }} \ No newline at end of file + path: ./_test/bug_report/${{ inputs.cluster-name }} From 5e5223d445ecd5e95d2908d66527d79214b7ca45 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 9 Aug 2024 11:03:48 -0400 Subject: [PATCH 11/39] fix kubernetes e2e test --- .../validation_reject_invalid/suite.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go b/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go index 446bdb06046..0835bd92036 100644 --- a/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go +++ b/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go @@ -114,12 +114,16 @@ func (s *testingSuite) TestVirtualServiceWithSecretDeletion() { gloo_defaults.GlooReporter, ) - // failing to delete a secret that is in use - output, err := s.testInstallation.Actions.Kubectl().DeleteFileWithOutput(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().Error(err) - s.Assert().Contains(output, fmt.Sprintf(`admission webhook "gloo.%s.svc" denied the request`, s.testInstallation.Metadata.InstallNamespace)) - s.Assert().Contains(output, fmt.Sprintf("failed validating the deletion of resource")) - s.Assert().Contains(output, fmt.Sprintf("SSL secret not found: list did not find secret %s.tls-secret", s.testInstallation.Metadata.InstallNamespace)) + // attempting to delete a secret that is in use produces a warning but succeeds + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.GatewayClient().Read(s.testInstallation.Metadata.InstallNamespace, "gateway-proxy-ssl", clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Warning, + gloo_defaults.GlooReporter, + ) // deleting a secret that is not in use works err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) From eb65fc5e3bd1dfdb39b1c883b012d3d15889e8f3 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 9 Aug 2024 14:33:48 -0400 Subject: [PATCH 12/39] kube2e --- test/kube2e/gateway/gateway_test.go | 14 ++++- test/kube2e/helper/curl.go | 20 ++++++-- test/kube2e/helper/http_echo.go | 4 +- test/kube2e/helper/test_container.go | 76 +++++++++++++++------------- test/kube2e/helper/testserver.go | 2 +- 5 files changed, 71 insertions(+), 45 deletions(-) diff --git a/test/kube2e/gateway/gateway_test.go b/test/kube2e/gateway/gateway_test.go index b4197a6ff3f..9f799105813 100644 --- a/test/kube2e/gateway/gateway_test.go +++ b/test/kube2e/gateway/gateway_test.go @@ -1233,6 +1233,7 @@ var _ = Describe("Kube2e: gateway", func() { var ( httpEcho helper.TestContainer httpEchoClusterName string + curlPod helper.TestContainer clusterIp string tcpPort = corev1.ServicePort{ Name: "tcp-proxy", @@ -1251,6 +1252,12 @@ var _ = Describe("Kube2e: gateway", func() { err = httpEcho.DeployResources(time.Minute) Expect(err).NotTo(HaveOccurred()) + curlPod, err = helper.NewCurl(testHelper.InstallNamespace) + Expect(err).NotTo(HaveOccurred()) + + err = curlPod.DeployResources(time.Minute) + Expect(err).NotTo(HaveOccurred()) + gwSvc, err := resourceClientset.KubeClients().CoreV1().Services(testHelper.InstallNamespace).Get(ctx, gatewayProxy, metav1.GetOptions{}) Expect(err).NotTo(HaveOccurred()) @@ -1291,6 +1298,9 @@ var _ = Describe("Kube2e: gateway", func() { err = httpEcho.TerminatePod() Expect(err).NotTo(HaveOccurred()) + err = curlPod.TerminatePod() + Expect(err).NotTo(HaveOccurred()) + err = resourceClientset.KubeClients().CoreV1().Services(testHelper.InstallNamespace).Delete(ctx, helper.HttpEchoName, metav1.DeleteOptions{}) Expect(err).NotTo(HaveOccurred()) }) @@ -1324,7 +1334,7 @@ var _ = Describe("Kube2e: gateway", func() { It("correctly routes to the service (tcp)", func() { responseString := fmt.Sprintf(`"hostname":"%s"`, gatewayProxy) - httpEcho.CurlEventuallyShouldRespond(helper.CurlOpts{ + curlPod.CurlEventuallyShouldRespond(helper.CurlOpts{ Protocol: "http", Service: gatewayProxy, Port: int(defaults2.TcpPort), @@ -1377,7 +1387,7 @@ var _ = Describe("Kube2e: gateway", func() { It("correctly routes to the service (tcp/tls)", func() { responseString := fmt.Sprintf(`"hostname":"%s"`, httpEchoClusterName) - httpEcho.CurlEventuallyShouldRespond(helper.CurlOpts{ + curlPod.CurlEventuallyShouldRespond(helper.CurlOpts{ Protocol: "https", Sni: httpEchoClusterName, Service: clusterIp, diff --git a/test/kube2e/helper/curl.go b/test/kube2e/helper/curl.go index 58684973821..6dceee3e22e 100644 --- a/test/kube2e/helper/curl.go +++ b/test/kube2e/helper/curl.go @@ -24,6 +24,16 @@ import ( "github.com/solo-io/go-utils/log" ) +const ( + defaultCurlImage = "curlimages/curl:7.83.1" + CurlName = "curl" + CurlPort = 3000 +) + +func NewCurl(namespace string) (TestContainer, error) { + return newTestContainer(namespace, defaultCurlImage, CurlName, CurlPort, false, []string{"tail", "-f", "/dev/null"}) +} + type CurlOpts struct { Protocol string Path string @@ -94,7 +104,7 @@ func (t *testContainer) CurlEventuallyShouldRespond(opts CurlOpts, expectedRespo cli := kubectl.NewCli() EventuallyWithOffset(ginkgoOffset+1, func(g Gomega) { - curlResp, err := cli.CurlFromPod(context.Background(), kubectl.PodExecOptions{Name: t.echoName, Namespace: t.namespace, Container: t.echoName}, t.buildCurlOptions(opts)...) + curlResp, err := cli.CurlFromPod(context.Background(), kubectl.PodExecOptions{Name: t.podName, Namespace: t.namespace, Container: t.podName}, t.buildCurlOptions(opts)...) if err != nil { // trigger an early exit if the pod has been deleted. if strings.Contains(err.Error(), `pods "testserver" not found`) { @@ -208,11 +218,11 @@ func (t *testContainer) buildCurlOptions(opts CurlOpts) []curl.Option { appendOption(curl.WithScheme(opts.Protocol)) } - service := opts.Service - if service == "" { - service = "test-ingress" + host := opts.Service + if host == "" { + host = "test-ingress" } - appendOption(curl.WithHost(service)) + appendOption(curl.WithHost(host)) if opts.SelfSigned { appendOption(curl.IgnoreServerCert()) diff --git a/test/kube2e/helper/http_echo.go b/test/kube2e/helper/http_echo.go index b0d1745c854..aa6dea95918 100644 --- a/test/kube2e/helper/http_echo.go +++ b/test/kube2e/helper/http_echo.go @@ -9,7 +9,7 @@ const ( // Deprecated // ported to test/kubernetes/e2e/defaults/testdata/http_echo.yaml func NewEchoHttp(namespace string) (TestContainer, error) { - return newTestContainer(namespace, defaultHttpEchoImage, HttpEchoName, HttpEchoPort) + return newTestContainer(namespace, defaultHttpEchoImage, HttpEchoName, HttpEchoPort, true, nil) } const ( @@ -21,5 +21,5 @@ const ( // Deprecated // ported to test/kubernetes/e2e/defaults/testdata/tcp_echo.yaml func NewEchoTcp(namespace string) (TestContainer, error) { - return newTestContainer(namespace, defaultTcpEchoImage, TcpEchoName, TcpEchoPort) + return newTestContainer(namespace, defaultTcpEchoImage, TcpEchoName, TcpEchoPort, true, nil) } diff --git a/test/kube2e/helper/test_container.go b/test/kube2e/helper/test_container.go index 15833cc1ef0..f6a03fccaf3 100644 --- a/test/kube2e/helper/test_container.go +++ b/test/kube2e/helper/test_container.go @@ -51,7 +51,7 @@ type TestUpstreamServer interface { DeployServerTls(timeout time.Duration, crt, key []byte) error } -func newTestContainer(namespace, imageTag, echoName string, port int32) (*testContainer, error) { +func newTestContainer(namespace, imageTag, echoName string, port int32, createService bool, command []string) (*testContainer, error) { cfg, err := kubeutils.GetRestConfigWithKubeContext("") if err != nil { return nil, err @@ -65,9 +65,11 @@ func newTestContainer(namespace, imageTag, echoName string, port int32) (*testCo namespace: namespace, kube: kube, - echoName: echoName, - port: port, - imageTag: imageTag, + podName: echoName, + port: port, + imageTag: imageTag, + createService: createService, + command: command, }, nil } @@ -78,22 +80,24 @@ type testContainer struct { namespace string kube kubernetes.Interface - imageTag string - echoName string - port int32 + imageTag string + podName string + port int32 + createService bool + command []string } func (t *testContainer) DeployResources(timeout time.Duration) error { return t.deploy(timeout) } -// Deploys the http echo to the kubernetes cluster the kubeconfig is pointing to and waits for the given time for the -// http-echo pod to be running. +// Deploys the specified pod to the kubernetes cluster the kubeconfig is pointing to and waits for the given time for the +// pod to be running. func (t *testContainer) deploy(timeout time.Duration) error { zero := int64(0) - labels := map[string]string{"gloo": t.echoName} + labels := map[string]string{"gloo": t.podName} metadata := metav1.ObjectMeta{ - Name: t.echoName, + Name: t.podName, Namespace: t.namespace, Labels: labels, } @@ -107,7 +111,8 @@ func (t *testContainer) deploy(timeout time.Duration) error { { Image: t.imageTag, ImagePullPolicy: corev1.PullIfNotPresent, - Name: t.echoName, + Name: t.podName, + Command: t.command, }, }, }, @@ -115,21 +120,22 @@ func (t *testContainer) deploy(timeout time.Duration) error { return err } - // Create http echo service - if _, err := t.kube.CoreV1().Services(t.namespace).Create(context.Background(), &corev1.Service{ - ObjectMeta: metadata, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: t.port, + if t.createService { + if _, err := t.kube.CoreV1().Services(t.namespace).Create(context.Background(), &corev1.Service{ + ObjectMeta: metadata, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "http", + Protocol: corev1.ProtocolTCP, + Port: t.port, + }, }, + Selector: labels, }, - Selector: labels, - }, - }, metav1.CreateOptions{}); err != nil { - return err + }, metav1.CreateOptions{}); err != nil { + return err + } } // added to check the time it takes to deploy the pods. This will allow us to @@ -140,25 +146,25 @@ func (t *testContainer) deploy(timeout time.Duration) error { // Wait until the http echo pod is running ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - if err := testutils.WaitPodsRunning(ctx, time.Second, t.namespace, "gloo="+t.echoName); err != nil { + if err := testutils.WaitPodsRunning(ctx, time.Second, t.namespace, "gloo="+t.podName); err != nil { return err } - log.Printf("deployed %s in %s", t.echoName, time.Now().Sub(tStart)/time.Second) + log.Printf("deployed %s in %s", t.podName, time.Now().Sub(tStart)/time.Second) return nil } func (t *testContainer) TerminatePod() error { - if err := testutils.Kubectl("delete", "pod", "-n", t.namespace, t.echoName, "--grace-period=0"); err != nil { - return errors.Wrapf(err, "deleting %s pod", t.echoName) + if err := testutils.Kubectl("delete", "pod", "-n", t.namespace, t.podName, "--grace-period=0"); err != nil { + return errors.Wrapf(err, "deleting %s pod", t.podName) } return nil } func (t *testContainer) DeleteService() error { - if err := testutils.Kubectl("delete", "service", "-n", t.namespace, t.echoName, "--grace-period=0"); err != nil { - return errors.Wrapf(err, "deleting %s service", t.echoName) + if err := testutils.Kubectl("delete", "service", "-n", t.namespace, t.podName, "--grace-period=0"); err != nil { + return errors.Wrapf(err, "deleting %s service", t.podName) } return nil } @@ -175,14 +181,14 @@ func (t *testContainer) TerminatePodAndDeleteService() error { // testContainer executes a command inside the testContainer container func (t *testContainer) Exec(command ...string) (string, error) { - args := append([]string{"exec", "-i", t.echoName, "-n", t.namespace, "--"}, command...) + args := append([]string{"exec", "-i", t.podName, "-n", t.namespace, "--"}, command...) return testutils.KubectlOut(args...) } // Cp copies files into the testContainer container func (t *testContainer) Cp(files map[string]string) error { for k, v := range files { - if err := testutils.Kubectl("cp", k, fmt.Sprintf("%s/%s:%s", t.namespace, t.echoName, v)); err != nil { + if err := testutils.Kubectl("cp", k, fmt.Sprintf("%s/%s:%s", t.namespace, t.podName, v)); err != nil { return err } } @@ -192,12 +198,12 @@ func (t *testContainer) Cp(files map[string]string) error { // ExecAsync executes a command inside the testContainer container // returning a buffer that can be read from as it executes func (t *testContainer) ExecAsync(args ...string) (io.Reader, chan struct{}, error) { - args = append([]string{"exec", "-i", t.echoName, "-n", t.namespace, "--"}, args...) + args = append([]string{"exec", "-i", t.podName, "-n", t.namespace, "--"}, args...) return testutils.KubectlOutAsync(args...) } func (t *testContainer) ExecChan(r io.Reader, args ...string) (<-chan io.Reader, chan struct{}, error) { - args = append([]string{"exec", "-i", t.echoName, "-n", t.namespace, "--"}, args...) + args = append([]string{"exec", "-i", t.podName, "-n", t.namespace, "--"}, args...) return testutils.KubectlOutChan(r, args...) } diff --git a/test/kube2e/helper/testserver.go b/test/kube2e/helper/testserver.go index d86c4dcaea8..648111a0509 100644 --- a/test/kube2e/helper/testserver.go +++ b/test/kube2e/helper/testserver.go @@ -83,7 +83,7 @@ const ( // tests relying on the test server should be ported using the default nginx deployment located at // test/kubernetes/e2e/defaults/testdata/nginx_pod.yaml func NewTestServer(namespace string) (TestUpstreamServer, error) { - testContainer, err := newTestContainer(namespace, defaultTestServerImage, TestServerName, TestServerPort) + testContainer, err := newTestContainer(namespace, defaultTestServerImage, TestServerName, TestServerPort, true, nil) if err != nil { return nil, err } From 13ff84b0663491aa8f45926e87f9df799701dcf6 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 12 Aug 2024 09:32:57 -0400 Subject: [PATCH 13/39] update action --- .../composite-actions/kubernetes-e2e-tests/action.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml index f78d38b6722..5464333bf96 100644 --- a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml +++ b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml @@ -32,7 +32,8 @@ runs: TEST_PKG: ./test/kubernetes/e2e/tests ISTIO_VERSION: ${{ inputs.istio-version }} shell: bash - run: 'mkdir ./_test/test_output; make go-test | tee ./_test/test_output/${{inputs.cluster-name}}; grep -E "(--- FAIL)|(--- PASS)" ./_test/test_output/${{inputs.cluster-name}}' + # we tee the output into a temp file and then grep through that for an overall summary of the run at the end. + run: 'mkdir ./_test/test_output && make go-test | tee ./_test/test_output/${{inputs.cluster-name}} || grep -E "(--- FAIL)|(--- PASS)" ./_test/test_output/${{inputs.cluster-name}}' - name: Archive bug report directory on failure if: ${{ failure() }} uses: actions/upload-artifact@v4 From d85c578bf215a95ab228db8c4c77fe04a9d19e32 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 12 Aug 2024 10:16:04 -0400 Subject: [PATCH 14/39] unset ns env var when test installation run finishes --- pkg/utils/env/env.go | 12 ----------- pkg/utils/envutils/env.go | 20 +++++++++++++++++++ test/kubernetes/e2e/tests/edge_gw_test.go | 7 +++++-- .../e2e/tests/glooctl_k8s_gw_test.go | 13 ++++++++++-- ..._minimal_default_gatewayparameters_test.go | 13 ++++++++++-- test/kubernetes/e2e/tests/k8s_gw_test.go | 13 ++++++++++-- .../tests/validation_always_accept_test.go | 7 +++++-- .../e2e/tests/validation_strict_test.go | 7 +++++-- 8 files changed, 68 insertions(+), 24 deletions(-) delete mode 100644 pkg/utils/env/env.go diff --git a/pkg/utils/env/env.go b/pkg/utils/env/env.go deleted file mode 100644 index 6707e7c570f..00000000000 --- a/pkg/utils/env/env.go +++ /dev/null @@ -1,12 +0,0 @@ -package env - -import "os" - -// GetOrDefault returns the value of the environment variable for the given key, -// or the default value if the environment variable is not set. -func GetOrDefault(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} diff --git a/pkg/utils/envutils/env.go b/pkg/utils/envutils/env.go index 26111da1631..0e9e3ce1640 100644 --- a/pkg/utils/envutils/env.go +++ b/pkg/utils/envutils/env.go @@ -23,3 +23,23 @@ func IsTruthyValue(value string) bool { envValue, _ := strconv.ParseBool(value) return envValue } + +// GetOrDefault returns the value of the environment variable for the given key, +// or the default value if the environment variable is not set. +func GetOrDefault(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + +// LookupOrDefault returns the value of the environment variable for the given key, +// or the default value if the environment variable is not set. Also returns whether +// the value existed. +func LookupOrDefault(key, fallback string) (string, bool) { + if value, ok := os.LookupEnv(key); ok { + return value, ok + } else { + return fallback, ok + } +} diff --git a/test/kubernetes/e2e/tests/edge_gw_test.go b/test/kubernetes/e2e/tests/edge_gw_test.go index 128bd516364..13fe8021ba5 100644 --- a/test/kubernetes/e2e/tests/edge_gw_test.go +++ b/test/kubernetes/e2e/tests/edge_gw_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -20,7 +20,7 @@ import ( // the k8s Gateway controller is disabled func TestGlooGatewayEdgeGateway(t *testing.T) { ctx := context.Background() - installNs := env.GetOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,6 +38,9 @@ func TestGlooGatewayEdgeGateway(t *testing.T) { // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } diff --git a/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go b/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go index 673d39e0082..773c63f4aef 100644 --- a/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go +++ b/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go @@ -2,11 +2,12 @@ package tests_test import ( "context" + "os" "path/filepath" "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -19,10 +20,11 @@ import ( // the k8s gateway controller enabled func TestGlooctlK8sGateway(t *testing.T) { ctx := context.Background() + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ - InstallNamespace: env.GetOrDefault(testutils.InstallNamespace, "glooctl-k8s-gw-test"), + InstallNamespace: installNs, ValuesManifestFile: filepath.Join(util.MustGetThisDir(), "manifests", "glooctl-k8s-gateway-test-helm.yaml"), ValidationAlwaysAccept: false, K8sGatewayEnabled: true, @@ -30,10 +32,17 @@ func TestGlooctlK8sGateway(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) + // Set the env to the install namespace if it is not already set + if os.Getenv(testutils.InstallNamespace) == "" { + os.Setenv(testutils.InstallNamespace, installNs) + } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } diff --git a/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go b/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go index 2d56e437d64..5dd3dc988c3 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go @@ -2,11 +2,12 @@ package tests_test import ( "context" + "os" "path/filepath" "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -19,10 +20,11 @@ import ( // which is expected to have all user-facing options set to null in helm values func TestK8sGatewayMinimalDefaultGatewayParameters(t *testing.T) { ctx := context.Background() + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gateway-minimal-default-gatewayparameters-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ - InstallNamespace: env.GetOrDefault(testutils.InstallNamespace, "k8s-gateway-minimal-default-gatewayparameters-test"), + InstallNamespace: installNs, ValuesManifestFile: filepath.Join(util.MustGetThisDir(), "manifests", "k8s-gateway-minimal-default-gatewayparameters-test-helm.yaml"), ValidationAlwaysAccept: false, K8sGatewayEnabled: true, @@ -30,10 +32,17 @@ func TestK8sGatewayMinimalDefaultGatewayParameters(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) + // Set the env to the install namespace if it is not already set + if os.Getenv(testutils.InstallNamespace) == "" { + os.Setenv(testutils.InstallNamespace, installNs) + } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } diff --git a/test/kubernetes/e2e/tests/k8s_gw_test.go b/test/kubernetes/e2e/tests/k8s_gw_test.go index 916e2714cb6..933282c11ee 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_test.go @@ -2,11 +2,12 @@ package tests_test import ( "context" + "os" "path/filepath" "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -18,10 +19,11 @@ import ( // TestK8sGateway is the function which executes a series of tests against a given installation func TestK8sGateway(t *testing.T) { ctx := context.Background() + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-always-accept-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ - InstallNamespace: env.GetOrDefault(testutils.InstallNamespace, "k8s-gw-test"), + InstallNamespace: installNs, ValuesManifestFile: filepath.Join(util.MustGetThisDir(), "manifests", "k8s-gateway-test-helm.yaml"), ValidationAlwaysAccept: false, K8sGatewayEnabled: true, @@ -29,10 +31,17 @@ func TestK8sGateway(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) + // Set the env to the install namespace if it is not already set + if os.Getenv(testutils.InstallNamespace) == "" { + os.Setenv(testutils.InstallNamespace, installNs) + } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } diff --git a/test/kubernetes/e2e/tests/validation_always_accept_test.go b/test/kubernetes/e2e/tests/validation_always_accept_test.go index a1f4efee8e6..2acebeb38de 100644 --- a/test/kubernetes/e2e/tests/validation_always_accept_test.go +++ b/test/kubernetes/e2e/tests/validation_always_accept_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -20,7 +20,7 @@ import ( // installation where validation is set to always accept func TestValidationAlwaysAccept(t *testing.T) { ctx := context.Background() - installNs := env.GetOrDefault(testutils.InstallNamespace, "validation-always-accept-test") + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-always-accept-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,6 +38,9 @@ func TestValidationAlwaysAccept(t *testing.T) { // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } diff --git a/test/kubernetes/e2e/tests/validation_strict_test.go b/test/kubernetes/e2e/tests/validation_strict_test.go index c3adad7a3a3..8c6ff9fd521 100644 --- a/test/kubernetes/e2e/tests/validation_strict_test.go +++ b/test/kubernetes/e2e/tests/validation_strict_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -20,7 +20,7 @@ import ( // installation where validation is strict (allow_warnings=false) func TestValidationStrict(t *testing.T) { ctx := context.Background() - installNs := env.GetOrDefault(testutils.InstallNamespace, "validation-strict-test") + installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-strict-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -39,6 +39,9 @@ func TestValidationStrict(t *testing.T) { // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { + if overrodeNs { + os.Unsetenv(testutils.InstallNamespace) + } if t.Failed() { testInstallation.PreFailHandler(ctx) } From 4df4e4f54145b6b09e0c35ac28fc7209b7a0223b Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 12 Aug 2024 14:41:06 -0400 Subject: [PATCH 15/39] fix helm test import --- test/kubernetes/e2e/tests/helm_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/kubernetes/e2e/tests/helm_test.go b/test/kubernetes/e2e/tests/helm_test.go index 14191054b79..a48dde0a226 100644 --- a/test/kubernetes/e2e/tests/helm_test.go +++ b/test/kubernetes/e2e/tests/helm_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/solo-io/gloo/pkg/utils/env" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/test/kubernetes/e2e" . "github.com/solo-io/gloo/test/kubernetes/e2e/tests" "github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway" @@ -19,7 +19,7 @@ import ( // TestHelm is the function which executes a series of helm tests func TestHelm(t *testing.T) { ctx := context.Background() - installNs := env.GetOrDefault(testutils.InstallNamespace, "helm-test") + installNs := envutils.GetOrDefault(testutils.InstallNamespace, "helm-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ From bda0de361bc9218c1d2c5a5847d8d85f70405b34 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 12 Aug 2024 17:30:35 -0400 Subject: [PATCH 16/39] revert gha --- .../composite-actions/kubernetes-e2e-tests/action.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml index 5464333bf96..681325eac05 100644 --- a/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml +++ b/.github/workflows/composite-actions/kubernetes-e2e-tests/action.yaml @@ -32,11 +32,10 @@ runs: TEST_PKG: ./test/kubernetes/e2e/tests ISTIO_VERSION: ${{ inputs.istio-version }} shell: bash - # we tee the output into a temp file and then grep through that for an overall summary of the run at the end. - run: 'mkdir ./_test/test_output && make go-test | tee ./_test/test_output/${{inputs.cluster-name}} || grep -E "(--- FAIL)|(--- PASS)" ./_test/test_output/${{inputs.cluster-name}}' + run: make go-test - name: Archive bug report directory on failure if: ${{ failure() }} uses: actions/upload-artifact@v4 with: name: bug-report-${{ inputs.cluster-name }} - path: ./_test/bug_report/${{ inputs.cluster-name }} + path: ./_test/bug_report/${{ inputs.cluster-name }} \ No newline at end of file From fbd5c27d1c4a8ceab08a5f6f47ec6b2021f2389d Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 14 Aug 2024 20:05:34 +0000 Subject: [PATCH 17/39] Adding changelog file to new location --- changelog/v1.18.0-beta16/missing-tls-secret.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/v1.18.0-beta16/missing-tls-secret.yaml diff --git a/changelog/v1.18.0-beta16/missing-tls-secret.yaml b/changelog/v1.18.0-beta16/missing-tls-secret.yaml new file mode 100644 index 00000000000..76ebb9afd00 --- /dev/null +++ b/changelog/v1.18.0-beta16/missing-tls-secret.yaml @@ -0,0 +1,8 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/gloo/issues/6957 + resolvesIssue: false + description: >- + Fix for issue where a missing TLS secret was treated by validation as an error, + potentially bringing down the entire HTTPS gateway if the gloo pod restarts while + in this bad state. From 0f1b807cb8afd2f5156f8e8b64c7ab8dfd0ce75d Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 14 Aug 2024 20:05:34 +0000 Subject: [PATCH 18/39] Deleting changelog file from old location --- changelog/v1.18.0-beta15/missing-tls-secret.yaml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 changelog/v1.18.0-beta15/missing-tls-secret.yaml diff --git a/changelog/v1.18.0-beta15/missing-tls-secret.yaml b/changelog/v1.18.0-beta15/missing-tls-secret.yaml deleted file mode 100644 index 76ebb9afd00..00000000000 --- a/changelog/v1.18.0-beta15/missing-tls-secret.yaml +++ /dev/null @@ -1,8 +0,0 @@ -changelog: - - type: FIX - issueLink: https://github.com/solo-io/gloo/issues/6957 - resolvesIssue: false - description: >- - Fix for issue where a missing TLS secret was treated by validation as an error, - potentially bringing down the entire HTTPS gateway if the gloo pod restarts while - in this bad state. From 759aa300114a1a48d21b4f317e2d4733858531f4 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 14:45:55 -0400 Subject: [PATCH 19/39] PR feedback --- .../e2e/features/server_tls/suite.go | 19 ++++++++++--------- .../e2e/features/server_tls/types.go | 3 +++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/test/kubernetes/e2e/features/server_tls/suite.go b/test/kubernetes/e2e/features/server_tls/suite.go index 1985add1738..3ab363a7da5 100644 --- a/test/kubernetes/e2e/features/server_tls/suite.go +++ b/test/kubernetes/e2e/features/server_tls/suite.go @@ -98,7 +98,7 @@ func (s *serverTlsTestingSuite) TestServerTls() { s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) } -// TestServerTls validates the happy path that two VirtualServices referencing existent TLS secrets +// TestServerTlsTwoVirtualServices validates the happy path that two VirtualServices referencing existent TLS secrets // terminate TLS and respond appropriately. func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { vs1 := vs1(s.ns) @@ -111,8 +111,9 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { s.NoError(err, "can delete vs2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) - s.NoError(err, "can delete tls secret manifest file") - // tlsSecret2 is deleted in the process of the test. + s.NoError(err, "can delete tls secret 1 manifest file") + err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret2) + s.NoError(err, "can delete tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) }) @@ -132,9 +133,9 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { s.assertEventualResponse(vs2.GetName(), expectedHealthyResponse2) } -// TestServerTls validates that when we have two VirtualServices referencing TLS secrets, but one secret -// is missing, the traffic routing defined by the other VirtualService is not affected. In order to test -// this properly, we require persistProxySpec to be off, validating that both VS are working correctly, +// TestServerTlsTwoVirtualServicesOneMissingTlsSecret validates that when we have two VirtualServices referencing TLS +// secrets, but one secret is missing, the traffic routing defined by the other VirtualService is not affected. In order +// to test this properly, we require persistProxySpec to be off, validating that both VS are working correctly, // then we delete the secret for one of the VS and restart the Gloo pod. This ensures that we are still // serving on the other VS. func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecret() { @@ -175,7 +176,7 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecr // Assert that we have traffic working on VS 1 but failed traffic on VS 2. s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) - s.assertEventualError(vs2.GetName(), 35) + s.assertEventualError(vs2.GetName(), expectedFailedResponseCertRequested) // Restart the Gloo deployment err = s.testInstallation.Actions.Kubectl().RestartDeploymentAndWait(s.ctx, "gloo", "-n", s.ns) @@ -185,7 +186,7 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecr // Assert that we have traffic working on VS 1 but failed traffic on VS 2. s.assertEventuallyConsistentResponse(vs1.GetName(), expectedHealthyResponse1, timeout, polling) - s.assertEventualError(vs2.GetName(), 35) + s.assertEventualError(vs2.GetName(), expectedFailedResponseCertRequested) } @@ -210,7 +211,7 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") - s.assertEventualError(vs.GetName(), 16) + s.assertEventualError(vs.GetName(), expectedFailedResponseCodeInvalidVs) } // TestOneWayServerTlsWorksWithOneWayTls validates that one-way server TLS traffic succeeds when CA data diff --git a/test/kubernetes/e2e/features/server_tls/types.go b/test/kubernetes/e2e/features/server_tls/types.go index 8d437d515da..24ef42e58ef 100644 --- a/test/kubernetes/e2e/features/server_tls/types.go +++ b/test/kubernetes/e2e/features/server_tls/types.go @@ -106,6 +106,9 @@ var ( StatusCode: http.StatusOK, Body: gomega.ContainSubstring("success from vs-with-oneway"), } +) + +const ( // These codes are defined at https://curl.se/libcurl/c/libcurl-errors.html. // These were determined experimentally. expectedFailedResponseCodeInvalidVs = 16 From 266343f0c1d8a56d08ecd51f08e041431e894167 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 20:30:44 -0400 Subject: [PATCH 20/39] update comment --- projects/gloo/pkg/utils/ssl.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/gloo/pkg/utils/ssl.go b/projects/gloo/pkg/utils/ssl.go index d6fc79b4472..a2576b54c06 100644 --- a/projects/gloo/pkg/utils/ssl.go +++ b/projects/gloo/pkg/utils/ssl.go @@ -31,6 +31,8 @@ var ( return eris.Errorf("ocsp staple policy %v not a valid policy", p) } + // SslSecretNotFoundError is an exported error that wraps errors produced in validation + // indicating a missing secret reference. This can be compared against using errors.Is. SslSecretNotFoundError = eris.New("SSL secret not found") sslSecretNotFoundError = func(err error) error { return eris.Wrapf(err, SslSecretNotFoundError.Error()) From 849ec77074c77f474b3fcb7e8bbea981c6f8fae3 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 21:27:04 -0400 Subject: [PATCH 21/39] add settings API for warning --- .../projects/gloo/api/v1/settings.proto.sk.md | 2 + .../gloo/crds/gloo.solo.io_v1_Settings.yaml | 3 + projects/gloo/api/v1/settings.proto | 5 + projects/gloo/pkg/api/v1/settings.pb.clone.go | 6 + projects/gloo/pkg/api/v1/settings.pb.equal.go | 10 ++ projects/gloo/pkg/api/v1/settings.pb.go | 138 ++++++++++-------- projects/gloo/pkg/api/v1/settings.pb.hash.go | 20 +++ 7 files changed, 124 insertions(+), 60 deletions(-) diff --git a/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/v1/settings.proto.sk.md b/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/v1/settings.proto.sk.md index a9f7971ace7..b2978fe1a5f 100644 --- a/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/v1/settings.proto.sk.md +++ b/docs/content/reference/api/github.com/solo-io/gloo/projects/gloo/api/v1/settings.proto.sk.md @@ -878,6 +878,7 @@ options for configuring admission control / validation "disableTransformationValidation": .google.protobuf.BoolValue "validationServerGrpcMaxSizeBytes": .google.protobuf.Int32Value "serverEnabled": .google.protobuf.BoolValue +"warnMissingTlsSecret": .google.protobuf.BoolValue ``` @@ -893,6 +894,7 @@ options for configuring admission control / validation | `disableTransformationValidation` | [.google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/bool-value) | By default gloo will attempt to validate transformations by calling out to a local envoy binary in `validate` mode. Calling this local envoy binary can become slow when done many times during a single validation. Setting this to true will stop gloo from calling out to envoy to validate the transformations, which may speed up the validation time considerably, but may also cause the transformation config to fail after being sent to envoy. When disabling this, ensure that your transformations are valid prior to applying them. | | `validationServerGrpcMaxSizeBytes` | [.google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/int-32-value) | By default, gRPC validation messages between gateway and gloo pods have a max message size of 100 MB. Setting this value sets the gRPC max message size in bytes for the gloo validation server. This should only be changed if necessary. If not included, the gRPC max message size will be the default of 100 MB. | | `serverEnabled` | [.google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/bool-value) | By providing the validation field (parent of this object) the user is implicitly opting into validation. This field allows the user to opt out of the validation server, while still configuring pre-existing fields such as `warn_route_short_circuiting` and `disable_transformation_validation`. If not included, the validation server will be enabled. | +| `warnMissingTlsSecret` | [.google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/bool-value) | Allows configuring validation to report a missing TLS secret referenced by a SslConfig or UpstreamSslConfig as a warning instead of an error. This will allow for eventually consistent workloads, but will also permit the accidental deletion of secrets being referenced, which would cause disruption in traffic. | diff --git a/install/helm/gloo/crds/gloo.solo.io_v1_Settings.yaml b/install/helm/gloo/crds/gloo.solo.io_v1_Settings.yaml index 52b0ff4c9e3..58d9ccd8ed4 100644 --- a/install/helm/gloo/crds/gloo.solo.io_v1_Settings.yaml +++ b/install/helm/gloo/crds/gloo.solo.io_v1_Settings.yaml @@ -546,6 +546,9 @@ spec: type: string validationWebhookTlsKey: type: string + warnMissingTlsSecret: + nullable: true + type: boolean warnRouteShortCircuiting: nullable: true type: boolean diff --git a/projects/gloo/api/v1/settings.proto b/projects/gloo/api/v1/settings.proto index 4bb6fde3f9c..a0bc77e37f4 100644 --- a/projects/gloo/api/v1/settings.proto +++ b/projects/gloo/api/v1/settings.proto @@ -832,6 +832,11 @@ message GatewayOptions { // // If not included, the validation server will be enabled. google.protobuf.BoolValue server_enabled = 12; + + // Allows configuring validation to report a missing TLS secret referenced by a SslConfig or UpstreamSslConfig + // as a warning instead of an error. This will allow for eventually consistent workloads, but will also permit + // the accidental deletion of secrets being referenced, which would cause disruption in traffic. + google.protobuf.BoolValue warn_missing_tls_secret = 13; } // If provided, the Gateway will perform [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) diff --git a/projects/gloo/pkg/api/v1/settings.pb.clone.go b/projects/gloo/pkg/api/v1/settings.pb.clone.go index 602359e9938..b6932b87524 100644 --- a/projects/gloo/pkg/api/v1/settings.pb.clone.go +++ b/projects/gloo/pkg/api/v1/settings.pb.clone.go @@ -1286,6 +1286,12 @@ func (m *GatewayOptions_ValidationOptions) Clone() proto.Message { target.ServerEnabled = proto.Clone(m.GetServerEnabled()).(*github_com_golang_protobuf_ptypes_wrappers.BoolValue) } + if h, ok := interface{}(m.GetWarnMissingTlsSecret()).(clone.Cloner); ok { + target.WarnMissingTlsSecret = h.Clone().(*github_com_golang_protobuf_ptypes_wrappers.BoolValue) + } else { + target.WarnMissingTlsSecret = proto.Clone(m.GetWarnMissingTlsSecret()).(*github_com_golang_protobuf_ptypes_wrappers.BoolValue) + } + return target } diff --git a/projects/gloo/pkg/api/v1/settings.pb.equal.go b/projects/gloo/pkg/api/v1/settings.pb.equal.go index cc002f7d622..2dd0ae850ec 100644 --- a/projects/gloo/pkg/api/v1/settings.pb.equal.go +++ b/projects/gloo/pkg/api/v1/settings.pb.equal.go @@ -2231,6 +2231,16 @@ func (m *GatewayOptions_ValidationOptions) Equal(that interface{}) bool { } } + if h, ok := interface{}(m.GetWarnMissingTlsSecret()).(equality.Equalizer); ok { + if !h.Equal(target.GetWarnMissingTlsSecret()) { + return false + } + } else { + if !proto.Equal(m.GetWarnMissingTlsSecret(), target.GetWarnMissingTlsSecret()) { + return false + } + } + return true } diff --git a/projects/gloo/pkg/api/v1/settings.pb.go b/projects/gloo/pkg/api/v1/settings.pb.go index f11d2430cd3..b1564ac1fc4 100644 --- a/projects/gloo/pkg/api/v1/settings.pb.go +++ b/projects/gloo/pkg/api/v1/settings.pb.go @@ -3307,6 +3307,10 @@ type GatewayOptions_ValidationOptions struct { // // If not included, the validation server will be enabled. ServerEnabled *wrappers.BoolValue `protobuf:"bytes,12,opt,name=server_enabled,json=serverEnabled,proto3" json:"server_enabled,omitempty"` + // Allows configuring validation to report a missing TLS secret referenced by a SslConfig or UpstreamSslConfig + // as a warning instead of an error. This will allow for eventually consistent workloads, but will also permit + // the accidental deletion of secrets being referenced, which would cause disruption in traffic. + WarnMissingTlsSecret *wrappers.BoolValue `protobuf:"bytes,13,opt,name=warn_missing_tls_secret,json=warnMissingTlsSecret,proto3" json:"warn_missing_tls_secret,omitempty"` } func (x *GatewayOptions_ValidationOptions) Reset() { @@ -3413,6 +3417,13 @@ func (x *GatewayOptions_ValidationOptions) GetServerEnabled() *wrappers.BoolValu return nil } +func (x *GatewayOptions_ValidationOptions) GetWarnMissingTlsSecret() *wrappers.BoolValue { + if x != nil { + return x.WarnMissingTlsSecret + } + return nil +} + type GraphqlOptions_SchemaChangeValidationOptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4185,7 +4196,7 @@ var file_github_com_solo_io_gloo_projects_gloo_api_v1_settings_proto_rawDesc = [ 0x77, 0x61, 0x79, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x6e, 0x65, 0x57, 0x61, - 0x79, 0x54, 0x6c, 0x73, 0x22, 0xb8, 0x0c, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x79, 0x54, 0x6c, 0x73, 0x22, 0x8b, 0x0d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, @@ -4235,7 +4246,7 @@ var file_github_com_solo_io_gloo_projects_gloo_api_v1_settings_proto_rawDesc = [ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x16, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x73, 0x1a, 0x9b, 0x06, 0x0a, 0x11, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x1a, 0xee, 0x06, 0x0a, 0x11, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x70, @@ -4284,57 +4295,63 @@ var file_github_com_solo_io_gloo_projects_gloo_api_v1_settings_proto_rawDesc = [ 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x22, - 0x97, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x4c, 0x0a, 0x14, 0x61, - 0x70, 0x69, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x5f, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x61, 0x70, 0x69, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, - 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xba, 0x04, 0x0a, 0x0e, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x71, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x83, 0x01, 0x0a, - 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, - 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x1d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x1a, 0xa1, 0x03, 0x0a, 0x1d, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x17, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x62, - 0x72, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x15, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x69, 0x6e, - 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x74, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0e, 0x32, 0x49, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, - 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0f, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xb5, - 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x55, 0x4c, 0x45, 0x5f, - 0x44, 0x41, 0x4e, 0x47, 0x45, 0x52, 0x4f, 0x55, 0x53, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x52, 0x45, - 0x41, 0x4b, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x55, 0x4c, 0x45, 0x5f, - 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, - 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x44, 0x41, 0x4e, 0x47, 0x45, 0x52, 0x4f, - 0x55, 0x53, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x49, 0x47, 0x4e, - 0x4f, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x53, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4c, - 0x45, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x41, 0x43, 0x48, - 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x42, 0x3e, 0xb8, 0xf5, 0x04, 0x01, 0xc0, 0xf5, 0x04, 0x01, - 0xd0, 0xf5, 0x04, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x73, 0x6f, 0x6c, 0x6f, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x17, 0x77, 0x61, 0x72, + 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x77, 0x61, 0x72, 0x6e, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x54, 0x6c, 0x73, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4a, 0x04, 0x08, 0x0a, + 0x10, 0x0b, 0x22, 0x97, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, + 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x4c, + 0x0a, 0x14, 0x61, 0x70, 0x69, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x61, 0x70, 0x69, 0x45, 0x78, 0x70, + 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xba, 0x04, 0x0a, + 0x0e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x83, 0x01, 0x0a, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x6c, 0x6f, + 0x6f, 0x2e, 0x73, 0x6f, 0x6c, 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, + 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x1d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xa1, 0x03, 0x0a, 0x1d, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x17, 0x72, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x74, 0x0a, 0x10, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x49, 0x2e, 0x67, 0x6c, 0x6f, 0x6f, 0x2e, 0x73, 0x6f, 0x6c, + 0x6f, 0x2e, 0x69, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x55, + 0x4c, 0x45, 0x5f, 0x44, 0x41, 0x4e, 0x47, 0x45, 0x52, 0x4f, 0x55, 0x53, 0x5f, 0x54, 0x4f, 0x5f, + 0x42, 0x52, 0x45, 0x41, 0x4b, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x55, + 0x4c, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, + 0x45, 0x4c, 0x44, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x44, 0x41, 0x4e, 0x47, + 0x45, 0x52, 0x4f, 0x55, 0x53, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x55, 0x4c, 0x45, 0x5f, + 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x53, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, + 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x52, 0x45, + 0x41, 0x43, 0x48, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x42, 0x3e, 0xb8, 0xf5, 0x04, 0x01, 0xc0, + 0xf5, 0x04, 0x01, 0xd0, 0xf5, 0x04, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x6c, 0x6f, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x67, 0x6c, 0x6f, 0x6f, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -4513,13 +4530,14 @@ var file_github_com_solo_io_gloo_projects_gloo_api_v1_settings_proto_depIdxs = [ 53, // 96: gloo.solo.io.GatewayOptions.ValidationOptions.disable_transformation_validation:type_name -> google.protobuf.BoolValue 59, // 97: gloo.solo.io.GatewayOptions.ValidationOptions.validation_server_grpc_max_size_bytes:type_name -> google.protobuf.Int32Value 53, // 98: gloo.solo.io.GatewayOptions.ValidationOptions.server_enabled:type_name -> google.protobuf.BoolValue - 53, // 99: gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.reject_breaking_changes:type_name -> google.protobuf.BoolValue - 1, // 100: gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.processing_rules:type_name -> gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.ProcessingRule - 101, // [101:101] is the sub-list for method output_type - 101, // [101:101] is the sub-list for method input_type - 101, // [101:101] is the sub-list for extension type_name - 101, // [101:101] is the sub-list for extension extendee - 0, // [0:101] is the sub-list for field type_name + 53, // 99: gloo.solo.io.GatewayOptions.ValidationOptions.warn_missing_tls_secret:type_name -> google.protobuf.BoolValue + 53, // 100: gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.reject_breaking_changes:type_name -> google.protobuf.BoolValue + 1, // 101: gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.processing_rules:type_name -> gloo.solo.io.GraphqlOptions.SchemaChangeValidationOptions.ProcessingRule + 102, // [102:102] is the sub-list for method output_type + 102, // [102:102] is the sub-list for method input_type + 102, // [102:102] is the sub-list for extension type_name + 102, // [102:102] is the sub-list for extension extendee + 0, // [0:102] is the sub-list for field type_name } func init() { file_github_com_solo_io_gloo_projects_gloo_api_v1_settings_proto_init() } diff --git a/projects/gloo/pkg/api/v1/settings.pb.hash.go b/projects/gloo/pkg/api/v1/settings.pb.hash.go index 2895866e8bb..070994f9a66 100644 --- a/projects/gloo/pkg/api/v1/settings.pb.hash.go +++ b/projects/gloo/pkg/api/v1/settings.pb.hash.go @@ -2854,6 +2854,26 @@ func (m *GatewayOptions_ValidationOptions) Hash(hasher hash.Hash64) (uint64, err } } + if h, ok := interface{}(m.GetWarnMissingTlsSecret()).(safe_hasher.SafeHasher); ok { + if _, err = hasher.Write([]byte("WarnMissingTlsSecret")); err != nil { + return 0, err + } + if _, err = h.Hash(hasher); err != nil { + return 0, err + } + } else { + if fieldValue, err := hashstructure.Hash(m.GetWarnMissingTlsSecret(), nil); err != nil { + return 0, err + } else { + if _, err = hasher.Write([]byte("WarnMissingTlsSecret")); err != nil { + return 0, err + } + if err := binary.Write(hasher, binary.LittleEndian, fieldValue); err != nil { + return 0, err + } + } + } + return hasher.Sum64(), nil } From 9745908e249af6cb07c3af92e97c16f9cca46b66 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 22:00:36 -0400 Subject: [PATCH 22/39] settings option for warning instead of error --- projects/gloo/pkg/translator/clusters.go | 5 ++++- projects/gloo/pkg/translator/filter_chain.go | 6 +++++- projects/gloo/pkg/translator/listener_subsystem.go | 6 ++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index 451cbfd85a6..ac303515811 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -122,7 +122,10 @@ func (t *translatorInstance) initializeCluster( applyDefaultsToUpstreamSslConfig(sslConfig, t.settings.GetUpstreamOptions()) cfg, err := utils.NewSslConfigTranslator().ResolveUpstreamSslConfig(*secrets, sslConfig) if err != nil { - if errors.Is(err, utils.SslSecretNotFoundError) { + // if we are configured to warn on missing tls secret and we match that error, add a + // warning instead of error to the report. + if t.settings.GetGateway().GetValidation().GetWarnMissingTlsSecret().GetValue() && + errors.Is(err, utils.SslSecretNotFoundError) { reports.AddWarning(upstream, err.Error()) } else { reports.AddError(upstream, err) diff --git a/projects/gloo/pkg/translator/filter_chain.go b/projects/gloo/pkg/translator/filter_chain.go index 0043ed28085..b134bd46cdf 100644 --- a/projects/gloo/pkg/translator/filter_chain.go +++ b/projects/gloo/pkg/translator/filter_chain.go @@ -206,6 +206,7 @@ func (t *tcpFilterChainTranslator) computeNetworkFilters(params plugins.Params) // An httpFilterChainTranslator configures a single set of NetworkFilters // and then creates duplicate filter chains for each provided SslConfig. type httpFilterChainTranslator struct { + settings *v1.Settings parentReport *validationapi.ListenerReport networkFilterTranslator NetworkFilterTranslator sslConfigurations []*ssl.SslConfig @@ -294,7 +295,10 @@ func (h *httpFilterChainTranslator) createFilterChainsFromSslConfiguration( // get secrets downstreamTlsContext, err := h.sslConfigTranslator.ResolveDownstreamSslConfig(snap.Secrets, sslConfig) if err != nil { - if errors.Is(err, utils.SslSecretNotFoundError) { + // if we are configured to warn on missing tls secret and we match that error, add a + // warning instead of error to the report. + if h.settings.GetGateway().GetValidation().GetWarnMissingTlsSecret().GetValue() && + errors.Is(err, utils.SslSecretNotFoundError) { // We add this as a warning to support eventual consistency with TLS Secret resources. In this way, // the Proxy producing this will not be considered Rejected, and the HTTPS Listener will still operate // as expected with a VirtualService in error. diff --git a/projects/gloo/pkg/translator/listener_subsystem.go b/projects/gloo/pkg/translator/listener_subsystem.go index b30ee163aff..a2ca2d10c8e 100644 --- a/projects/gloo/pkg/translator/listener_subsystem.go +++ b/projects/gloo/pkg/translator/listener_subsystem.go @@ -23,15 +23,18 @@ import ( type ListenerSubsystemTranslatorFactory struct { pluginRegistry plugins.PluginRegistry sslConfigTranslator utils.SslConfigTranslator + settings *v1.Settings } func NewListenerSubsystemTranslatorFactory( pluginRegistry plugins.PluginRegistry, sslConfigTranslator utils.SslConfigTranslator, + settings *v1.Settings, ) *ListenerSubsystemTranslatorFactory { return &ListenerSubsystemTranslatorFactory{ pluginRegistry: pluginRegistry, sslConfigTranslator: sslConfigTranslator, + settings: settings, } } @@ -94,6 +97,7 @@ func (l *ListenerSubsystemTranslatorFactory) GetHttpListenerTranslators(ctx cont sslConfigurations: listener.GetSslConfigurations(), defaultSslConfig: nil, // not available for HttpGateway, HybridGateway only feature sourcePrefixRanges: nil, // not available for HttpGateway, HybridGateway only feature + settings: l.settings, } // This translator produces a single Listener @@ -218,6 +222,7 @@ func (l *ListenerSubsystemTranslatorFactory) GetHybridListenerTranslators(ctx co prefixRanges: matcher.GetPrefixRanges(), // HybridGateway only feature sourcePrefixRanges: matcher.GetSourcePrefixRanges(), // HybridGateway only feature destinationPort: matcher.GetDestinationPort().GetValue(), // HybridGateway only feature + settings: l.settings, } // This translator produces a single RouteConfiguration @@ -351,6 +356,7 @@ func (l *ListenerSubsystemTranslatorFactory) GetAggregateListenerTranslators(ctx prefixRanges: httpFilterChain.GetMatcher().GetPrefixRanges(), sourcePrefixRanges: httpFilterChain.GetMatcher().GetSourcePrefixRanges(), destinationPort: httpFilterChain.GetMatcher().GetDestinationPort().GetValue(), + settings: l.settings, } // This translator produces a single RouteConfiguration From 4a007839a22b9aaed54e40ff99aa4e8445faf59c Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 22:05:11 -0400 Subject: [PATCH 23/39] update changelog --- changelog/v1.18.0-beta16/missing-tls-secret.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelog/v1.18.0-beta16/missing-tls-secret.yaml b/changelog/v1.18.0-beta16/missing-tls-secret.yaml index 76ebb9afd00..0a41e276821 100644 --- a/changelog/v1.18.0-beta16/missing-tls-secret.yaml +++ b/changelog/v1.18.0-beta16/missing-tls-secret.yaml @@ -6,3 +6,15 @@ changelog: Fix for issue where a missing TLS secret was treated by validation as an error, potentially bringing down the entire HTTPS gateway if the gloo pod restarts while in this bad state. + + To disable this behavior, use the helm setting `gateway.validation.warnMissingTlsSecret=false` + or the same field on the Settings CR. This field has no effect if allowWarnings is false or + acceptAllResources is true. + - type: HELM + issueLink: https://github.com/solo-io/gloo/issues/6957 + resolvesIssue: false + description: >- + New field gateway.validation.warnMissingTlsSecret controls whether missing TLS secrets referenced + in SslConfig and UpstreamSslConfig will be treated as a warning instead of an error during validation. + Defaults to true. This field has no effect if allowWarnings is false or acceptAllResources is true. + From 23eaa92ef96114a631f22b044cfa0ad117172644 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Thu, 15 Aug 2024 22:33:00 -0400 Subject: [PATCH 24/39] helm and tests --- install/helm/gloo/generate/values.go | 1 + install/helm/gloo/templates/18-settings.yaml | 2 +- install/helm/gloo/values-template.yaml | 3 +- .../fixtures/settings/gateway_validation.yaml | 3 +- install/test/helm_test.go | 1 + .../validation_allow_warnings/suite.go | 94 +++++++++++++++++++ .../validation_reject_invalid/suite.go | 16 ++-- .../validation_strict_warnings/suite.go | 89 ++++++++++++++++++ 8 files changed, 196 insertions(+), 13 deletions(-) diff --git a/install/helm/gloo/generate/values.go b/install/helm/gloo/generate/values.go index 5b3c1c2052e..297a5109154 100644 --- a/install/helm/gloo/generate/values.go +++ b/install/helm/gloo/generate/values.go @@ -460,6 +460,7 @@ type GatewayValidation struct { Enabled *bool `json:"enabled,omitempty" desc:"enable Gloo Edge API Gateway validation hook (default true)"` AlwaysAcceptResources *bool `json:"alwaysAcceptResources,omitempty" desc:"unless this is set this to false in order to ensure validation webhook rejects invalid resources. by default, validation webhook will only log and report metrics for invalid resource admission without rejecting them outright."` AllowWarnings *bool `json:"allowWarnings,omitempty" desc:"set this to false in order to ensure validation webhook rejects resources that would have warning status or rejected status, rather than just rejected."` + WarnMissingTlsSecret *bool `json:"warnMissingTlsSecret,omitempty" desc:"set this to false in order to treat missing tls secret references as errors, causing validation to fail."` ServerEnabled *bool `json:"serverEnabled,omitempty" desc:"By providing the validation field (parent of this object) the user is implicitly opting into validation. This field allows the user to opt out of the validation server, while still configuring pre-existing fields such as warn_route_short_circuiting and disable_transformation_validation."` DisableTransformationValidation *bool `json:"disableTransformationValidation,omitempty" desc:"set this to true to disable transformation validation. This may bring signifigant performance benefits if using many transformations, at the cost of possibly incorrect transformations being sent to Envoy. When using this value make sure to pre-validate transformations."` WarnRouteShortCircuiting *bool `json:"warnRouteShortCircuiting,omitempty" desc:"Write a warning to route resources if validation produced a route ordering warning (defaults to false). By setting to true, this means that Gloo Edge will start assigning warnings to resources that would result in route short-circuiting within a virtual host."` diff --git a/install/helm/gloo/templates/18-settings.yaml b/install/helm/gloo/templates/18-settings.yaml index 5b3916810f7..6b2c1d5f27a 100644 --- a/install/helm/gloo/templates/18-settings.yaml +++ b/install/helm/gloo/templates/18-settings.yaml @@ -130,9 +130,9 @@ spec: {{- if .Values.gateway.validation.enabled }} validation: proxyValidationServerAddr: "gloo:{{ .Values.gloo.deployment.validationPort }}" -{{- /* need to do this weird if/else because Helm cannot differentiate between 'false' and 'unset' */}} alwaysAccept: {{ .Values.gateway.validation.alwaysAcceptResources }} allowWarnings: {{ .Values.gateway.validation.allowWarnings }} + warnMissingTlsSecret: {{ .Values.gateway.validation.warnMissingTlsSecret }} serverEnabled: {{ .Values.gateway.validation.serverEnabled }} disableTransformationValidation: {{ .Values.gateway.validation.disableTransformationValidation }} warnRouteShortCircuiting: {{ .Values.gateway.validation.warnRouteShortCircuiting }} diff --git a/install/helm/gloo/values-template.yaml b/install/helm/gloo/values-template.yaml index 378398610e5..54dab4262ec 100644 --- a/install/helm/gloo/values-template.yaml +++ b/install/helm/gloo/values-template.yaml @@ -132,6 +132,7 @@ gateway: secretName: gateway-validation-certs alwaysAcceptResources: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -318,4 +319,4 @@ global: # additionalLabels adds a label to all object metadata additionalLabels: {} # securitySettings defines global security settings such as `floatingUserId` - securitySettings: {} \ No newline at end of file + securitySettings: {} diff --git a/install/test/fixtures/settings/gateway_validation.yaml b/install/test/fixtures/settings/gateway_validation.yaml index 9affdecd82e..0aa2ade2c59 100644 --- a/install/test/fixtures/settings/gateway_validation.yaml +++ b/install/test/fixtures/settings/gateway_validation.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: false serverEnabled: true disableTransformationValidation: true warnRouteShortCircuiting: true @@ -41,4 +42,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/helm_test.go b/install/test/helm_test.go index de2d69a6da6..8f81cfbc7a6 100644 --- a/install/test/helm_test.go +++ b/install/test/helm_test.go @@ -4170,6 +4170,7 @@ spec: ValuesArgs: []string{ "gateway.validation.disableTransformationValidation=true", "gateway.validation.warnRouteShortCircuiting=true", + "gateway.validation.warnMissingTlsSecret=true", }, }) testManifest.ExpectUnstructured(settings.GetKind(), settings.GetNamespace(), settings.GetName()).To(BeEquivalentTo(settings)) diff --git a/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go b/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go index 65faed99b4e..d508e072e8b 100644 --- a/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go +++ b/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go @@ -2,6 +2,8 @@ package validation_allow_warnings import ( "context" + "os" + "time" gloo_defaults "github.com/solo-io/gloo/projects/gloo/pkg/defaults" "github.com/solo-io/gloo/test/kubernetes/e2e" @@ -34,6 +36,98 @@ func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite. } } +/* +TestVirtualServiceWithSecretDeletion tests behaviors when Gloo rejects a VirtualService with a secret that is deleted + +To create the private key and certificate to use: + + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout tls.key -out tls.crt -subj "/CN=*" + +To create the Kubernetes secrets to hold this cert: + + kubectl create secret tls upstream-tls --key tls.key \ + --cert tls.crt --namespace gloo-system +*/ +func (s *testingSuite) TestVirtualServiceWithSecretDeletion() { + // VS with secret should be accepted, need to substitute the secret ns + secretVS, err := os.ReadFile(validation.SecretVSTemplate) + s.Assert().NoError(err) + // Replace environment variables placeholders with their values + substitutedSecretVS := os.ExpandEnv(string(secretVS)) + + s.T().Cleanup(func() { + // Can delete resources in correct order + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, []byte(substitutedSecretVS), "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err, "can delete virtual service with secret") + + // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update + s.Assert().Eventually(func() bool { + err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) + return err == nil + }, time.Minute, 5*time.Second, "can delete "+validation.ExampleUpstream) + + // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update + s.Assert().Eventually(func() bool { + err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + return err == nil + }, time.Minute, 5*time.Second, "can delete "+validation.Secret) + + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, testdefaults.NginxPodManifest) + s.Assert().NoError(err, "can delete "+testdefaults.NginxPodManifest) + }) + + // apply example app + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.NginxPodManifest) + s.Assert().NoError(err) + // Check that test resources are running + s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, testdefaults.NginxPod.ObjectMeta.GetNamespace(), metav1.ListOptions{ + LabelSelector: "app.kubernetes.io/name=nginx", + }) + + // Secrets should be accepted + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + + // Upstream should be accepted + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.UpstreamClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleUpstreamName, clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Accepted, + gloo_defaults.GlooReporter, + ) + // Apply VS with secret after Upstream and Secret exist + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, []byte(substitutedSecretVS)) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.VirtualServiceClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleVsName, clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Accepted, + gloo_defaults.GlooReporter, + ) + + // attempting to delete a secret that is in use produces a warning but succeeds + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.GatewayClient().Read(s.testInstallation.Metadata.InstallNamespace, "gateway-proxy-ssl", clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Warning, + gloo_defaults.GlooReporter, + ) + + // deleting a secret that is not in use works + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) +} + // TestMissingUpstream tests behaviors when Gloo allows invalid VirtualServices to be persisted func (s *testingSuite) TestMissingUpstream() { s.T().Cleanup(func() { diff --git a/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go b/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go index 0835bd92036..446bdb06046 100644 --- a/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go +++ b/test/kubernetes/e2e/features/validation/validation_reject_invalid/suite.go @@ -114,16 +114,12 @@ func (s *testingSuite) TestVirtualServiceWithSecretDeletion() { gloo_defaults.GlooReporter, ) - // attempting to delete a secret that is in use produces a warning but succeeds - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) - s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( - func() (resources.InputResource, error) { - return s.testInstallation.ResourceClients.GatewayClient().Read(s.testInstallation.Metadata.InstallNamespace, "gateway-proxy-ssl", clients.ReadOpts{Ctx: s.ctx}) - }, - core.Status_Warning, - gloo_defaults.GlooReporter, - ) + // failing to delete a secret that is in use + output, err := s.testInstallation.Actions.Kubectl().DeleteFileWithOutput(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().Error(err) + s.Assert().Contains(output, fmt.Sprintf(`admission webhook "gloo.%s.svc" denied the request`, s.testInstallation.Metadata.InstallNamespace)) + s.Assert().Contains(output, fmt.Sprintf("failed validating the deletion of resource")) + s.Assert().Contains(output, fmt.Sprintf("SSL secret not found: list did not find secret %s.tls-secret", s.testInstallation.Metadata.InstallNamespace)) // deleting a secret that is not in use works err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) diff --git a/test/kubernetes/e2e/features/validation/validation_strict_warnings/suite.go b/test/kubernetes/e2e/features/validation/validation_strict_warnings/suite.go index 796cecb0f99..7f612181ddc 100644 --- a/test/kubernetes/e2e/features/validation/validation_strict_warnings/suite.go +++ b/test/kubernetes/e2e/features/validation/validation_strict_warnings/suite.go @@ -3,6 +3,7 @@ package validation_strict_warnings import ( "context" "fmt" + "os" "time" gloo_defaults "github.com/solo-io/gloo/projects/gloo/pkg/defaults" @@ -36,6 +37,94 @@ func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite. } } +/* +TestVirtualServiceWithSecretDeletion tests behaviors when Gloo rejects a VirtualService with a secret that is deleted + +To create the private key and certificate to use: + + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout tls.key -out tls.crt -subj "/CN=*" + +To create the Kubernetes secrets to hold this cert: + + kubectl create secret tls upstream-tls --key tls.key \ + --cert tls.crt --namespace gloo-system +*/ +func (s *testingSuite) TestVirtualServiceWithSecretDeletion() { + // VS with secret should be accepted, need to substitute the secret ns + secretVS, err := os.ReadFile(validation.SecretVSTemplate) + s.Assert().NoError(err) + // Replace environment variables placeholders with their values + substitutedSecretVS := os.ExpandEnv(string(secretVS)) + + s.T().Cleanup(func() { + // Can delete resources in correct order + err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, []byte(substitutedSecretVS), "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err, "can delete virtual service with secret") + + // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update + s.Assert().Eventually(func() bool { + err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) + return err == nil + }, time.Minute, 5*time.Second, "can delete "+validation.ExampleUpstream) + + // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update + s.Assert().Eventually(func() bool { + err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + return err == nil + }, time.Minute, 5*time.Second, "can delete "+validation.Secret) + + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, testdefaults.NginxPodManifest) + s.Assert().NoError(err, "can delete "+testdefaults.NginxPodManifest) + }) + + // apply example app + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.NginxPodManifest) + s.Assert().NoError(err) + // Check that test resources are running + s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, testdefaults.NginxPod.ObjectMeta.GetNamespace(), metav1.ListOptions{ + LabelSelector: "app.kubernetes.io/name=nginx", + }) + + // Secrets should be accepted + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + + // Upstream should be accepted + err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.UpstreamClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleUpstreamName, clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Accepted, + gloo_defaults.GlooReporter, + ) + // Apply VS with secret after Upstream and Secret exist + err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, []byte(substitutedSecretVS)) + s.Assert().NoError(err) + s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( + func() (resources.InputResource, error) { + return s.testInstallation.ResourceClients.VirtualServiceClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleVsName, clients.ReadOpts{Ctx: s.ctx}) + }, + core.Status_Accepted, + gloo_defaults.GlooReporter, + ) + + // failing to delete a secret that is in use + output, err := s.testInstallation.Actions.Kubectl().DeleteFileWithOutput(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().Error(err) + s.Assert().Contains(output, fmt.Sprintf(`admission webhook "gloo.%s.svc" denied the request`, s.testInstallation.Metadata.InstallNamespace)) + s.Assert().Contains(output, fmt.Sprintf("failed validating the deletion of resource")) + s.Assert().Contains(output, fmt.Sprintf("SSL secret not found: list did not find secret %s.tls-secret", s.testInstallation.Metadata.InstallNamespace)) + + // deleting a secret that is not in use works + err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) + s.Assert().NoError(err) +} + // TestInvalidUpstreamMissingPort tests behaviors when Gloo rejects an invalid upstream with a missing port func (s *testingSuite) TestInvalidUpstreamMissingPort() { s.T().Cleanup(func() { From e0c7b84d439c1578ac73623a89b152c4c3dfc6d4 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 07:24:36 -0400 Subject: [PATCH 25/39] fix build issues and codegen --- docs/content/reference/values.txt | 1 + projects/gloo/pkg/translator/listener_subsystem_test.go | 2 +- projects/gloo/pkg/translator/network_filters_test.go | 2 +- projects/gloo/pkg/translator/translator.go | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/content/reference/values.txt b/docs/content/reference/values.txt index 80e8b4a96f7..a55ec9b327f 100644 --- a/docs/content/reference/values.txt +++ b/docs/content/reference/values.txt @@ -541,6 +541,7 @@ |gateway.validation.enabled|bool|true|enable Gloo Edge API Gateway validation hook (default true)| |gateway.validation.alwaysAcceptResources|bool|true|unless this is set this to false in order to ensure validation webhook rejects invalid resources. by default, validation webhook will only log and report metrics for invalid resource admission without rejecting them outright.| |gateway.validation.allowWarnings|bool|true|set this to false in order to ensure validation webhook rejects resources that would have warning status or rejected status, rather than just rejected.| +|gateway.validation.warnMissingTlsSecret|bool|true|set this to false in order to treat missing tls secret references as errors, causing validation to fail.| |gateway.validation.serverEnabled|bool|true|By providing the validation field (parent of this object) the user is implicitly opting into validation. This field allows the user to opt out of the validation server, while still configuring pre-existing fields such as warn_route_short_circuiting and disable_transformation_validation.| |gateway.validation.disableTransformationValidation|bool|false|set this to true to disable transformation validation. This may bring signifigant performance benefits if using many transformations, at the cost of possibly incorrect transformations being sent to Envoy. When using this value make sure to pre-validate transformations.| |gateway.validation.warnRouteShortCircuiting|bool|false|Write a warning to route resources if validation produced a route ordering warning (defaults to false). By setting to true, this means that Gloo Edge will start assigning warnings to resources that would result in route short-circuiting within a virtual host.| diff --git a/projects/gloo/pkg/translator/listener_subsystem_test.go b/projects/gloo/pkg/translator/listener_subsystem_test.go index 40d7317ebed..b16019b5dcb 100644 --- a/projects/gloo/pkg/translator/listener_subsystem_test.go +++ b/projects/gloo/pkg/translator/listener_subsystem_test.go @@ -85,7 +85,7 @@ var _ = Describe("Listener Subsystem", func() { }) } - translatorFactory = translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator()) + translatorFactory = translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), &v1.Settings{}) }) AfterEach(func() { diff --git a/projects/gloo/pkg/translator/network_filters_test.go b/projects/gloo/pkg/translator/network_filters_test.go index 7fc3da7a40d..a1d30514938 100644 --- a/projects/gloo/pkg/translator/network_filters_test.go +++ b/projects/gloo/pkg/translator/network_filters_test.go @@ -53,7 +53,7 @@ var _ = Describe("Router filter test", func() { }) } - translatorFactory := translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator()) + translatorFactory := translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), &v1.Settings) listener := &v1.Listener{ Name: "aggregate-listener", BindAddress: gatewaydefaults.GatewayBindAddress, diff --git a/projects/gloo/pkg/translator/translator.go b/projects/gloo/pkg/translator/translator.go index 1e7283f32a8..f952a9d0710 100644 --- a/projects/gloo/pkg/translator/translator.go +++ b/projects/gloo/pkg/translator/translator.go @@ -71,7 +71,7 @@ func NewTranslatorWithHasher( pluginRegistry: pluginRegistry, settings: settings, hasher: hasher, - listenerTranslatorFactory: NewListenerSubsystemTranslatorFactory(pluginRegistry, sslConfigTranslator), + listenerTranslatorFactory: NewListenerSubsystemTranslatorFactory(pluginRegistry, sslConfigTranslator, settings), } } From 1ee3b05800bf2d21c81ed12edc0b9f18242b5541 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 07:46:39 -0400 Subject: [PATCH 26/39] missing curlies >_> --- projects/gloo/pkg/translator/network_filters_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gloo/pkg/translator/network_filters_test.go b/projects/gloo/pkg/translator/network_filters_test.go index a1d30514938..73b11c625e7 100644 --- a/projects/gloo/pkg/translator/network_filters_test.go +++ b/projects/gloo/pkg/translator/network_filters_test.go @@ -53,7 +53,7 @@ var _ = Describe("Router filter test", func() { }) } - translatorFactory := translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), &v1.Settings) + translatorFactory := translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), &v1.Settings{}) listener := &v1.Listener{ Name: "aggregate-listener", BindAddress: gatewaydefaults.GatewayBindAddress, From de34f502b9035719f8b002ebf098ee4e17373c95 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 08:20:08 -0400 Subject: [PATCH 27/39] helm values fixes --- .../settings/compressed_proxy_spec.yaml | 56 ++++----- .../consul_config_upstream_discovery.yaml | 85 +++++++------- .../settings/consul_config_values.yaml | 107 +++++++++--------- .../disable_kubernetes_destinations.yaml | 71 ++++++------ .../disable_proxy_garbage_collection.yaml | 71 ++++++------ .../fixtures/settings/disabled_gateway.yaml | 3 +- .../settings/enable_default_credentials.yaml | 3 +- .../fixtures/settings/enable_rest_eds.yaml | 71 ++++++------ .../enable_rest_eds_and_gloo_mtls.yaml | 71 ++++++------ .../settings/gateway_circuit_breakers.yaml | 81 ++++++------- .../fixtures/settings/gateway_settings.yaml | 71 ++++++------ .../settings/graphql_fds_disabled.yaml | 1 + .../isolate_virtual_hosts_by_ssl_config.yaml | 3 +- .../settings/ratelimit_descriptors.yaml | 85 +++++++------- .../fixtures/settings/ratelimit_server.yaml | 85 +++++++------- .../read_gateways_from_all_namespaces.yaml | 54 ++++----- .../settings/set_regex_max_program_size.yaml | 3 +- .../set_regex_max_program_size_default.yaml | 3 +- .../set_secretSettings_in_settings.yaml | 3 +- .../test/fixtures/settings/sts_discovery.yaml | 3 +- .../settings/translate_empty_gateway.yaml | 58 +++++----- .../settings/watched_discovery_labels.yaml | 3 +- 22 files changed, 505 insertions(+), 486 deletions(-) diff --git a/install/test/fixtures/settings/compressed_proxy_spec.yaml b/install/test/fixtures/settings/compressed_proxy_spec.yaml index 99e73032ce3..b981bd4ae00 100644 --- a/install/test/fixtures/settings/compressed_proxy_spec.yaml +++ b/install/test/fixtures/settings/compressed_proxy_spec.yaml @@ -7,31 +7,31 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - compressedProxySpec: true - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + compressedProxySpec: true + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/consul_config_upstream_discovery.yaml b/install/test/fixtures/settings/consul_config_upstream_discovery.yaml index c05c82d6f9a..74d2ac208f9 100644 --- a/install/test/fixtures/settings/consul_config_upstream_discovery.yaml +++ b/install/test/fixtures/settings/consul_config_upstream_discovery.yaml @@ -7,45 +7,46 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - enableGatewayController: true - readGatewaysFromAllNamespaces: false - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - consulDiscovery: - useTlsTagging: true - tlsTagName: tag - splitTlsServices: true - rootCa: - name: testName - namespace: testNamespace - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + enableGatewayController: true + readGatewaysFromAllNamespaces: false + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + consulDiscovery: + useTlsTagging: true + tlsTagName: tag + splitTlsServices: true + rootCa: + name: testName + namespace: testNamespace + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/consul_config_values.yaml b/install/test/fixtures/settings/consul_config_values.yaml index 5065306fbd2..11d4f4c40d4 100644 --- a/install/test/fixtures/settings/consul_config_values.yaml +++ b/install/test/fixtures/settings/consul_config_values.yaml @@ -7,56 +7,57 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - isolateVirtualHostsBySslConfig: false - enableGatewayController: true - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - consul: - datacenter: datacenter - username: user - password: password - token: aToken - caFile: testCaFile - caPath: testCaPath - certFile: testCertFile - keyFile: testKeyFile - insecureSkipVerify: true - waitTime: 12s - serviceDiscovery: - dataCenters: - - dc1 - - dc2 - httpAddress: 1.2.3.4 - dnsAddress: 5.6.7.8 - dnsPollingInterval: 5s - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + isolateVirtualHostsBySslConfig: false + enableGatewayController: true + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + consul: + datacenter: datacenter + username: user + password: password + token: aToken + caFile: testCaFile + caPath: testCaPath + certFile: testCertFile + keyFile: testKeyFile + insecureSkipVerify: true + waitTime: 12s + serviceDiscovery: + dataCenters: + - dc1 + - dc2 + httpAddress: 1.2.3.4 + dnsAddress: 5.6.7.8 + dnsPollingInterval: 5s + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/disable_kubernetes_destinations.yaml b/install/test/fixtures/settings/disable_kubernetes_destinations.yaml index b4eb0c9e4e2..979f00e91fe 100644 --- a/install/test/fixtures/settings/disable_kubernetes_destinations.yaml +++ b/install/test/fixtures/settings/disable_kubernetes_destinations.yaml @@ -7,38 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: true - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: true + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/disable_proxy_garbage_collection.yaml b/install/test/fixtures/settings/disable_proxy_garbage_collection.yaml index 1415ab13e86..1d2b24fec48 100644 --- a/install/test/fixtures/settings/disable_proxy_garbage_collection.yaml +++ b/install/test/fixtures/settings/disable_proxy_garbage_collection.yaml @@ -7,38 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: true - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: true + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/disabled_gateway.yaml b/install/test/fixtures/settings/disabled_gateway.yaml index 374d61a3293..3e08aecb461 100644 --- a/install/test/fixtures/settings/disabled_gateway.yaml +++ b/install/test/fixtures/settings/disabled_gateway.yaml @@ -17,6 +17,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -42,4 +43,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/enable_default_credentials.yaml b/install/test/fixtures/settings/enable_default_credentials.yaml index 21529875af5..7f7fe072f11 100644 --- a/install/test/fixtures/settings/enable_default_credentials.yaml +++ b/install/test/fixtures/settings/enable_default_credentials.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -43,4 +44,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/enable_rest_eds.yaml b/install/test/fixtures/settings/enable_rest_eds.yaml index ad2d6b7b6db..3f4c31ce14d 100644 --- a/install/test/fixtures/settings/enable_rest_eds.yaml +++ b/install/test/fixtures/settings/enable_rest_eds.yaml @@ -7,38 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/enable_rest_eds_and_gloo_mtls.yaml b/install/test/fixtures/settings/enable_rest_eds_and_gloo_mtls.yaml index b595e82c8c8..17a4738b46b 100644 --- a/install/test/fixtures/settings/enable_rest_eds_and_gloo_mtls.yaml +++ b/install/test/fixtures/settings/enable_rest_eds_and_gloo_mtls.yaml @@ -7,38 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: "127.0.0.1:9999" - restXdsBindAddr: "127.0.0.1:9998" - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: "127.0.0.1:9999" + restXdsBindAddr: "127.0.0.1:9998" + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/gateway_circuit_breakers.yaml b/install/test/fixtures/settings/gateway_circuit_breakers.yaml index d28b6fa59e6..931e21a4bc9 100644 --- a/install/test/fixtures/settings/gateway_circuit_breakers.yaml +++ b/install/test/fixtures/settings/gateway_circuit_breakers.yaml @@ -7,43 +7,44 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - circuitBreakers: - maxConnections: 1024 - maxPendingRequests: 1024 - maxRequests: 1024 - maxRetries: 3 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - replaceInvalidRoutes: false - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + circuitBreakers: + maxConnections: 1024 + maxPendingRequests: 1024 + maxRequests: 1024 + maxRetries: 3 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + replaceInvalidRoutes: false + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/gateway_settings.yaml b/install/test/fixtures/settings/gateway_settings.yaml index 081983b20ae..d3de611fe12 100644 --- a/install/test/fixtures/settings/gateway_settings.yaml +++ b/install/test/fixtures/settings/gateway_settings.yaml @@ -7,38 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - replaceInvalidRoutes: true - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + replaceInvalidRoutes: true + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/graphql_fds_disabled.yaml b/install/test/fixtures/settings/graphql_fds_disabled.yaml index c0ff697b8ac..63184351d2d 100644 --- a/install/test/fixtures/settings/graphql_fds_disabled.yaml +++ b/install/test/fixtures/settings/graphql_fds_disabled.yaml @@ -18,6 +18,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false diff --git a/install/test/fixtures/settings/isolate_virtual_hosts_by_ssl_config.yaml b/install/test/fixtures/settings/isolate_virtual_hosts_by_ssl_config.yaml index 00c99798633..545158e3e19 100644 --- a/install/test/fixtures/settings/isolate_virtual_hosts_by_ssl_config.yaml +++ b/install/test/fixtures/settings/isolate_virtual_hosts_by_ssl_config.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -41,4 +42,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/ratelimit_descriptors.yaml b/install/test/fixtures/settings/ratelimit_descriptors.yaml index d4bf1bb8fc5..bd608a292cf 100644 --- a/install/test/fixtures/settings/ratelimit_descriptors.yaml +++ b/install/test/fixtures/settings/ratelimit_descriptors.yaml @@ -7,45 +7,46 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} - ratelimit: - descriptors: - - key: generic_key - value: "per-second" - rateLimit: - requestsPerUnit: 2 - unit: SECOND \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} + ratelimit: + descriptors: + - key: generic_key + value: "per-second" + rateLimit: + requestsPerUnit: 2 + unit: SECOND diff --git a/install/test/fixtures/settings/ratelimit_server.yaml b/install/test/fixtures/settings/ratelimit_server.yaml index 6bdc1c056aa..ff6d6849c9b 100644 --- a/install/test/fixtures/settings/ratelimit_server.yaml +++ b/install/test/fixtures/settings/ratelimit_server.yaml @@ -7,45 +7,46 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - serverEnabled: true - disableTransformationValidation: false - warnRouteShortCircuiting: false - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} - ratelimitServer: - ratelimitServerRef: - name: ratelimit - namespace: ratelimitns - denyOnFail: true - rateLimitBeforeAuth: true - enableXRatelimitHeaders: true + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: true + serverEnabled: true + disableTransformationValidation: false + warnRouteShortCircuiting: false + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} + ratelimitServer: + ratelimitServerRef: + name: ratelimit + namespace: ratelimitns + denyOnFail: true + rateLimitBeforeAuth: true + enableXRatelimitHeaders: true diff --git a/install/test/fixtures/settings/read_gateways_from_all_namespaces.yaml b/install/test/fixtures/settings/read_gateways_from_all_namespaces.yaml index 9a1b96c5036..1002dae7f49 100644 --- a/install/test/fixtures/settings/read_gateways_from_all_namespaces.yaml +++ b/install/test/fixtures/settings/read_gateways_from_all_namespaces.yaml @@ -7,30 +7,30 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: true - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: true + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/set_regex_max_program_size.yaml b/install/test/fixtures/settings/set_regex_max_program_size.yaml index a8fe8d51f62..c43c6d6a442 100644 --- a/install/test/fixtures/settings/set_regex_max_program_size.yaml +++ b/install/test/fixtures/settings/set_regex_max_program_size.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -41,4 +42,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/set_regex_max_program_size_default.yaml b/install/test/fixtures/settings/set_regex_max_program_size_default.yaml index a5ecde5fb22..8a585cb5e4f 100644 --- a/install/test/fixtures/settings/set_regex_max_program_size_default.yaml +++ b/install/test/fixtures/settings/set_regex_max_program_size_default.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -41,4 +42,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/set_secretSettings_in_settings.yaml b/install/test/fixtures/settings/set_secretSettings_in_settings.yaml index d5586fdae23..5ac6616030f 100644 --- a/install/test/fixtures/settings/set_secretSettings_in_settings.yaml +++ b/install/test/fixtures/settings/set_secretSettings_in_settings.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -51,4 +52,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/sts_discovery.yaml b/install/test/fixtures/settings/sts_discovery.yaml index 32c2fcb1eb7..5bb62dc3fef 100644 --- a/install/test/fixtures/settings/sts_discovery.yaml +++ b/install/test/fixtures/settings/sts_discovery.yaml @@ -16,6 +16,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -47,4 +48,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/fixtures/settings/translate_empty_gateway.yaml b/install/test/fixtures/settings/translate_empty_gateway.yaml index e51798fde5f..2b65bf3b848 100644 --- a/install/test/fixtures/settings/translate_empty_gateway.yaml +++ b/install/test/fixtures/settings/translate_empty_gateway.yaml @@ -7,32 +7,32 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - translateEmptyGateways: true - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - replaceInvalidRoutes: false - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} - + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + translateEmptyGateways: true + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + replaceInvalidRoutes: false + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} + diff --git a/install/test/fixtures/settings/watched_discovery_labels.yaml b/install/test/fixtures/settings/watched_discovery_labels.yaml index 2fa313195f7..173a25bd76d 100644 --- a/install/test/fixtures/settings/watched_discovery_labels.yaml +++ b/install/test/fixtures/settings/watched_discovery_labels.yaml @@ -19,6 +19,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -44,4 +45,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} From e2a98ab2d7139c2b8e7c4429230d029115aa4548 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 08:20:36 -0400 Subject: [PATCH 28/39] missed one --- .../fixtures/settings/gateway_validation.yaml | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/install/test/fixtures/settings/gateway_validation.yaml b/install/test/fixtures/settings/gateway_validation.yaml index 0aa2ade2c59..513186cbf65 100644 --- a/install/test/fixtures/settings/gateway_validation.yaml +++ b/install/test/fixtures/settings/gateway_validation.yaml @@ -7,39 +7,39 @@ metadata: name: default namespace: {{ . }} spec: - discovery: - fdsMode: WHITELIST - gateway: - readGatewaysFromAllNamespaces: false - enableGatewayController: true - isolateVirtualHostsBySslConfig: false - validation: - alwaysAccept: true - allowWarnings: true - warnMissingTlsSecret: false - serverEnabled: true - disableTransformationValidation: true - warnRouteShortCircuiting: true - proxyValidationServerAddr: gloo:9988 - validationServerGrpcMaxSizeBytes: 104857600 - gloo: - regexMaxProgramSize: 1024 - enableRestEds: false - xdsBindAddr: 0.0.0.0:9977 - restXdsBindAddr: 0.0.0.0:9976 - proxyDebugBindAddr: 0.0.0.0:9966 - disableKubernetesDestinations: false - disableProxyGarbageCollection: false - invalidConfigPolicy: - replaceInvalidRoutes: false - invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. - invalidRouteResponseCode: 404 - istioOptions: - appendXForwardedHost: true - enableAutoMtls: false - enableIntegration: false - kubernetesArtifactSource: {} - kubernetesConfigSource: {} - kubernetesSecretSource: {} - refreshRate: 60s - discoveryNamespace: {{ . }} + discovery: + fdsMode: WHITELIST + gateway: + readGatewaysFromAllNamespaces: false + enableGatewayController: true + isolateVirtualHostsBySslConfig: false + validation: + alwaysAccept: true + allowWarnings: true + warnMissingTlsSecret: false + serverEnabled: true + disableTransformationValidation: true + warnRouteShortCircuiting: true + proxyValidationServerAddr: gloo:9988 + validationServerGrpcMaxSizeBytes: 104857600 + gloo: + regexMaxProgramSize: 1024 + enableRestEds: false + xdsBindAddr: 0.0.0.0:9977 + restXdsBindAddr: 0.0.0.0:9976 + proxyDebugBindAddr: 0.0.0.0:9966 + disableKubernetesDestinations: false + disableProxyGarbageCollection: false + invalidConfigPolicy: + replaceInvalidRoutes: false + invalidRouteResponseBody: Gloo Gateway has invalid configuration. Administrators should run `glooctl check` to find and fix config errors. + invalidRouteResponseCode: 404 + istioOptions: + appendXForwardedHost: true + enableAutoMtls: false + enableIntegration: false + kubernetesArtifactSource: {} + kubernetesConfigSource: {} + kubernetesSecretSource: {} + refreshRate: 60s + discoveryNamespace: {{ . }} From 2dd6438488e0a61e506236ca87ca6ae9e1724d91 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 08:34:24 -0400 Subject: [PATCH 29/39] wrong value in test setup --- install/test/helm_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/test/helm_test.go b/install/test/helm_test.go index 8f81cfbc7a6..f05e2a7b981 100644 --- a/install/test/helm_test.go +++ b/install/test/helm_test.go @@ -4170,7 +4170,7 @@ spec: ValuesArgs: []string{ "gateway.validation.disableTransformationValidation=true", "gateway.validation.warnRouteShortCircuiting=true", - "gateway.validation.warnMissingTlsSecret=true", + "gateway.validation.warnMissingTlsSecret=false", }, }) testManifest.ExpectUnstructured(settings.GetKind(), settings.GetNamespace(), settings.GetName()).To(BeEquivalentTo(settings)) From 97d46c607eb06924bc2fc22f4ed53e6e2df2de67 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 09:08:12 -0400 Subject: [PATCH 30/39] helm tests are actually passing now... excellent... --- install/test/fixtures/settings/uds_disabled.yaml | 3 ++- install/test/helm_test.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/install/test/fixtures/settings/uds_disabled.yaml b/install/test/fixtures/settings/uds_disabled.yaml index 25715feb999..737a5accd85 100644 --- a/install/test/fixtures/settings/uds_disabled.yaml +++ b/install/test/fixtures/settings/uds_disabled.yaml @@ -18,6 +18,7 @@ spec: validation: alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false @@ -43,4 +44,4 @@ spec: kubernetesConfigSource: {} kubernetesSecretSource: {} refreshRate: 60s - discoveryNamespace: {{ . }} \ No newline at end of file + discoveryNamespace: {{ . }} diff --git a/install/test/helm_test.go b/install/test/helm_test.go index f05e2a7b981..713ae5f7ff6 100644 --- a/install/test/helm_test.go +++ b/install/test/helm_test.go @@ -4373,6 +4373,7 @@ spec: proxyValidationServerAddr: gloo:9988 alwaysAccept: true allowWarnings: true + warnMissingTlsSecret: true serverEnabled: true disableTransformationValidation: false warnRouteShortCircuiting: false From a8c4afd7eb8814a4578b3a984fc15587cba8d22e Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 09:55:43 -0400 Subject: [PATCH 31/39] fix translation tests --- .../pkg/translator/listener_subsystem_test.go | 17 +++++++++++++++-- projects/gloo/pkg/translator/translator_test.go | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/projects/gloo/pkg/translator/listener_subsystem_test.go b/projects/gloo/pkg/translator/listener_subsystem_test.go index b16019b5dcb..91d68b0890a 100644 --- a/projects/gloo/pkg/translator/listener_subsystem_test.go +++ b/projects/gloo/pkg/translator/listener_subsystem_test.go @@ -9,6 +9,7 @@ import ( envoy_http_connection_manager_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "github.com/golang/mock/gomock" "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/types/known/wrapperspb" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -59,6 +60,8 @@ var _ = Describe("Listener Subsystem", func() { ctrl *gomock.Controller sslTranslator *mock_utils.MockSslConfigTranslator + + settings *v1.Settings ) BeforeEach(func() { @@ -68,6 +71,15 @@ var _ = Describe("Listener Subsystem", func() { ctx, cancel = context.WithCancel(context.Background()) + settings = &v1.Settings{ + Gateway: &v1.GatewayOptions{ + Validation: &v1.GatewayOptions_ValidationOptions{ + // set this as it is the default setting initialized by helm + WarnMissingTlsSecret: &wrapperspb.BoolValue{Value: true}, + }, + }, + } + // Create a pluginRegistry with a minimal number of plugins // This test is not concerned with the functionality of individual plugins pluginRegistry := registry.NewPluginRegistry([]plugins.Plugin{ @@ -81,11 +93,12 @@ var _ = Describe("Listener Subsystem", func() { for _, p := range pluginRegistry.GetPlugins() { p.Init(plugins.InitParams{ Ctx: ctx, - Settings: &v1.Settings{}, + Settings: settings, }) } - translatorFactory = translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), &v1.Settings{}) + translatorFactory = translator.NewListenerSubsystemTranslatorFactory(pluginRegistry, sslutils.NewSslConfigTranslator(), settings) + }) AfterEach(func() { diff --git a/projects/gloo/pkg/translator/translator_test.go b/projects/gloo/pkg/translator/translator_test.go index d9bd8c418a4..e57777b986c 100644 --- a/projects/gloo/pkg/translator/translator_test.go +++ b/projects/gloo/pkg/translator/translator_test.go @@ -123,6 +123,8 @@ var _ = Describe("Translator", func() { // "Invalid type URL, unknown type: envoy.api.v2.filter.http.RouteTransformations for type Any)" // We do not perform transformation validation as part of our translator tests, so we explicitly disable this DisableTransformationValidation: &wrappers.BoolValue{Value: true}, + // We set this value as it is defaulted on via helm + WarnMissingTlsSecret: &wrappers.BoolValue{Value: true}, }, }, } From efb1631d62047fe5ade6ac21d26a72600329b8bb Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 10:16:41 -0400 Subject: [PATCH 32/39] put breaking change verbage in changelog --- changelog/v1.18.0-beta16/missing-tls-secret.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog/v1.18.0-beta16/missing-tls-secret.yaml b/changelog/v1.18.0-beta16/missing-tls-secret.yaml index 0a41e276821..286837da4e9 100644 --- a/changelog/v1.18.0-beta16/missing-tls-secret.yaml +++ b/changelog/v1.18.0-beta16/missing-tls-secret.yaml @@ -1,11 +1,11 @@ changelog: - - type: FIX + - type: BREAKING_CHANGE issueLink: https://github.com/solo-io/gloo/issues/6957 resolvesIssue: false description: >- Fix for issue where a missing TLS secret was treated by validation as an error, potentially bringing down the entire HTTPS gateway if the gloo pod restarts while - in this bad state. + in this bad state. This is a breaking change in the default behavior of validation. To disable this behavior, use the helm setting `gateway.validation.warnMissingTlsSecret=false` or the same field on the Settings CR. This field has no effect if allowWarnings is false or From b7c9d8e11cd9df9872048ae5c0226b89d57131d4 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Fri, 16 Aug 2024 15:09:44 -0400 Subject: [PATCH 33/39] add setting to preserve missing secret error to test manifest --- test/kubernetes/e2e/tests/manifests/edge-gateway-test-helm.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/kubernetes/e2e/tests/manifests/edge-gateway-test-helm.yaml b/test/kubernetes/e2e/tests/manifests/edge-gateway-test-helm.yaml index c9d5589709e..4e27e26243e 100644 --- a/test/kubernetes/e2e/tests/manifests/edge-gateway-test-helm.yaml +++ b/test/kubernetes/e2e/tests/manifests/edge-gateway-test-helm.yaml @@ -13,6 +13,8 @@ gateway: validation: allowWarnings: true alwaysAcceptResources: false + # added to preserve behavior tested by this suite. + warnMissingTlsSecret: false # skipping delete validation due to flakes per https://github.com/solo-io/solo-projects/issues/6272 webhook: skipDeleteValidationResources: From 45003822039f3ba899c1848b115be493013ad08b Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 19 Aug 2024 07:03:25 -0400 Subject: [PATCH 34/39] revert allow_warnings test --- .../validation_allow_warnings/suite.go | 94 ------------------- .../validation-always-accept-helm.yaml | 2 + 2 files changed, 2 insertions(+), 94 deletions(-) diff --git a/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go b/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go index d508e072e8b..65faed99b4e 100644 --- a/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go +++ b/test/kubernetes/e2e/features/validation/validation_allow_warnings/suite.go @@ -2,8 +2,6 @@ package validation_allow_warnings import ( "context" - "os" - "time" gloo_defaults "github.com/solo-io/gloo/projects/gloo/pkg/defaults" "github.com/solo-io/gloo/test/kubernetes/e2e" @@ -36,98 +34,6 @@ func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite. } } -/* -TestVirtualServiceWithSecretDeletion tests behaviors when Gloo rejects a VirtualService with a secret that is deleted - -To create the private key and certificate to use: - - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout tls.key -out tls.crt -subj "/CN=*" - -To create the Kubernetes secrets to hold this cert: - - kubectl create secret tls upstream-tls --key tls.key \ - --cert tls.crt --namespace gloo-system -*/ -func (s *testingSuite) TestVirtualServiceWithSecretDeletion() { - // VS with secret should be accepted, need to substitute the secret ns - secretVS, err := os.ReadFile(validation.SecretVSTemplate) - s.Assert().NoError(err) - // Replace environment variables placeholders with their values - substitutedSecretVS := os.ExpandEnv(string(secretVS)) - - s.T().Cleanup(func() { - // Can delete resources in correct order - err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, []byte(substitutedSecretVS), "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err, "can delete virtual service with secret") - - // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update - s.Assert().Eventually(func() bool { - err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) - return err == nil - }, time.Minute, 5*time.Second, "can delete "+validation.ExampleUpstream) - - // Delete can fail with strict validation if VS is not deleted first from snapshot, so try multiple times so that snapshot has time to update - s.Assert().Eventually(func() bool { - err := s.testInstallation.Actions.Kubectl().DeleteFileSafe(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) - return err == nil - }, time.Minute, 5*time.Second, "can delete "+validation.Secret) - - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, testdefaults.NginxPodManifest) - s.Assert().NoError(err, "can delete "+testdefaults.NginxPodManifest) - }) - - // apply example app - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, testdefaults.NginxPodManifest) - s.Assert().NoError(err) - // Check that test resources are running - s.testInstallation.Assertions.EventuallyPodsRunning(s.ctx, testdefaults.NginxPod.ObjectMeta.GetNamespace(), metav1.ListOptions{ - LabelSelector: "app.kubernetes.io/name=nginx", - }) - - // Secrets should be accepted - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) - - // Upstream should be accepted - err = s.testInstallation.Actions.Kubectl().ApplyFile(s.ctx, validation.ExampleUpstream, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) - s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( - func() (resources.InputResource, error) { - return s.testInstallation.ResourceClients.UpstreamClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleUpstreamName, clients.ReadOpts{Ctx: s.ctx}) - }, - core.Status_Accepted, - gloo_defaults.GlooReporter, - ) - // Apply VS with secret after Upstream and Secret exist - err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, []byte(substitutedSecretVS)) - s.Assert().NoError(err) - s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( - func() (resources.InputResource, error) { - return s.testInstallation.ResourceClients.VirtualServiceClient().Read(s.testInstallation.Metadata.InstallNamespace, validation.ExampleVsName, clients.ReadOpts{Ctx: s.ctx}) - }, - core.Status_Accepted, - gloo_defaults.GlooReporter, - ) - - // attempting to delete a secret that is in use produces a warning but succeeds - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.Secret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) - s.testInstallation.Assertions.EventuallyResourceStatusMatchesState( - func() (resources.InputResource, error) { - return s.testInstallation.ResourceClients.GatewayClient().Read(s.testInstallation.Metadata.InstallNamespace, "gateway-proxy-ssl", clients.ReadOpts{Ctx: s.ctx}) - }, - core.Status_Warning, - gloo_defaults.GlooReporter, - ) - - // deleting a secret that is not in use works - err = s.testInstallation.Actions.Kubectl().DeleteFile(s.ctx, validation.UnusedSecret, "-n", s.testInstallation.Metadata.InstallNamespace) - s.Assert().NoError(err) -} - // TestMissingUpstream tests behaviors when Gloo allows invalid VirtualServices to be persisted func (s *testingSuite) TestMissingUpstream() { s.T().Cleanup(func() { diff --git a/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml b/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml index 0cc96d5aaf9..60ee4817e46 100644 --- a/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml +++ b/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml @@ -20,6 +20,8 @@ gateway: validation: allowWarnings: true alwaysAcceptResources: true + # added to preserve behavior tested by this suite. + warnMissingTlsSecret: false kubeGateway: # This is the field that enables the K8s Gateway Integration in Gloo Gateway enabled: true From 6eeb021cfa658a0b9b91c422dc63d6a122cd9914 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 19 Aug 2024 09:34:40 -0400 Subject: [PATCH 35/39] add icky sleep --- .../e2e/features/server_tls/suite.go | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/kubernetes/e2e/features/server_tls/suite.go b/test/kubernetes/e2e/features/server_tls/suite.go index 3ab363a7da5..7fccaba6193 100644 --- a/test/kubernetes/e2e/features/server_tls/suite.go +++ b/test/kubernetes/e2e/features/server_tls/suite.go @@ -18,7 +18,8 @@ import ( var _ e2e.NewSuiteFunc = NewTestingSuite -// serverTlsTestingSuite is the entire Suite of tests for the "Gloo mtls" cases +// serverTlsTestingSuite is the entire Suite of tests for gloo gateway proxy serving terminated TLS. +// The assertions in these tests assume that the warnMissingTlsSecret setting is "false" type serverTlsTestingSuite struct { suite.Suite @@ -45,8 +46,8 @@ func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite. func (s *serverTlsTestingSuite) SetupSuite() { var err error - // We are substituting our namespace via os.ExpandEnv in order to place our referenced - // resources in our NS. + // These functions each substitute our namespace for placeholders in the given manifest + // file via os.ExpandEnv in order to place our referenced resources in our NS. s.tlsSecret1, err = tlsSecret1Manifest() s.NoError(err, "can substitute NS in tlsSecret1") s.tlsSecret2, err = tlsSecret2Manifest() @@ -72,9 +73,9 @@ func (s *serverTlsTestingSuite) TearDownSuite() { s.NoError(err, "can delete Curl setup manifest") } -// TestServerTls validates the happy path that a VirtualService referencing an existent TLS secret +// TestOneVirtualService validates the happy path that a VirtualService referencing an existent TLS secret // terminates TLS and responds appropriately. -func (s *serverTlsTestingSuite) TestServerTls() { +func (s *serverTlsTestingSuite) TestOneVirtualService() { vs1 := vs1(s.ns) s.T().Cleanup(func() { // ordering here matters if strict validation enabled @@ -98,9 +99,9 @@ func (s *serverTlsTestingSuite) TestServerTls() { s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) } -// TestServerTlsTwoVirtualServices validates the happy path that two VirtualServices referencing existent TLS secrets +// TestTwoVirtualServices validates the happy path that two VirtualServices referencing existent TLS secrets // terminate TLS and respond appropriately. -func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { +func (s *serverTlsTestingSuite) TestTwoVirtualServices() { vs1 := vs1(s.ns) vs2 := vs2(s.ns) s.T().Cleanup(func() { @@ -133,12 +134,12 @@ func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServices() { s.assertEventualResponse(vs2.GetName(), expectedHealthyResponse2) } -// TestServerTlsTwoVirtualServicesOneMissingTlsSecret validates that when we have two VirtualServices referencing TLS +// TestTwoVirtualServicesOneMissingTlsSecret validates that when we have two VirtualServices referencing TLS // secrets, but one secret is missing, the traffic routing defined by the other VirtualService is not affected. In order // to test this properly, we require persistProxySpec to be off, validating that both VS are working correctly, // then we delete the secret for one of the VS and restart the Gloo pod. This ensures that we are still // serving on the other VS. -func (s *serverTlsTestingSuite) TestServerTlsTwoVirtualServicesOneMissingTlsSecret() { +func (s *serverTlsTestingSuite) TestTwoVirtualServicesOneMissingTlsSecret() { vs1 := vs1(s.ns) vs2 := vs2(s.ns) s.T().Cleanup(func() { @@ -208,8 +209,13 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { // ordering here matters if strict validation enabled err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can apply tls secret manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecretWithCa(s.ns)) + // TODO(jbohanon) remove this sleep by figuring out why the `EventuallyObjectsExist` + // is not sufficient to get the VS through validation. Stale snapshots? + time.Sleep(time.Second * 5) // 2 seconds consistently worked on local; 2.5x that to prevent flakes err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, vsWithoutOneWay(s.ns)) s.assertEventualError(vs.GetName(), expectedFailedResponseCodeInvalidVs) } From ffdc5b131ef654a9b301f43836833aafefadd555 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 19 Aug 2024 14:27:31 -0400 Subject: [PATCH 36/39] expand admin server assertions, move server tls test --- .../e2e/features/admin_server/suite.go | 40 ++---------------- .../error_missing_tls_secret/suite.go | 0 .../e2e/features/server_tls/suite.go | 42 +++++++++++++++++-- .../e2e/features/server_tls/types.go | 7 ++++ .../e2e/features/validation/README.md | 15 +++---- test/kubernetes/e2e/test.go | 2 +- test/kubernetes/e2e/tests/edge_gw_tests.go | 2 - .../manifests/validation-strict-helm.yaml | 2 + .../tests/validation_always_accept_tests.go | 4 ++ test/kubernetes/testutils/assertions/gloo.go | 38 +++++++++++++++++ 10 files changed, 102 insertions(+), 50 deletions(-) create mode 100644 test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go diff --git a/test/kubernetes/e2e/features/admin_server/suite.go b/test/kubernetes/e2e/features/admin_server/suite.go index 55f02d76236..c997feca8bf 100644 --- a/test/kubernetes/e2e/features/admin_server/suite.go +++ b/test/kubernetes/e2e/features/admin_server/suite.go @@ -2,18 +2,12 @@ package admin_server import ( "context" - "time" "github.com/solo-io/gloo/projects/gateway2/api/v1alpha1" v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/onsi/gomega/types" "github.com/solo-io/gloo/projects/gloo/pkg/defaults" - "github.com/onsi/gomega" - "github.com/solo-io/gloo/pkg/utils/glooadminutils/admincli" "github.com/solo-io/gloo/pkg/utils/kubeutils" "github.com/solo-io/gloo/test/kubernetes/e2e" "github.com/stretchr/testify/suite" @@ -50,7 +44,7 @@ func (s *testingSuite) TestGetInputSnapshotIncludesSettings() { Name: kubeutils.GlooDeploymentName, Namespace: s.testInstallation.Metadata.InstallNamespace, }, - inputSnapshotContainsElement(s.testInstallation, v1.SettingsGVK, metav1.ObjectMeta{ + s.testInstallation.Assertions.InputSnapshotContainsElement(v1.SettingsGVK, metav1.ObjectMeta{ Name: defaults.SettingsName, Namespace: s.testInstallation.Metadata.InstallNamespace, }), @@ -74,7 +68,7 @@ func (s *testingSuite) TestGetInputSnapshotIncludesEdgeApiResources() { Name: kubeutils.GlooDeploymentName, Namespace: s.testInstallation.Metadata.InstallNamespace, }, - inputSnapshotContainsElement(s.testInstallation, v1.UpstreamGVK, upstreamMeta), + s.testInstallation.Assertions.InputSnapshotContainsElement(v1.UpstreamGVK, upstreamMeta), ) } @@ -99,34 +93,6 @@ func (s *testingSuite) TestGetInputSnapshotIncludesK8sGatewayApiResources() { Name: kubeutils.GlooDeploymentName, Namespace: s.testInstallation.Metadata.InstallNamespace, }, - inputSnapshotContainsElement(s.testInstallation, v1alpha1.GatewayParametersGVK, gatewayParametersMeta), + s.testInstallation.Assertions.InputSnapshotContainsElement(v1alpha1.GatewayParametersGVK, gatewayParametersMeta), ) } - -func inputSnapshotContainsElement(testInstallation *e2e.TestInstallation, gvk schema.GroupVersionKind, meta metav1.ObjectMeta) func(ctx context.Context, adminClient *admincli.Client) { - return inputSnapshotMatches(testInstallation, gomega.ContainElement( - gomega.And( - gomega.HaveKeyWithValue("kind", gomega.Equal(gvk.Kind)), - gomega.HaveKeyWithValue("apiVersion", gomega.Equal(gvk.GroupVersion().String())), - gomega.HaveKeyWithValue("metadata", gomega.And( - gomega.HaveKeyWithValue("name", meta.GetName()), - gomega.HaveKeyWithValue("namespace", meta.GetNamespace()), - )), - ), - )) -} - -func inputSnapshotMatches(testInstallation *e2e.TestInstallation, inputSnapshotMatcher types.GomegaMatcher) func(ctx context.Context, adminClient *admincli.Client) { - return func(ctx context.Context, adminClient *admincli.Client) { - testInstallation.Assertions.Gomega.Eventually(func(g gomega.Gomega) { - inputSnapshot, err := adminClient.GetInputSnapshot(ctx) - g.Expect(err).NotTo(gomega.HaveOccurred(), "error getting input snapshot") - g.Expect(inputSnapshot).NotTo(gomega.BeEmpty(), "objects are returned") - g.Expect(inputSnapshot).To(inputSnapshotMatcher) - }). - WithContext(ctx). - WithTimeout(time.Second * 10). - WithPolling(time.Millisecond * 200). - Should(gomega.Succeed()) - } -} diff --git a/test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go b/test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/kubernetes/e2e/features/server_tls/suite.go b/test/kubernetes/e2e/features/server_tls/suite.go index 7fccaba6193..9d28d0049f9 100644 --- a/test/kubernetes/e2e/features/server_tls/suite.go +++ b/test/kubernetes/e2e/features/server_tls/suite.go @@ -4,12 +4,14 @@ import ( "context" "time" + gatewayv1 "github.com/solo-io/gloo/projects/gateway/pkg/api/v1" "github.com/solo-io/gloo/projects/gateway/pkg/defaults" "github.com/solo-io/gloo/test/gomega/matchers" "github.com/solo-io/gloo/test/kube2e/helper" testdefaults "github.com/solo-io/gloo/test/kubernetes/e2e/defaults" "github.com/stretchr/testify/suite" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "github.com/solo-io/gloo/pkg/utils/kubeutils" "github.com/solo-io/gloo/pkg/utils/requestutils/curl" @@ -82,6 +84,7 @@ func (s *serverTlsTestingSuite) TestOneVirtualService() { err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can delete vs1 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs1.ObjectMeta) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret manifest file") // tlsSecret2 is deleted in the process of the test. @@ -92,6 +95,7 @@ func (s *serverTlsTestingSuite) TestOneVirtualService() { err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret1) s.NoError(err, "can apply tls secret 1 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns)) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecret1(s.ns).ObjectMeta) err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") @@ -111,6 +115,8 @@ func (s *serverTlsTestingSuite) TestTwoVirtualServices() { err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can delete vs2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs1.ObjectMeta) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs2.ObjectMeta) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret 1 manifest file") err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret2) @@ -124,6 +130,8 @@ func (s *serverTlsTestingSuite) TestTwoVirtualServices() { err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret2) s.NoError(err, "can apply tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecret1(s.ns).ObjectMeta) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecret2(s.ns).ObjectMeta) err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs2, "-n", s.ns) @@ -149,6 +157,8 @@ func (s *serverTlsTestingSuite) TestTwoVirtualServicesOneMissingTlsSecret() { err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vs2, "-n", s.ns) s.NoError(err, "can delete vs2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs1, vs2) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs1.ObjectMeta) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs2.ObjectMeta) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret1) s.NoError(err, "can delete tls secret manifest file") // tlsSecret2 is deleted in the process of the test. @@ -161,6 +171,8 @@ func (s *serverTlsTestingSuite) TestTwoVirtualServicesOneMissingTlsSecret() { err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecret2) s.NoError(err, "can apply tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecret1(s.ns), tlsSecret2(s.ns)) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecret1(s.ns).ObjectMeta) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecret2(s.ns).ObjectMeta) err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs1, "-n", s.ns) s.NoError(err, "can apply vs1 manifest file") err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vs2, "-n", s.ns) @@ -174,6 +186,7 @@ func (s *serverTlsTestingSuite) TestTwoVirtualServicesOneMissingTlsSecret() { err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecret2) s.NoError(err, "can delete tls secret 2 manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecret2(s.ns)) + s.eventuallyNotInSnapshot(coreSecretGVK, tlsSecret2(s.ns).ObjectMeta) // Assert that we have traffic working on VS 1 but failed traffic on VS 2. s.assertEventualResponse(vs1.GetName(), expectedHealthyResponse1) @@ -201,6 +214,7 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can delete vs manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs.ObjectMeta) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can delete tls secret manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) @@ -210,9 +224,7 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsFailsWithoutOneWayTls() { err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can apply tls secret manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecretWithCa(s.ns)) - // TODO(jbohanon) remove this sleep by figuring out why the `EventuallyObjectsExist` - // is not sufficient to get the VS through validation. Stale snapshots? - time.Sleep(time.Second * 5) // 2 seconds consistently worked on local; 2.5x that to prevent flakes + s.eventuallyInSnapshot(coreSecretGVK, tlsSecretWithCa(s.ns).ObjectMeta) err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithoutOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, vsWithoutOneWay(s.ns)) @@ -230,6 +242,7 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsWorksWithOneWayTls() { err := s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.vsWithOneWay, "-n", s.ns) s.NoError(err, "can delete vs manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, vs) + s.eventuallyNotInSnapshot(gatewayv1.VirtualServiceGVK, vs.ObjectMeta) err = s.testInstallation.Actions.Kubectl().Delete(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can delete tls secret manifest file") s.testInstallation.Assertions.EventuallyObjectsNotExist(s.ctx, tlsSecretWithCa(s.ns)) @@ -238,6 +251,8 @@ func (s *serverTlsTestingSuite) TestOneWayServerTlsWorksWithOneWayTls() { // ordering here matters if strict validation enabled err := s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.tlsSecretWithCa) s.NoError(err, "can apply tls secret manifest file") + s.testInstallation.Assertions.EventuallyObjectsExist(s.ctx, tlsSecretWithCa(s.ns)) + s.eventuallyInSnapshot(coreSecretGVK, tlsSecretWithCa(s.ns).ObjectMeta) err = s.testInstallation.Actions.Kubectl().Apply(s.ctx, s.vsWithOneWay, "-n", s.ns) s.NoError(err, "can apply vs manifest file") @@ -304,3 +319,24 @@ func (s *serverTlsTestingSuite) assertEventualError(hostHeaderValue string, code curlOptions(s.ns, hostHeaderValue), code) } + +func (s *serverTlsTestingSuite) eventuallyInSnapshot(gvk schema.GroupVersionKind, meta metav1.ObjectMeta) { + s.testInstallation.Assertions.AssertGlooAdminApi( + s.ctx, + metav1.ObjectMeta{ + Name: kubeutils.GlooDeploymentName, + Namespace: s.testInstallation.Metadata.InstallNamespace, + }, + s.testInstallation.Assertions.InputSnapshotContainsElement(gvk, meta), + ) +} +func (s *serverTlsTestingSuite) eventuallyNotInSnapshot(gvk schema.GroupVersionKind, meta metav1.ObjectMeta) { + s.testInstallation.Assertions.AssertGlooAdminApi( + s.ctx, + metav1.ObjectMeta{ + Name: kubeutils.GlooDeploymentName, + Namespace: s.testInstallation.Metadata.InstallNamespace, + }, + s.testInstallation.Assertions.InputSnapshotDoesNotContainElement(gvk, meta), + ) +} diff --git a/test/kubernetes/e2e/features/server_tls/types.go b/test/kubernetes/e2e/features/server_tls/types.go index 24ef42e58ef..9096d2e25e2 100644 --- a/test/kubernetes/e2e/features/server_tls/types.go +++ b/test/kubernetes/e2e/features/server_tls/types.go @@ -12,6 +12,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) var ( @@ -106,6 +107,12 @@ var ( StatusCode: http.StatusOK, Body: gomega.ContainSubstring("success from vs-with-oneway"), } + + coreSecretGVK = schema.GroupVersionKind{ + Version: "v1", + Group: "", + Kind: "Secret", + } ) const ( diff --git a/test/kubernetes/e2e/features/validation/README.md b/test/kubernetes/e2e/features/validation/README.md index 19236f598a2..e2039e36503 100644 --- a/test/kubernetes/e2e/features/validation/README.md +++ b/test/kubernetes/e2e/features/validation/README.md @@ -11,6 +11,7 @@ This includes values: |-----------------------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `alwaysAccept` | bool | Always accept resources even if validation produced an error. Validation will still log the error and increment the validation.gateway.solo.io/resources_rejected stat. Currently defaults to true - must be set to `false` to prevent writing invalid resources to storage. | | `allowWarnings` | bool | Accept resources if validation produced a warning (defaults to true). By setting to false, this means that validation will start rejecting resources that would result in warnings, rather than just those that would result in errors. Note that this setting has no impact on Kubernetes Gateway API validation, as warnings will always be allowed in that context. | +| `warnMissingTlsSecret` | bool | Treat a missing TLS secret referenced by an SslConfig or UpstreamSslConfig as a warning instead of error (defaults to true). By setting to false, this means that Gloo will start assigning errors to proxies generated from VirtualService and Upstream resources that reference a non-existent TLS secret, causing validation to fail. | | `warnRouteShortCircuiting` | bool | Write a warning to route resources if validation produced a route ordering warning (defaults to false). By setting to true, this means that Gloo will start assigning warnings to resources that would result in route short-circuiting within a virtual host, for example: - prefix routes that make later routes unreachable - regex routes that make later routes unreachable - duplicate matchers. | | `disableTransformationValidation` | bool | By default gloo will attempt to validate transformations by calling out to a local envoy binary in `validate` mode. Calling this local envoy binary can become slow when done many times during a single validation. Setting this to true will stop gloo from calling out to envoy to validate the transformations, which may speed up the validation time considerably, but may also cause the transformation config to fail after being sent to envoy. When disabling this, ensure that your transformations are valid prior to applying them. | | `serverEnabled` | bool | By providing the validation field (parent of this object) the user is implicitly opting into validation. This field allows the user to opt out of the validation server, while still configuring pre-existing fields such as `warn_route_short_circuiting` and `disable_transformation_validation`. If not included, the validation server will be enabled. | @@ -21,12 +22,12 @@ when a Gateway cannot communicate with Gloo (e.g. Gloo is offline) if the resour #### Test Combinations The below table contains the combinations that are run in the test suite. -| Setup Name | Suites Run | Description | -|-----------------------------------|-------------------------------------------------------|----------------------------------------| -| strict validation | validation_strict_warnings, validation_reject_invalid | allowWarnings=false, alwaysAllow=false | -| allow warnings validation | validation_allow_warnings, validation_reject_invalid | allowWarnings=true, alwaysAllow=false | -| allow all validation | validation_allow_warnings, validation_always_accept | allowWarnings=true, alwaysAllow=true | -| disable transformation validation | transformation_validation_disabled | disableTransformationValidation=true | +| Setup Name | Suites Run | Description | Run Location | +|-----------------------------------|-------------------------------------------------------|-----------------------------------------|--------------------------------------------| +| strict validation | validation_strict_warnings, validation_reject_invalid | allowWarnings=false, alwaysAccept=false | validation_strict_test.go | +| allow warnings validation | validation_allow_warnings, validation_reject_invalid | allowWarnings=true, alwaysAccept=false | edge_gw_test.go | +| allow all validation | validation_allow_warnings, validation_always_accept | allowWarnings=true, alwaysAccept=true | validation_always_accept_test.go | +| disable transformation validation | transformation_validation_disabled | disableTransformationValidation=true | disabled_transformation_validation_test.go | When the validation webhook is enabled, the resource will not be able to be applied to the cluster if it is invalid. -When invalid resources are accepted (alwaysAllow=true), a status should appear on the resource with the correct status state and message. \ No newline at end of file +When invalid resources are accepted (alwaysAccept=true), a status should appear on the resource with the correct status state and message. diff --git a/test/kubernetes/e2e/test.go b/test/kubernetes/e2e/test.go index dea7ab5df16..02d8cc83c7b 100644 --- a/test/kubernetes/e2e/test.go +++ b/test/kubernetes/e2e/test.go @@ -94,7 +94,7 @@ func CreateTestInstallationForCluster( // ResourceClients are only available _after_ installing Gloo Gateway ResourceClients: nil, - // Create an operations provider, and point it to the running installation + // Create an actions provider, and point it to the running installation Actions: actions.NewActionsProvider(). WithClusterContext(clusterContext). WithGlooGatewayContext(glooGatewayContext), diff --git a/test/kubernetes/e2e/tests/edge_gw_tests.go b/test/kubernetes/e2e/tests/edge_gw_tests.go index 9ce4edad9d5..b1fc855924f 100644 --- a/test/kubernetes/e2e/tests/edge_gw_tests.go +++ b/test/kubernetes/e2e/tests/edge_gw_tests.go @@ -7,7 +7,6 @@ import ( "github.com/solo-io/gloo/test/kubernetes/e2e/features/client_tls" "github.com/solo-io/gloo/test/kubernetes/e2e/features/headless_svc" "github.com/solo-io/gloo/test/kubernetes/e2e/features/port_routing" - "github.com/solo-io/gloo/test/kubernetes/e2e/features/server_tls" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_allow_warnings" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_reject_invalid" ) @@ -21,7 +20,6 @@ func EdgeGwSuiteRunner() e2e.SuiteRunner { edgeGwSuiteRunner.Register("ValidationAllowWarnings", validation_allow_warnings.NewTestingSuite) edgeGwSuiteRunner.Register("GlooAdminServer", admin_server.NewTestingSuite) edgeGwSuiteRunner.Register("ClientTls", client_tls.NewTestingSuite) - edgeGwSuiteRunner.Register("ServerTls", server_tls.NewTestingSuite) edgeGwSuiteRunner.Register("BasicRouting", basicrouting.NewBasicEdgeRoutingSuite) return edgeGwSuiteRunner diff --git a/test/kubernetes/e2e/tests/manifests/validation-strict-helm.yaml b/test/kubernetes/e2e/tests/manifests/validation-strict-helm.yaml index 95370fbe3bd..4f9a730c9f9 100644 --- a/test/kubernetes/e2e/tests/manifests/validation-strict-helm.yaml +++ b/test/kubernetes/e2e/tests/manifests/validation-strict-helm.yaml @@ -22,6 +22,8 @@ gateway: failurePolicy: Fail # For "strict" validation mode, fail the validation if webhook server is not available allowWarnings: false # For "strict" validation mode, webhook will also reject warnings alwaysAcceptResources: false + # added to preserve behavior tested by this suite. + warnMissingTlsSecret: false kubeGateway: # This is the field that enables the K8s Gateway Integration in Gloo Gateway enabled: true diff --git a/test/kubernetes/e2e/tests/validation_always_accept_tests.go b/test/kubernetes/e2e/tests/validation_always_accept_tests.go index 65cbac82273..f73e7e8f4ee 100644 --- a/test/kubernetes/e2e/tests/validation_always_accept_tests.go +++ b/test/kubernetes/e2e/tests/validation_always_accept_tests.go @@ -2,6 +2,7 @@ package tests import ( "github.com/solo-io/gloo/test/kubernetes/e2e" + "github.com/solo-io/gloo/test/kubernetes/e2e/features/server_tls" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_allow_warnings" "github.com/solo-io/gloo/test/kubernetes/e2e/features/validation/validation_always_accept" ) @@ -11,6 +12,9 @@ func ValidationAlwaysAcceptSuiteRunner() e2e.SuiteRunner { validationSuiteRunner.Register("ValidationAlwaysAccept", validation_always_accept.NewTestingSuite) validationSuiteRunner.Register("ValidationAllowWarnings", validation_allow_warnings.NewTestingSuite) + // Server TLS tests are run here because they rely on VirtualService resources being applied + // with missing TLS references. This is an error in validation unless warnMissingTlsSecret=true + validationSuiteRunner.Register("ServerTls", server_tls.NewTestingSuite) return validationSuiteRunner } diff --git a/test/kubernetes/testutils/assertions/gloo.go b/test/kubernetes/testutils/assertions/gloo.go index f680cf76e44..87aaad7eec7 100644 --- a/test/kubernetes/testutils/assertions/gloo.go +++ b/test/kubernetes/testutils/assertions/gloo.go @@ -6,11 +6,14 @@ import ( "net" "time" + "github.com/onsi/gomega" . "github.com/onsi/gomega" + "github.com/onsi/gomega/types" "github.com/solo-io/gloo/pkg/utils/glooadminutils/admincli" "github.com/solo-io/gloo/pkg/utils/kubeutils/portforward" "github.com/solo-io/gloo/pkg/utils/requestutils/curl" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) func (p *Provider) AssertGlooAdminApi( @@ -53,3 +56,38 @@ func (p *Provider) AssertGlooAdminApi( adminAssertion(ctx, adminClient) } } + +func containElementMatcher(gvk schema.GroupVersionKind, meta metav1.ObjectMeta) types.GomegaMatcher { + return gomega.ContainElement( + gomega.And( + gomega.HaveKeyWithValue("kind", gomega.Equal(gvk.Kind)), + gomega.HaveKeyWithValue("apiVersion", gomega.Equal(gvk.GroupVersion().String())), + gomega.HaveKeyWithValue("metadata", gomega.And( + gomega.HaveKeyWithValue("name", meta.GetName()), + gomega.HaveKeyWithValue("namespace", meta.GetNamespace()), + )), + ), + ) +} +func (p *Provider) InputSnapshotContainsElement(gvk schema.GroupVersionKind, meta metav1.ObjectMeta) func(ctx context.Context, adminClient *admincli.Client) { + return p.InputSnapshotMatches(containElementMatcher(gvk, meta)) +} + +func (p *Provider) InputSnapshotDoesNotContainElement(gvk schema.GroupVersionKind, meta metav1.ObjectMeta) func(ctx context.Context, adminClient *admincli.Client) { + return p.InputSnapshotMatches(gomega.Not(containElementMatcher(gvk, meta))) +} + +func (p *Provider) InputSnapshotMatches(inputSnapshotMatcher types.GomegaMatcher) func(ctx context.Context, adminClient *admincli.Client) { + return func(ctx context.Context, adminClient *admincli.Client) { + p.Gomega.Eventually(func(g gomega.Gomega) { + inputSnapshot, err := adminClient.GetInputSnapshot(ctx) + g.Expect(err).NotTo(gomega.HaveOccurred(), "error getting input snapshot") + g.Expect(inputSnapshot).NotTo(gomega.BeEmpty(), "objects are returned") + g.Expect(inputSnapshot).To(inputSnapshotMatcher) + }). + WithContext(ctx). + WithTimeout(time.Second * 10). + WithPolling(time.Millisecond * 200). + Should(gomega.Succeed()) + } +} From faa8d41aeb877ed6b64f57f7931577bdc64476e4 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Mon, 19 Aug 2024 14:39:37 -0400 Subject: [PATCH 37/39] remove extra skeleton --- .../e2e/features/server_tls/error_missing_tls_secret/suite.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go diff --git a/test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go b/test/kubernetes/e2e/features/server_tls/error_missing_tls_secret/suite.go deleted file mode 100644 index e69de29bb2d..00000000000 From 383cd6f6a874eda9243f763ba9a3961a3efe9312 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Tue, 20 Aug 2024 09:59:05 -0400 Subject: [PATCH 38/39] rename bool and fix logic --- .../e2e/tests/automtls_istio_edge_api_test.go | 6 +++--- test/kubernetes/e2e/tests/automtls_istio_test.go | 6 +++--- .../tests/disabled_transformation_validation_test.go | 6 +++--- test/kubernetes/e2e/tests/edge_gw_test.go | 6 +++--- test/kubernetes/e2e/tests/glooctl_edge_gw_test.go | 6 +++--- test/kubernetes/e2e/tests/glooctl_istio_inject_test.go | 6 +++--- test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go | 10 +++------- test/kubernetes/e2e/tests/gloomtls_edge_api_test.go | 6 +++--- test/kubernetes/e2e/tests/helm_test.go | 6 +++--- test/kubernetes/e2e/tests/istio_edge_api_test.go | 6 +++--- test/kubernetes/e2e/tests/istio_regression_test.go | 6 +++--- test/kubernetes/e2e/tests/k8s_gw_istio_test.go | 6 +++--- .../k8s_gw_minimal_default_gatewayparameters_test.go | 10 +++------- test/kubernetes/e2e/tests/k8s_gw_no_validation_test.go | 6 +++--- test/kubernetes/e2e/tests/k8s_gw_test.go | 10 +++------- .../e2e/tests/revision_istio_edge_gw_test.go | 6 +++--- .../kubernetes/e2e/tests/revision_istio_k8s_gw_test.go | 6 +++--- .../e2e/tests/validation_always_accept_test.go | 6 +++--- test/kubernetes/e2e/tests/validation_strict_test.go | 6 +++--- 19 files changed, 57 insertions(+), 69 deletions(-) diff --git a/test/kubernetes/e2e/tests/automtls_istio_edge_api_test.go b/test/kubernetes/e2e/tests/automtls_istio_edge_api_test.go index e20d9d77602..e6b6b2ed825 100644 --- a/test/kubernetes/e2e/tests/automtls_istio_edge_api_test.go +++ b/test/kubernetes/e2e/tests/automtls_istio_edge_api_test.go @@ -22,7 +22,7 @@ import ( // the k8s Gateway controller is disabled func TestAutomtlsIstioEdgeApisGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "automtls-istio-edge-api-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "automtls-istio-edge-api-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,14 +38,14 @@ func TestAutomtlsIstioEdgeApisGateway(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/automtls_istio_test.go b/test/kubernetes/e2e/tests/automtls_istio_test.go index 07a46b9dfb2..02db8f7ec58 100644 --- a/test/kubernetes/e2e/tests/automtls_istio_test.go +++ b/test/kubernetes/e2e/tests/automtls_istio_test.go @@ -19,7 +19,7 @@ import ( // TestK8sGatewayIstioAutoMtls is the function which executes a series of tests against a given installation func TestK8sGatewayIstioAutoMtls(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "automtls-istio-k8s-gw-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "automtls-istio-k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -35,14 +35,14 @@ func TestK8sGatewayIstioAutoMtls(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/disabled_transformation_validation_test.go b/test/kubernetes/e2e/tests/disabled_transformation_validation_test.go index 410d923f3f7..19ee8478f00 100644 --- a/test/kubernetes/e2e/tests/disabled_transformation_validation_test.go +++ b/test/kubernetes/e2e/tests/disabled_transformation_validation_test.go @@ -20,7 +20,7 @@ import ( // installation where validation has disableTransformationValidation=true func TestTransformationValidationDisabled(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "disable-transformation-validation-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "disable-transformation-validation-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,14 +32,14 @@ func TestTransformationValidationDisabled(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/edge_gw_test.go b/test/kubernetes/e2e/tests/edge_gw_test.go index 13fe8021ba5..61677fbddf2 100644 --- a/test/kubernetes/e2e/tests/edge_gw_test.go +++ b/test/kubernetes/e2e/tests/edge_gw_test.go @@ -20,7 +20,7 @@ import ( // the k8s Gateway controller is disabled func TestGlooGatewayEdgeGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -31,14 +31,14 @@ func TestGlooGatewayEdgeGateway(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/glooctl_edge_gw_test.go b/test/kubernetes/e2e/tests/glooctl_edge_gw_test.go index e6b011aa0c5..71ce264bab0 100644 --- a/test/kubernetes/e2e/tests/glooctl_edge_gw_test.go +++ b/test/kubernetes/e2e/tests/glooctl_edge_gw_test.go @@ -20,7 +20,7 @@ import ( // installation where the k8s Gateway controller is disabled. func TestGlooctlGlooGatewayEdgeGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-gloo-gateway-edge-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-gloo-gateway-edge-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,14 +32,14 @@ func TestGlooctlGlooGatewayEdgeGateway(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/glooctl_istio_inject_test.go b/test/kubernetes/e2e/tests/glooctl_istio_inject_test.go index ea9e015f73e..d620d3b46c0 100644 --- a/test/kubernetes/e2e/tests/glooctl_istio_inject_test.go +++ b/test/kubernetes/e2e/tests/glooctl_istio_inject_test.go @@ -21,7 +21,7 @@ import ( // the k8s Gateway controller is disabled and glooctl istio inject is used to inject istio into the installation func TestGlooctlIstioInjectEdgeApiGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-edge-api-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-edge-api-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -37,14 +37,14 @@ func TestGlooctlIstioInjectEdgeApiGateway(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go b/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go index fa4a4f326d9..c626b36d6f2 100644 --- a/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go +++ b/test/kubernetes/e2e/tests/glooctl_k8s_gw_test.go @@ -20,7 +20,7 @@ import ( // the k8s gateway controller enabled func TestGlooctlK8sGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-k8s-gw-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "glooctl-k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,20 +32,16 @@ func TestGlooctlK8sGateway(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) - // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { - os.Setenv(testutils.InstallNamespace, installNs) - } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/gloomtls_edge_api_test.go b/test/kubernetes/e2e/tests/gloomtls_edge_api_test.go index 32687fa3183..28896d06210 100644 --- a/test/kubernetes/e2e/tests/gloomtls_edge_api_test.go +++ b/test/kubernetes/e2e/tests/gloomtls_edge_api_test.go @@ -20,7 +20,7 @@ import ( // the k8s Gateway controller is disabled and gloomtls is enabled func TestGloomtlsGatewayEdgeGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "gloo-gateway-edge-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,14 +32,14 @@ func TestGloomtlsGatewayEdgeGateway(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/helm_test.go b/test/kubernetes/e2e/tests/helm_test.go index ff99a761bc4..8be656efd02 100644 --- a/test/kubernetes/e2e/tests/helm_test.go +++ b/test/kubernetes/e2e/tests/helm_test.go @@ -19,7 +19,7 @@ import ( // TestHelm is the function which executes a series of helm tests func TestHelm(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "helm-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "helm-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -31,14 +31,14 @@ func TestHelm(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/istio_edge_api_test.go b/test/kubernetes/e2e/tests/istio_edge_api_test.go index b789006a0f0..3e18f5cb152 100644 --- a/test/kubernetes/e2e/tests/istio_edge_api_test.go +++ b/test/kubernetes/e2e/tests/istio_edge_api_test.go @@ -21,7 +21,7 @@ import ( // the k8s Gateway controller is disabled func TestIstioEdgeApiGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-edge-api-gateway-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-edge-api-gateway-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,14 +38,14 @@ func TestIstioEdgeApiGateway(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/istio_regression_test.go b/test/kubernetes/e2e/tests/istio_regression_test.go index 797cd513949..1fd3c067b9b 100644 --- a/test/kubernetes/e2e/tests/istio_regression_test.go +++ b/test/kubernetes/e2e/tests/istio_regression_test.go @@ -21,7 +21,7 @@ import ( // the k8s Gateway controller is disabled and the deprecated Istio integration values are used to check for regressions func TestIstioRegression(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-regression-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-regression-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,14 +38,14 @@ func TestIstioRegression(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/k8s_gw_istio_test.go b/test/kubernetes/e2e/tests/k8s_gw_istio_test.go index c1dc5b27154..4ac0f9f2678 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_istio_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_istio_test.go @@ -19,7 +19,7 @@ import ( // TestK8sGatewayIstio is the function which executes a series of tests against a given installation func TestK8sGatewayIstio(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-k8s-gw-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -36,14 +36,14 @@ func TestK8sGatewayIstio(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go b/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go index afc8b0a4626..9b02ad077ee 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_minimal_default_gatewayparameters_test.go @@ -20,7 +20,7 @@ import ( // which is expected to have all user-facing options set to null in helm values func TestK8sGatewayMinimalDefaultGatewayParameters(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gateway-minimal-default-gatewayparameters-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gateway-minimal-default-gatewayparameters-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,20 +32,16 @@ func TestK8sGatewayMinimalDefaultGatewayParameters(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) - // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { - os.Setenv(testutils.InstallNamespace, installNs) - } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/k8s_gw_no_validation_test.go b/test/kubernetes/e2e/tests/k8s_gw_no_validation_test.go index 41dbafd05a2..d52eeea42a1 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_no_validation_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_no_validation_test.go @@ -20,7 +20,7 @@ import ( // TestK8sGatewayNoValidation executes tests against a K8s Gateway gloo install with validation disabled func TestK8sGatewayNoValidation(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gw-test-no-validation") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gw-test-no-validation") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -34,14 +34,14 @@ func TestK8sGatewayNoValidation(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/k8s_gw_test.go b/test/kubernetes/e2e/tests/k8s_gw_test.go index 3def17a0699..81a0a85e7b2 100644 --- a/test/kubernetes/e2e/tests/k8s_gw_test.go +++ b/test/kubernetes/e2e/tests/k8s_gw_test.go @@ -19,7 +19,7 @@ import ( // TestK8sGateway is the function which executes a series of tests against a given installation func TestK8sGateway(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gw-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -31,20 +31,16 @@ func TestK8sGateway(t *testing.T) { ) testHelper := e2e.MustTestHelper(ctx, testInstallation) - // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { - os.Setenv(testutils.InstallNamespace, installNs) - } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/revision_istio_edge_gw_test.go b/test/kubernetes/e2e/tests/revision_istio_edge_gw_test.go index 45763fe33cc..09f963bcb71 100644 --- a/test/kubernetes/e2e/tests/revision_istio_edge_gw_test.go +++ b/test/kubernetes/e2e/tests/revision_istio_edge_gw_test.go @@ -21,7 +21,7 @@ import ( // the k8s Gateway controller is disabled and the Istio integration values are enabled with Istio revisions func TestRevisionIstioRegression(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-rev-regression-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-rev-regression-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -38,14 +38,14 @@ func TestRevisionIstioRegression(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/revision_istio_k8s_gw_test.go b/test/kubernetes/e2e/tests/revision_istio_k8s_gw_test.go index 8e20b9fb433..25bde2b2bdb 100644 --- a/test/kubernetes/e2e/tests/revision_istio_k8s_gw_test.go +++ b/test/kubernetes/e2e/tests/revision_istio_k8s_gw_test.go @@ -20,7 +20,7 @@ import ( // k8s gateway enabled and Istio installed with revisions func TestK8sGatewayIstioRevision(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-rev-k8s-gw-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "istio-rev-k8s-gw-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -36,14 +36,14 @@ func TestK8sGatewayIstioRevision(t *testing.T) { } // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/validation_always_accept_test.go b/test/kubernetes/e2e/tests/validation_always_accept_test.go index 2acebeb38de..132f01727a8 100644 --- a/test/kubernetes/e2e/tests/validation_always_accept_test.go +++ b/test/kubernetes/e2e/tests/validation_always_accept_test.go @@ -20,7 +20,7 @@ import ( // installation where validation is set to always accept func TestValidationAlwaysAccept(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-always-accept-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-always-accept-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -31,14 +31,14 @@ func TestValidationAlwaysAccept(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { diff --git a/test/kubernetes/e2e/tests/validation_strict_test.go b/test/kubernetes/e2e/tests/validation_strict_test.go index 8c6ff9fd521..3371aefafad 100644 --- a/test/kubernetes/e2e/tests/validation_strict_test.go +++ b/test/kubernetes/e2e/tests/validation_strict_test.go @@ -20,7 +20,7 @@ import ( // installation where validation is strict (allow_warnings=false) func TestValidationStrict(t *testing.T) { ctx := context.Background() - installNs, overrodeNs := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-strict-test") + installNs, nsEnvPredefined := envutils.LookupOrDefault(testutils.InstallNamespace, "validation-strict-test") testInstallation := e2e.CreateTestInstallation( t, &gloogateway.Context{ @@ -32,14 +32,14 @@ func TestValidationStrict(t *testing.T) { testHelper := e2e.MustTestHelper(ctx, testInstallation) // Set the env to the install namespace if it is not already set - if os.Getenv(testutils.InstallNamespace) == "" { + if !nsEnvPredefined { os.Setenv(testutils.InstallNamespace, installNs) } // We register the cleanup function _before_ we actually perform the installation. // This allows us to uninstall Gloo Gateway, in case the original installation only completed partially t.Cleanup(func() { - if overrodeNs { + if !nsEnvPredefined { os.Unsetenv(testutils.InstallNamespace) } if t.Failed() { From bd91d85588a77aa9f7c5d71d015c96548e48d0b4 Mon Sep 17 00:00:00 2001 From: Jacob Bohanon Date: Tue, 20 Aug 2024 10:49:08 -0400 Subject: [PATCH 39/39] update setting in always accept test --- .../e2e/tests/manifests/validation-always-accept-helm.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml b/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml index 60ee4817e46..553bd96e5c3 100644 --- a/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml +++ b/test/kubernetes/e2e/tests/manifests/validation-always-accept-helm.yaml @@ -20,8 +20,9 @@ gateway: validation: allowWarnings: true alwaysAcceptResources: true - # added to preserve behavior tested by this suite. - warnMissingTlsSecret: false + # this is needed to run the ServerTls tests which verify that with this setting, we + # will not bring down an entire https gateway from a missing tls secret + warnMissingTlsSecret: true kubeGateway: # This is the field that enables the K8s Gateway Integration in Gloo Gateway enabled: true