From f50602f8200dbd679d5ee5b6c71ddf11dbb6792c Mon Sep 17 00:00:00 2001 From: Steven Landow Date: Wed, 30 Oct 2024 14:47:50 -0700 Subject: [PATCH 01/11] ggv2: make cluster names parseable --- .../proxy_syncer/kube_gw_translator_syncer.go | 13 +++++- .../gateway2/validation/validator_test.go | 1 + projects/gloo/constants/gloo_gateway.go | 1 + .../pkg/plugins/kubernetes/uds_convert.go | 41 ++++++++++++++++++- projects/gloo/pkg/syncer/setup/translator.go | 3 +- projects/gloo/pkg/translator/clusters.go | 17 +++++--- projects/gloo/pkg/translator/translator.go | 37 ++++++++++++++--- 7 files changed, 98 insertions(+), 15 deletions(-) diff --git a/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go b/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go index 27ce5b39b20..ed6e9c16614 100644 --- a/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go +++ b/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go @@ -8,12 +8,15 @@ import ( "github.com/solo-io/solo-kit/pkg/api/v2/reporter" "istio.io/istio/pkg/kube/krt" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/pkg/utils/settingsutil" "github.com/solo-io/gloo/pkg/utils/statsutils" + "github.com/solo-io/gloo/projects/gloo/constants" "github.com/solo-io/gloo/projects/gloo/pkg/api/grpc/validation" v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" v1snap "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/gloosnapshot" "github.com/solo-io/gloo/projects/gloo/pkg/plugins" + "github.com/solo-io/gloo/projects/gloo/pkg/translator" "github.com/solo-io/gloo/projects/gloo/pkg/xds" "github.com/solo-io/solo-kit/pkg/api/v1/control-plane/cache" @@ -63,7 +66,14 @@ func (s *ProxyTranslator) buildXdsSnapshot( Messages: map[*core.ResourceRef][]string{}, } - xdsSnapshot, reports, proxyReport := s.translator.NewTranslator(ctx, settings).Translate(params, proxy) + legacyClusterNames := envutils.IsEnvTruthy(constants.GlooGatewayKubeStyleClusterNames) + tx := s.translator.NewTranslator( + ctx, + settings, + translator.ForGatewayV2(), + translator.WithParseableClusterNames(!legacyClusterNames), + ) + xdsSnapshot, reports, proxyReport := tx.Translate(params, proxy) // Messages are aggregated during translation, and need to be added to reports for _, messages := range params.Messages { @@ -107,7 +117,6 @@ func (s *ProxyTranslator) syncXds( // a default initial fetch timeout snap.MakeConsistent() s.xdsCache.SetSnapshot(proxyKey, snap) - } func (s *ProxyTranslator) syncStatus( diff --git a/projects/gateway2/validation/validator_test.go b/projects/gateway2/validation/validator_test.go index 65013b2feb6..01656c64576 100644 --- a/projects/gateway2/validation/validator_test.go +++ b/projects/gateway2/validation/validator_test.go @@ -81,6 +81,7 @@ var _ = Describe("Kube Gateway API Policy Validation Helper", func() { settings, pluginRegistry, translator.EnvoyCacheResourcesListToFnvHash, + translator.ForGatewayV2(), ) vc = gloovalidation.ValidatorConfig{ Ctx: context.Background(), diff --git a/projects/gloo/constants/gloo_gateway.go b/projects/gloo/constants/gloo_gateway.go index bbbc7bed0ba..2712e9561ac 100644 --- a/projects/gloo/constants/gloo_gateway.go +++ b/projects/gloo/constants/gloo_gateway.go @@ -2,4 +2,5 @@ package constants const ( GlooGatewayEnableK8sGwControllerEnv = "GG_K8S_GW_CONTROLLER" + GlooGatewayKubeStyleClusterNames = "GG_K8S_GW_LEGACY_CLUSTER_NAMES" ) diff --git a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go index b52048b3ae2..a8e8dff650b 100644 --- a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go +++ b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "reflect" + "strconv" "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes/serviceconverter" "github.com/solo-io/go-utils/contextutils" @@ -20,6 +21,37 @@ import ( corev1 "k8s.io/api/core/v1" ) +// these labels are used to propagate internal data +// on synthetic Gloo resources generated from other Kubernetes +// resources (generally Service). +const ( + // KubeSourceResourceLabel indicates the kind of resource that the synthetic + // resource is based on. + KubeSourceResourceLabel = "~internal.solo.io/kubernetes-source-resource" + // KubeSourceResourceLabel indicates the original name of the resource that + // the synthetic resource is based on. + KubeNameLabel = "~internal.solo.io/kubernetes-name" + // KubeSourceResourceLabel indicates the original namespace of the resource + // that the synthetic resource is based on. + KubeNamespaceLabel = "~internal.solo.io/kubernetes-namespace" + // KubeSourceResourceLabel indicates the service port when applicable. + KubeServicePortLabel = "~internal.solo.io/kubernetes-service-port" +) + +// ClusterNameForKube builds the cluster name based on _internal_ labels. +// All of the kind, name, namespace and port must be provided. +func ClusterNameForKube(us *v1.Upstream) (string, bool) { + labels := us.Metadata.GetLabels() + kind, kok := labels[KubeSourceResourceLabel] + name, nok := labels[KubeNameLabel] + ns, nsok := labels[KubeNamespaceLabel] + port, pok := labels[KubeServicePortLabel] + if !(kok && nok && nsok && pok) { + return "", false + } + return fmt.Sprintf("%s_%s_%s_%s", kind, name, ns, port), true +} + type UpstreamConverter interface { UpstreamsForService(ctx context.Context, svc *corev1.Service) v1.UpstreamList } @@ -48,7 +80,14 @@ func (uc *KubeUpstreamConverter) CreateUpstream(ctx context.Context, svc *corev1 coremeta.ResourceVersion = "" coremeta.Name = UpstreamName(meta.Namespace, meta.Name, port.Port) labels := coremeta.GetLabels() - coremeta.Labels = make(map[string]string) + coremeta.Labels = map[string]string{ + // preserve parts of the source service in a structured way + // so we don't rely on string parsing to recover these + // this is more extensible than relying on casting Spec to Upstream_Kube + KubeNameLabel: meta.Name, + KubeNamespaceLabel: meta.Namespace, + KubeServicePortLabel: strconv.Itoa(int(port.Port)), + } us := &v1.Upstream{ Metadata: coremeta, diff --git a/projects/gloo/pkg/syncer/setup/translator.go b/projects/gloo/pkg/syncer/setup/translator.go index 03a29f82baf..bef76b24430 100644 --- a/projects/gloo/pkg/syncer/setup/translator.go +++ b/projects/gloo/pkg/syncer/setup/translator.go @@ -13,12 +13,13 @@ type TranslatorFactory struct { PluginRegistry plugins.PluginRegistryFactory } -func (tf TranslatorFactory) NewTranslator(ctx context.Context, settings *v1.Settings) translator.Translator { +func (tf TranslatorFactory) NewTranslator(ctx context.Context, settings *v1.Settings, opts ...translator.Option) translator.Translator { return translator.NewTranslatorWithHasher( sslutils.NewSslConfigTranslator(), settings, tf.PluginRegistry(ctx), translator.EnvoyCacheResourcesListToFnvHash, + opts..., ) } diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index 597fbd46125..d5815fb1534 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -20,6 +20,7 @@ import ( v1_options "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/options" "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/ssl" "github.com/solo-io/gloo/projects/gloo/pkg/plugins" + "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" upstream_proxy_protocol "github.com/solo-io/gloo/projects/gloo/pkg/plugins/utils/upstreamproxyprotocol" "github.com/solo-io/gloo/projects/gloo/pkg/utils" "github.com/solo-io/gloo/projects/gloo/pkg/xds" @@ -37,7 +38,6 @@ func (t *translatorInstance) computeClusters( upstreamRefKeyToEndpoints map[string][]*v1.Endpoint, proxy *v1.Proxy, ) ([]*envoy_config_cluster_v3.Cluster, map[*envoy_config_cluster_v3.Cluster]*v1.Upstream) { - ctx, span := trace.StartSpan(params.Ctx, "gloo.translator.computeClusters") defer span.End() params.Ctx = contextutils.WithLogger(ctx, "compute_clusters") @@ -140,15 +140,23 @@ func (t *translatorInstance) initializeCluster( errorList = append(errorList, err) } + clusterName := UpstreamToClusterName(upstream.GetMetadata().Ref()) + // TODO maybe drop the ggv2 flag is redundant + if t.opts.ggv2 && t.opts.parseableClusterNames { + if k8sStyle, ok := kubernetes.ClusterNameForKube(upstream); ok { + clusterName = k8sStyle + } + } + circuitBreakers := t.settings.GetGloo().GetCircuitBreakers() out := &envoy_config_cluster_v3.Cluster{ - Name: UpstreamToClusterName(upstream.GetMetadata().Ref()), + Name: clusterName, Metadata: new(envoy_config_core_v3.Metadata), CircuitBreakers: getCircuitBreakers(upstream.GetCircuitBreakers(), circuitBreakers), LbSubsetConfig: createLbConfig(upstream), HealthChecks: hcConfig, OutlierDetection: detectCfg, - //defaults to Cluster_USE_CONFIGURED_PROTOCOL + // defaults to Cluster_USE_CONFIGURED_PROTOCOL ProtocolSelection: envoy_config_cluster_v3.Cluster_ClusterProtocolSelection(upstream.GetProtocolSelection()), // this field can be overridden by plugins ConnectTimeout: ptypes.DurationProto(ClusterConnectionTimeout), @@ -354,7 +362,6 @@ func getCircuitBreakers(cfgs ...*v1.CircuitBreakerConfig) *envoy_config_cluster_ // it consumes an ordered list of preconnect policies // it returns the first non-nil policy func getPreconnectPolicy(cfgs ...*v1.PreconnectPolicy) (*envoy_config_cluster_v3.Cluster_PreconnectPolicy, error) { - // since we dont want strict reliance on envoy's current api // but still able to map as closely as possible // if not nil then convert the gloo configurations to envoy @@ -380,7 +387,6 @@ func getPreconnectPolicy(cfgs ...*v1.PreconnectPolicy) (*envoy_config_cluster_v3 return nil, errors.New("invalid preconnect policy: " + strings.Join(eStrings, "; ")) } return &envoy_config_cluster_v3.Cluster_PreconnectPolicy{ - PerUpstreamPreconnectRatio: curConfig.GetPerUpstreamPreconnectRatio(), PredictivePreconnectRatio: curConfig.GetPredictivePreconnectRatio(), }, nil @@ -517,7 +523,6 @@ func validateRouteDestinationForValidLambdas( } } } - } // Apply defaults to UpstreamSslConfig diff --git a/projects/gloo/pkg/translator/translator.go b/projects/gloo/pkg/translator/translator.go index 838c28d01bb..a372a32122e 100644 --- a/projects/gloo/pkg/translator/translator.go +++ b/projects/gloo/pkg/translator/translator.go @@ -54,12 +54,11 @@ type ClusterTranslator interface { ) (*envoy_config_cluster_v3.Cluster, []error) } -var ( - _ Translator = new(translatorInstance) -) +var _ Translator = new(translatorInstance) // translatorInstance is the implementation for a Translator used during Gloo translation type translatorInstance struct { + opts translatorOpts lock sync.Mutex pluginRegistry plugins.PluginRegistry settings *v1.Settings @@ -68,8 +67,28 @@ type translatorInstance struct { shouldEnforceNamespaceMatch bool } -func NewDefaultTranslator(settings *v1.Settings, pluginRegistry plugins.PluginRegistry) *translatorInstance { - return NewTranslatorWithHasher(utils.NewSslConfigTranslator(), settings, pluginRegistry, EnvoyCacheResourcesListToFnvHash) +type Option func(o *translatorOpts) + +// Maybe just have a separate New to make this harder to miss... +func ForGatewayV2() Option { + return func(o *translatorOpts) { + o.ggv2 = true + } +} + +func WithParseableClusterNames(enabled bool) Option { + return func(o *translatorOpts) { + o.parseableClusterNames = enabled + } +} + +type translatorOpts struct { + // ggv2 should only be set for translating ggv2 proxies. + ggv2 bool + // parseableClusterNames only applies when GGv2 is also true. + // When set, we will format cluster names for Kubernetes resources + // in a way that is pareseable for telemetry. + parseableClusterNames bool } func NewTranslatorWithHasher( @@ -77,6 +96,7 @@ func NewTranslatorWithHasher( settings *v1.Settings, pluginRegistry plugins.PluginRegistry, hasher func(resources []envoycache.Resource) (uint64, error), + opts ...Option, ) *translatorInstance { shouldEnforceStr := os.Getenv(api_conversion.MatchingNamespaceEnv) shouldEnforceNamespaceMatch := false @@ -87,6 +107,12 @@ func NewTranslatorWithHasher( // TODO: what to do here? } } + + o := translatorOpts{} + for _, opt := range opts { + opt(&o) + } + return &translatorInstance{ lock: sync.Mutex{}, pluginRegistry: pluginRegistry, @@ -94,6 +120,7 @@ func NewTranslatorWithHasher( hasher: hasher, listenerTranslatorFactory: NewListenerSubsystemTranslatorFactory(pluginRegistry, sslConfigTranslator, settings), shouldEnforceNamespaceMatch: shouldEnforceNamespaceMatch, + opts: o, } } From 00cde619c08c0af142bb01f8a1f72c388700055d Mon Sep 17 00:00:00 2001 From: Steven Landow Date: Tue, 5 Nov 2024 10:24:06 -0800 Subject: [PATCH 02/11] Update projects/gloo/pkg/plugins/kubernetes/uds_convert.go Co-authored-by: Nathan Fudenberg --- projects/gloo/pkg/plugins/kubernetes/uds_convert.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go index a8e8dff650b..d82db85049d 100644 --- a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go +++ b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go @@ -41,7 +41,7 @@ const ( // ClusterNameForKube builds the cluster name based on _internal_ labels. // All of the kind, name, namespace and port must be provided. func ClusterNameForKube(us *v1.Upstream) (string, bool) { - labels := us.Metadata.GetLabels() + labels := us.GetMetadata().GetLabels() kind, kok := labels[KubeSourceResourceLabel] name, nok := labels[KubeNameLabel] ns, nsok := labels[KubeNamespaceLabel] From ba3db154d045d205f091e5ac3b5a9a5e4e9bed0c Mon Sep 17 00:00:00 2001 From: Steven Landow Date: Tue, 5 Nov 2024 10:48:52 -0800 Subject: [PATCH 03/11] fix usage in krt eds code --- projects/gateway2/proxy_syncer/endpoints.go | 20 ++++++++++++++----- .../pkg/plugins/kubernetes/uds_convert.go | 9 ++++++--- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/projects/gateway2/proxy_syncer/endpoints.go b/projects/gateway2/proxy_syncer/endpoints.go index a788cac913a..144a014fcac 100644 --- a/projects/gateway2/proxy_syncer/endpoints.go +++ b/projects/gateway2/proxy_syncer/endpoints.go @@ -11,12 +11,14 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/wrapperspb" + "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/projects/gateway2/krtcollections" ggv2utils "github.com/solo-io/gloo/projects/gateway2/utils" "github.com/solo-io/gloo/projects/gloo/constants" v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" glookubev1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/kube/apis/gloo.solo.io/v1" kubeplugin "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/options/kubernetes" + "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" "github.com/solo-io/gloo/projects/gloo/pkg/translator" "github.com/solo-io/go-utils/contextutils" "istio.io/istio/pkg/kube" @@ -34,12 +36,15 @@ type EndpointsSettings struct { EnableAutoMtls bool } -var _ krt.ResourceNamer = EndpointsSettings{} -var _ krt.Equaler[EndpointsSettings] = EndpointsSettings{} +var ( + _ krt.ResourceNamer = EndpointsSettings{} + _ krt.Equaler[EndpointsSettings] = EndpointsSettings{} +) func (p EndpointsSettings) Equals(in EndpointsSettings) bool { return p == in } + func (p EndpointsSettings) ResourceName() string { return "endpoints-settings" } @@ -104,6 +109,7 @@ func NewEndpointsForUpstream(us UpstreamWrapper, logger *zap.Logger) *EndpointsF lbEpsEqualityHash: lbEpsEqualityHash, } } + func hashEndpoints(l krtcollections.PodLocality, emd EndpointWithMd) uint64 { hasher := fnv.New64() hasher.Write([]byte(l.Region)) @@ -263,7 +269,6 @@ func createLbEndpoint(address string, port uint32, podLabels map[string]string, } func addIstioAutomtlsMetadata(metadata *envoy_config_core_v3.Metadata, labels map[string]string, enableAutoMtls bool) *envoy_config_core_v3.Metadata { - const EnvoyTransportSocketMatch = "envoy.transport_socket_match" if enableAutoMtls { if _, ok := labels[constants.IstioTlsModeLabel]; ok { @@ -317,9 +322,14 @@ func findFirstPortInEndpointSubsets(subset corev1.EndpointSubset, singlePortServ return port } -// TODO: use exported version from translator? func getEndpointClusterName(upstream *v1.Upstream) string { - clusterName := translator.UpstreamToClusterName(upstream.GetMetadata().Ref()) + // TODO it would be nice to avoid duplicating the env logic + legacyClusterNames := envutils.IsEnvTruthy(constants.GlooGatewayKubeStyleClusterNames) + clusterName, ok := kubernetes.ClusterNameForKube(upstream) + if !ok || legacyClusterNames { + clusterName = translator.UpstreamToClusterName(upstream.GetMetadata().Ref()) + } + endpointClusterName, err := translator.GetEndpointClusterName(clusterName, upstream) if err != nil { panic(err) diff --git a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go index d82db85049d..3d657e974b5 100644 --- a/projects/gloo/pkg/plugins/kubernetes/uds_convert.go +++ b/projects/gloo/pkg/plugins/kubernetes/uds_convert.go @@ -24,6 +24,8 @@ import ( // these labels are used to propagate internal data // on synthetic Gloo resources generated from other Kubernetes // resources (generally Service). +// The `~` is an invalid character that prevents these labels from ending up +// on actual Kubernetes resources. const ( // KubeSourceResourceLabel indicates the kind of resource that the synthetic // resource is based on. @@ -84,9 +86,10 @@ func (uc *KubeUpstreamConverter) CreateUpstream(ctx context.Context, svc *corev1 // preserve parts of the source service in a structured way // so we don't rely on string parsing to recover these // this is more extensible than relying on casting Spec to Upstream_Kube - KubeNameLabel: meta.Name, - KubeNamespaceLabel: meta.Namespace, - KubeServicePortLabel: strconv.Itoa(int(port.Port)), + KubeSourceResourceLabel: "kube-svc", + KubeNameLabel: meta.Name, + KubeNamespaceLabel: meta.Namespace, + KubeServicePortLabel: strconv.Itoa(int(port.Port)), } us := &v1.Upstream{ From 2669e0e7b2e1e3d9dcd8e64cc778ea412520238c Mon Sep 17 00:00:00 2001 From: Steven Landow Date: Tue, 5 Nov 2024 10:56:46 -0800 Subject: [PATCH 04/11] consolidate usage of env var --- projects/gateway2/proxy_syncer/endpoints.go | 10 +--------- .../proxy_syncer/kube_gw_translator_syncer.go | 6 +----- .../gateway2/validation/validator_test.go | 2 +- projects/gloo/pkg/translator/clusters.go | 11 +++------- projects/gloo/pkg/translator/translator.go | 19 ++++-------------- projects/gloo/pkg/translator/utils.go | 20 ++++++++++++++----- 6 files changed, 25 insertions(+), 43 deletions(-) diff --git a/projects/gateway2/proxy_syncer/endpoints.go b/projects/gateway2/proxy_syncer/endpoints.go index 144a014fcac..d69a63a0889 100644 --- a/projects/gateway2/proxy_syncer/endpoints.go +++ b/projects/gateway2/proxy_syncer/endpoints.go @@ -11,14 +11,12 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/wrapperspb" - "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/projects/gateway2/krtcollections" ggv2utils "github.com/solo-io/gloo/projects/gateway2/utils" "github.com/solo-io/gloo/projects/gloo/constants" v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" glookubev1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/kube/apis/gloo.solo.io/v1" kubeplugin "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/options/kubernetes" - "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" "github.com/solo-io/gloo/projects/gloo/pkg/translator" "github.com/solo-io/go-utils/contextutils" "istio.io/istio/pkg/kube" @@ -323,13 +321,7 @@ func findFirstPortInEndpointSubsets(subset corev1.EndpointSubset, singlePortServ } func getEndpointClusterName(upstream *v1.Upstream) string { - // TODO it would be nice to avoid duplicating the env logic - legacyClusterNames := envutils.IsEnvTruthy(constants.GlooGatewayKubeStyleClusterNames) - clusterName, ok := kubernetes.ClusterNameForKube(upstream) - if !ok || legacyClusterNames { - clusterName = translator.UpstreamToClusterName(upstream.GetMetadata().Ref()) - } - + clusterName := translator.KubeGatewayUpstreamToClusterName(upstream) endpointClusterName, err := translator.GetEndpointClusterName(clusterName, upstream) if err != nil { panic(err) diff --git a/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go b/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go index ed6e9c16614..a7d88a40c21 100644 --- a/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go +++ b/projects/gateway2/proxy_syncer/kube_gw_translator_syncer.go @@ -8,10 +8,8 @@ import ( "github.com/solo-io/solo-kit/pkg/api/v2/reporter" "istio.io/istio/pkg/kube/krt" - "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/pkg/utils/settingsutil" "github.com/solo-io/gloo/pkg/utils/statsutils" - "github.com/solo-io/gloo/projects/gloo/constants" "github.com/solo-io/gloo/projects/gloo/pkg/api/grpc/validation" v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" v1snap "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/gloosnapshot" @@ -66,12 +64,10 @@ func (s *ProxyTranslator) buildXdsSnapshot( Messages: map[*core.ResourceRef][]string{}, } - legacyClusterNames := envutils.IsEnvTruthy(constants.GlooGatewayKubeStyleClusterNames) tx := s.translator.NewTranslator( ctx, settings, - translator.ForGatewayV2(), - translator.WithParseableClusterNames(!legacyClusterNames), + translator.ForKubeGatewayAPI(), ) xdsSnapshot, reports, proxyReport := tx.Translate(params, proxy) diff --git a/projects/gateway2/validation/validator_test.go b/projects/gateway2/validation/validator_test.go index 01656c64576..a0e1fabd2e3 100644 --- a/projects/gateway2/validation/validator_test.go +++ b/projects/gateway2/validation/validator_test.go @@ -81,7 +81,7 @@ var _ = Describe("Kube Gateway API Policy Validation Helper", func() { settings, pluginRegistry, translator.EnvoyCacheResourcesListToFnvHash, - translator.ForGatewayV2(), + translator.ForKubeGatewayAPI(), ) vc = gloovalidation.ValidatorConfig{ Ctx: context.Background(), diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index d5815fb1534..630231874f8 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -1,12 +1,11 @@ package translator import ( + "errors" "fmt" "strings" "time" - "errors" - envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" @@ -20,7 +19,6 @@ import ( v1_options "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/options" "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/ssl" "github.com/solo-io/gloo/projects/gloo/pkg/plugins" - "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" upstream_proxy_protocol "github.com/solo-io/gloo/projects/gloo/pkg/plugins/utils/upstreamproxyprotocol" "github.com/solo-io/gloo/projects/gloo/pkg/utils" "github.com/solo-io/gloo/projects/gloo/pkg/xds" @@ -141,11 +139,8 @@ func (t *translatorInstance) initializeCluster( } clusterName := UpstreamToClusterName(upstream.GetMetadata().Ref()) - // TODO maybe drop the ggv2 flag is redundant - if t.opts.ggv2 && t.opts.parseableClusterNames { - if k8sStyle, ok := kubernetes.ClusterNameForKube(upstream); ok { - clusterName = k8sStyle - } + if t.opts.kubeGatewayAPI { + clusterName = KubeGatewayUpstreamToClusterName(upstream) } circuitBreakers := t.settings.GetGloo().GetCircuitBreakers() diff --git a/projects/gloo/pkg/translator/translator.go b/projects/gloo/pkg/translator/translator.go index a372a32122e..aeb1fd54200 100644 --- a/projects/gloo/pkg/translator/translator.go +++ b/projects/gloo/pkg/translator/translator.go @@ -69,26 +69,15 @@ type translatorInstance struct { type Option func(o *translatorOpts) -// Maybe just have a separate New to make this harder to miss... -func ForGatewayV2() Option { +func ForKubeGatewayAPI() Option { return func(o *translatorOpts) { - o.ggv2 = true - } -} - -func WithParseableClusterNames(enabled bool) Option { - return func(o *translatorOpts) { - o.parseableClusterNames = enabled + o.kubeGatewayAPI = true } } type translatorOpts struct { - // ggv2 should only be set for translating ggv2 proxies. - ggv2 bool - // parseableClusterNames only applies when GGv2 is also true. - // When set, we will format cluster names for Kubernetes resources - // in a way that is pareseable for telemetry. - parseableClusterNames bool + // kubeGatewayAPI should only be set for translating kubeGatewayAPI proxies. + kubeGatewayAPI bool } func NewTranslatorWithHasher( diff --git a/projects/gloo/pkg/translator/utils.go b/projects/gloo/pkg/translator/utils.go index 27a5914bff7..a5d67a9dff4 100644 --- a/projects/gloo/pkg/translator/utils.go +++ b/projects/gloo/pkg/translator/utils.go @@ -12,13 +12,27 @@ import ( "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" + "github.com/solo-io/gloo/pkg/utils/envutils" + "github.com/solo-io/gloo/projects/gloo/constants" + "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" + "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" "github.com/solo-io/gloo/projects/gloo/pkg/utils" "github.com/solo-io/solo-kit/pkg/api/v1/resources/core" ) // returns the name of the cluster created for a given upstream -func UpstreamToClusterName(upstream *core.ResourceRef) string { +// used only for kube gateway api (aka ggv2) proxies. +func KubeGatewayUpstreamToClusterName(upstream *v1.Upstream) string { + legacyClusterNames := envutils.IsEnvTruthy(constants.GlooGatewayKubeStyleClusterNames) + clusterName, ok := kubernetes.ClusterNameForKube(upstream) + if !ok || legacyClusterNames { + return UpstreamToClusterName(upstream.GetMetadata().Ref()) + } + return clusterName +} +// returns the name of the cluster created for a given upstream +func UpstreamToClusterName(upstream *core.ResourceRef) string { // For non-namespaced resources, return only name if upstream.GetNamespace() == "" { return upstream.GetName() @@ -30,7 +44,6 @@ func UpstreamToClusterName(upstream *core.ResourceRef) string { // returns the ref of the upstream for a given cluster func ClusterToUpstreamRef(cluster string) (*core.ResourceRef, error) { - split := strings.Split(cluster, "_") if len(split) > 2 || len(split) < 1 { return nil, errors.Errorf("unable to convert cluster %s back to upstream ref", cluster) @@ -47,7 +60,6 @@ func ClusterToUpstreamRef(cluster string) (*core.ResourceRef, error) { } func NewFilterWithTypedConfig(name string, config proto.Message) (*envoy_config_listener_v3.Filter, error) { - s := &envoy_config_listener_v3.Filter{ Name: name, } @@ -107,14 +119,12 @@ func IsIpv4Address(bindAddress string) (validIpv4, strictIPv4 bool, err error) { if bindIP == nil { // If bindAddress is not a valid textual representation of an IP address return false, false, errors.Errorf("bindAddress %s is not a valid IP address", bindAddress) - } else if bindIP.To4() == nil { // If bindIP is not an IPv4 address, To4 returns nil. // so this is not an acceptable ipv4 return false, false, nil } return true, isPureIPv4Address(bindAddress), nil - } // isPureIPv4Address checks the string to see if it is From 89015c742a17c501bbad4c629f6da59c2d586ea2 Mon Sep 17 00:00:00 2001 From: nfuden Date: Wed, 6 Nov 2024 12:23:50 -0500 Subject: [PATCH 05/11] changelog: add based on pr --- changelog/v1.18.0-beta33/cluster_names.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/v1.18.0-beta33/cluster_names.yaml diff --git a/changelog/v1.18.0-beta33/cluster_names.yaml b/changelog/v1.18.0-beta33/cluster_names.yaml new file mode 100644 index 00000000000..7be47c3358d --- /dev/null +++ b/changelog/v1.18.0-beta33/cluster_names.yaml @@ -0,0 +1,7 @@ +changelog: + - type: NEW_FEATURE + issueLink: https://github.com/solo-io/solo-projects/issues/7105 + resolvesIssue: false + description: >- + Kubernetes gateway cluster names for kubernetes services will have a new more parsable format. + This behavior for kubernetes gateway can be reverted for now via GG_K8S_GW_LEGACY_CLUSTER_NAMES. \ No newline at end of file From 812d1ecfa1acf4e9d17b6de00d5b2af35a2e7720 Mon Sep 17 00:00:00 2001 From: nfuden Date: Wed, 6 Nov 2024 12:24:00 -0500 Subject: [PATCH 06/11] static checks linter --- projects/gloo/pkg/translator/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gloo/pkg/translator/utils.go b/projects/gloo/pkg/translator/utils.go index a5d67a9dff4..e394bb83637 100644 --- a/projects/gloo/pkg/translator/utils.go +++ b/projects/gloo/pkg/translator/utils.go @@ -14,7 +14,7 @@ import ( "github.com/golang/protobuf/ptypes/any" "github.com/solo-io/gloo/pkg/utils/envutils" "github.com/solo-io/gloo/projects/gloo/constants" - "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" + v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1" "github.com/solo-io/gloo/projects/gloo/pkg/plugins/kubernetes" "github.com/solo-io/gloo/projects/gloo/pkg/utils" "github.com/solo-io/solo-kit/pkg/api/v1/resources/core" From 9bc63c4130ab40cc0c80b5db2b056cbedf428d55 Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 6 Nov 2024 18:23:22 +0000 Subject: [PATCH 07/11] Adding changelog file to new location --- changelog/v1.18.0-beta34/cluster_names.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/v1.18.0-beta34/cluster_names.yaml diff --git a/changelog/v1.18.0-beta34/cluster_names.yaml b/changelog/v1.18.0-beta34/cluster_names.yaml new file mode 100644 index 00000000000..7be47c3358d --- /dev/null +++ b/changelog/v1.18.0-beta34/cluster_names.yaml @@ -0,0 +1,7 @@ +changelog: + - type: NEW_FEATURE + issueLink: https://github.com/solo-io/solo-projects/issues/7105 + resolvesIssue: false + description: >- + Kubernetes gateway cluster names for kubernetes services will have a new more parsable format. + This behavior for kubernetes gateway can be reverted for now via GG_K8S_GW_LEGACY_CLUSTER_NAMES. \ No newline at end of file From 860037a3413dad83e2cf488cf45e102dee8a2f1c Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 6 Nov 2024 18:23:23 +0000 Subject: [PATCH 08/11] Deleting changelog file from old location --- changelog/v1.18.0-beta33/cluster_names.yaml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 changelog/v1.18.0-beta33/cluster_names.yaml diff --git a/changelog/v1.18.0-beta33/cluster_names.yaml b/changelog/v1.18.0-beta33/cluster_names.yaml deleted file mode 100644 index 7be47c3358d..00000000000 --- a/changelog/v1.18.0-beta33/cluster_names.yaml +++ /dev/null @@ -1,7 +0,0 @@ -changelog: - - type: NEW_FEATURE - issueLink: https://github.com/solo-io/solo-projects/issues/7105 - resolvesIssue: false - description: >- - Kubernetes gateway cluster names for kubernetes services will have a new more parsable format. - This behavior for kubernetes gateway can be reverted for now via GG_K8S_GW_LEGACY_CLUSTER_NAMES. \ No newline at end of file From bc9bdbc0ad028d396ef8ab034009b85942d8b3a8 Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 13 Nov 2024 12:59:40 +0000 Subject: [PATCH 09/11] Adding changelog file to new location --- changelog/v1.18.0-beta35/cluster_names.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/v1.18.0-beta35/cluster_names.yaml diff --git a/changelog/v1.18.0-beta35/cluster_names.yaml b/changelog/v1.18.0-beta35/cluster_names.yaml new file mode 100644 index 00000000000..7be47c3358d --- /dev/null +++ b/changelog/v1.18.0-beta35/cluster_names.yaml @@ -0,0 +1,7 @@ +changelog: + - type: NEW_FEATURE + issueLink: https://github.com/solo-io/solo-projects/issues/7105 + resolvesIssue: false + description: >- + Kubernetes gateway cluster names for kubernetes services will have a new more parsable format. + This behavior for kubernetes gateway can be reverted for now via GG_K8S_GW_LEGACY_CLUSTER_NAMES. \ No newline at end of file From 3222c3f7d460b203e4229af16c62a08fd2ac3949 Mon Sep 17 00:00:00 2001 From: changelog-bot Date: Wed, 13 Nov 2024 12:59:40 +0000 Subject: [PATCH 10/11] Deleting changelog file from old location --- changelog/v1.18.0-beta34/cluster_names.yaml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 changelog/v1.18.0-beta34/cluster_names.yaml diff --git a/changelog/v1.18.0-beta34/cluster_names.yaml b/changelog/v1.18.0-beta34/cluster_names.yaml deleted file mode 100644 index 7be47c3358d..00000000000 --- a/changelog/v1.18.0-beta34/cluster_names.yaml +++ /dev/null @@ -1,7 +0,0 @@ -changelog: - - type: NEW_FEATURE - issueLink: https://github.com/solo-io/solo-projects/issues/7105 - resolvesIssue: false - description: >- - Kubernetes gateway cluster names for kubernetes services will have a new more parsable format. - This behavior for kubernetes gateway can be reverted for now via GG_K8S_GW_LEGACY_CLUSTER_NAMES. \ No newline at end of file From 9b1ad1a03e914d176ac11f1df4f5d76e5af623bb Mon Sep 17 00:00:00 2001 From: Jenny Shu Date: Wed, 13 Nov 2024 10:46:03 -0500 Subject: [PATCH 11/11] typos --- projects/gateway2/krtcollections/endpoints.go | 9 +-------- projects/gloo/pkg/translator/clusters.go | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/projects/gateway2/krtcollections/endpoints.go b/projects/gateway2/krtcollections/endpoints.go index 6bff952034d..c5a3716fca9 100644 --- a/projects/gateway2/krtcollections/endpoints.go +++ b/projects/gateway2/krtcollections/endpoints.go @@ -226,12 +226,6 @@ func transformK8sEndpoints(ctx context.Context, inputs EndpointsInputs) func(kct return nil } - if len(endpointSlices) == 0 { - warnsToLog = append(warnsToLog, fmt.Sprintf("EndpointSlices not found for service %v/%v", svcNs, svcName)) - logger.Debug("EndpointSlices not found for service") - return nil - } - // Initialize the returned EndpointsForUpstream settings := krt.FetchOne(kctx, inputs.EndpointsSettings.AsCollection()) enableAutoMtls := settings.EnableAutoMtls @@ -397,8 +391,7 @@ func findPortInEndpointSlice(endpointSlice *discoveryv1.EndpointSlice, singlePor // TODO: use exported version from translator? func GetEndpointClusterName(upstream *v1.Upstream) string { - clusterName := translator.UpstreamToClusterName(upstream.GetMetadata().Ref()) - // clusterName := translator.KubeGatewayUpstreamToClusterName(upstream) + clusterName := translator.KubeGatewayUpstreamToClusterName(upstream) endpointClusterName, err := translator.GetEndpointClusterName(clusterName, upstream) if err != nil { panic(err) diff --git a/projects/gloo/pkg/translator/clusters.go b/projects/gloo/pkg/translator/clusters.go index 630231874f8..ed5ae3ab4ec 100644 --- a/projects/gloo/pkg/translator/clusters.go +++ b/projects/gloo/pkg/translator/clusters.go @@ -69,7 +69,7 @@ func (t *translatorInstance) computeClusters( } // This function is intented to be used when translating a single upstream outside of the context of a full snapshot. -// This happens in GGv2 krt implementation. +// This happens in the kube gateway krt implementation. func (t *translatorInstance) TranslateCluster( params plugins.Params, upstream *v1.Upstream,