From 8a5705a09613138937c7d2e1736f5a127dcd43b8 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Tue, 4 Jun 2024 15:44:17 -0700 Subject: [PATCH 1/7] feat: support custom names for generated k8s resources Relates to https://github.com/envoyproxy/gateway/pull/3527 Signed-off-by: Arko Dasgupta --- .../kubernetes/proxy/resource_provider.go | 24 +- .../proxy/resource_provider_test.go | 21 ++ .../proxy/testdata/daemonsets/with-name.yaml | 302 ++++++++++++++++++ .../proxy/testdata/deployments/with-name.yaml | 300 +++++++++++++++++ .../proxy/testdata/services/with-name.yaml | 30 ++ 5 files changed, 674 insertions(+), 3 deletions(-) create mode 100644 internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml create mode 100644 internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml create mode 100644 internal/infrastructure/kubernetes/proxy/testdata/services/with-name.yaml diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index 502620c1cd0..d8a1b99ec29 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -143,13 +143,19 @@ func (r *ResourceRender) Service() (*corev1.Service, error) { }, ObjectMeta: metav1.ObjectMeta{ Namespace: r.Namespace, - Name: r.Name(), Labels: labels, Annotations: annotations, }, Spec: serviceSpec, } + // set name + if envoyServiceConfig.Name != nil { + svc.ObjectMeta.Name = *envoyServiceConfig.Name + } else { + svc.ObjectMeta.Name = r.Name() + } + // apply merge patch to service var err error if svc, err = envoyServiceConfig.ApplyMergePatch(svc); err != nil { @@ -225,7 +231,6 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { }, ObjectMeta: metav1.ObjectMeta{ Namespace: r.Namespace, - Name: r.Name(), Labels: dpLabels, Annotations: dpAnnotations, }, @@ -261,6 +266,13 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { }, } + // set name + if deploymentConfig.Name != nil { + deployment.ObjectMeta.Name = *deploymentConfig.Name + } else { + deployment.ObjectMeta.Name = r.Name() + } + // omit the deployment replicas if HPA is being set if provider.GetEnvoyProxyKubeProvider().EnvoyHpa != nil { deployment.Spec.Replicas = nil @@ -314,7 +326,6 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) { }, ObjectMeta: metav1.ObjectMeta{ Namespace: r.Namespace, - Name: r.Name(), Labels: dsLabels, Annotations: dsAnnotations, }, @@ -331,6 +342,13 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) { }, } + // set name + if daemonSetConfig.Name != nil { + daemonSet.ObjectMeta.Name = *daemonSetConfig.Name + } else { + daemonSet.ObjectMeta.Name = r.Name() + } + // apply merge patch to daemonset if daemonSet, err = daemonSetConfig.ApplyMergePatch(daemonSet); err != nil { return nil, err diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go index e32d4953f42..6eff14d2584 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go @@ -511,6 +511,13 @@ func TestDeployment(t *testing.T) { }, }, }, + { + caseName: "with-name", + infra: newTestInfra(), + deploy: &egv1a1.KubernetesDeploymentSpec{ + Name: ptr.To("custom-deployment-name"), + }, + }, } for _, tc := range cases { t.Run(tc.caseName, func(t *testing.T) { @@ -933,6 +940,13 @@ func TestDaemonSet(t *testing.T) { infra: newTestInfra(), extraArgs: []string{"--key1 val1", "--key2 val2"}, }, + { + caseName: "with-name", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Name: ptr.To("custom-daemonset-name"), + }, + }, } for _, tc := range cases { t.Run(tc.caseName, func(t *testing.T) { @@ -1083,6 +1097,13 @@ func TestService(t *testing.T) { }, }, }, + { + caseName: "with-name", + infra: newTestInfra(), + service: &egv1a1.KubernetesServiceSpec{ + Name: ptr.To("custom-service-name"), + }, + }, } for _, tc := range cases { t.Run(tc.caseName, func(t *testing.T) { diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml new file mode 100644 index 00000000000..3820ca17ead --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml @@ -0,0 +1,302 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: custom-daemonset-name + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml new file mode 100644 index 00000000000..91b38ecbd3d --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml @@ -0,0 +1,300 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: custom-deployment-name + namespace: envoy-gateway-system +spec: + progressDeadlineSeconds: 600 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + strategy: + type: RollingUpdate + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds +status: {} diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/with-name.yaml new file mode 100644 index 00000000000..150fd62b5b5 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/with-name.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: envoy + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: custom-service-name + namespace: envoy-gateway-system +spec: + externalTrafficPolicy: Local + ports: + - name: EnvoyHTTPPort + port: 0 + protocol: TCP + targetPort: 8080 + - name: EnvoyHTTPSPort + port: 0 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: envoy + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + sessionAffinity: None + type: LoadBalancer From c47dae4ef2398af0b8c79c2d6280fff8b43a9d1a Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Wed, 5 Jun 2024 14:43:41 -0700 Subject: [PATCH 2/7] use labels instead of name and ns to get deployment and svc Signed-off-by: Arko Dasgupta --- internal/gatewayapi/helpers.go | 9 ++++++ internal/provider/kubernetes/helpers.go | 12 -------- internal/provider/kubernetes/predicates.go | 34 +++++++++++++--------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index c763d806837..d410489f79b 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -228,6 +228,15 @@ func GatewayClassOwnerLabel(name string) map[string]string { return map[string]string{OwningGatewayClassLabel: name} } +// OwnerLabels returns the owner labels based on the mergeGateways setting +func OwnerLabels(gateway *gwapiv1.Gateway, mergeGateways bool) map[string]string { + if mergeGateways { + return GatewayClassOwnerLabel(gateway.Name) + } + + return GatewayOwnerLabels(gateway.Namespace, gateway.Name) +} + // servicePortToContainerPort translates a service port into an ephemeral // container port. func servicePortToContainerPort(servicePort int32, envoyProxy *egv1a1.EnvoyProxy) int32 { diff --git a/internal/provider/kubernetes/helpers.go b/internal/provider/kubernetes/helpers.go index a59b7604fb5..bc765b2260f 100644 --- a/internal/provider/kubernetes/helpers.go +++ b/internal/provider/kubernetes/helpers.go @@ -18,7 +18,6 @@ import ( egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/gatewayapi" - "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy" ) const ( @@ -145,17 +144,6 @@ func refsSecret(ref *gwapiv1.SecretObjectReference) bool { (ref.Kind == nil || *ref.Kind == gatewayapi.KindSecret) } -// infraName returns expected name for the EnvoyProxy infra resources. -// By default it returns hashed string from {GatewayNamespace}/{GatewayName}, -// but if mergeGateways is set, it will return hashed string of {GatewayClassName}. -func infraName(gateway *gwapiv1.Gateway, merged bool) string { - if merged { - return proxy.ExpectedResourceHashedName(string(gateway.Spec.GatewayClassName)) - } - infraName := fmt.Sprintf("%s/%s", gateway.Namespace, gateway.Name) - return proxy.ExpectedResourceHashedName(infraName) -} - // validateBackendRef validates that ref is a reference to a local Service. // TODO: Add support for: // - Validating weights. diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index eb4c35eff74..3200939800a 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -464,34 +464,40 @@ func (r *gatewayAPIReconciler) validateDeploymentForReconcile(obj client.Object) // envoyDeploymentForGateway returns the Envoy Deployment, returning nil if the Deployment doesn't exist. func (r *gatewayAPIReconciler) envoyDeploymentForGateway(ctx context.Context, gateway *gwapiv1.Gateway) (*appsv1.Deployment, error) { - key := types.NamespacedName{ - Namespace: r.namespace, - Name: infraName(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName))), - } - deployment := new(appsv1.Deployment) - if err := r.client.Get(ctx, key, deployment); err != nil { + var deployments appsv1.DeploymentList + labelSelector := labels.SelectorFromSet(labels.Set(gatewayapi.OwnerLabels(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName))))) + if err := r.client.List(ctx, &deployments, &client.ListOptions{ + LabelSelector: labelSelector, + Namespace: r.namespace, + }); err != nil { if kerrors.IsNotFound(err) { return nil, nil } return nil, err } - return deployment, nil + if len(deployments.Items) == 0 { + return nil, nil + } + return &deployments.Items[0], nil } // envoyServiceForGateway returns the Envoy service, returning nil if the service doesn't exist. func (r *gatewayAPIReconciler) envoyServiceForGateway(ctx context.Context, gateway *gwapiv1.Gateway) (*corev1.Service, error) { - key := types.NamespacedName{ - Namespace: r.namespace, - Name: infraName(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName))), - } - svc := new(corev1.Service) - if err := r.client.Get(ctx, key, svc); err != nil { + var services corev1.ServiceList + labelSelector := labels.SelectorFromSet(labels.Set(gatewayapi.OwnerLabels(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName))))) + if err := r.client.List(ctx, &services, &client.ListOptions{ + LabelSelector: labelSelector, + Namespace: r.namespace, + }); err != nil { if kerrors.IsNotFound(err) { return nil, nil } return nil, err } - return svc, nil + if len(services.Items) == 0 { + return nil, nil + } + return &services.Items[0], nil } // findOwningGateway attempts finds a Gateway using "labels". From 1ec8471859bc27268e20518487f80099fc95824d Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Wed, 5 Jun 2024 16:56:00 -0700 Subject: [PATCH 3/7] fix test Signed-off-by: Arko Dasgupta --- internal/provider/kubernetes/predicates_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go index 431d9638272..c27caa97ef8 100644 --- a/internal/provider/kubernetes/predicates_test.go +++ b/internal/provider/kubernetes/predicates_test.go @@ -24,6 +24,7 @@ import ( "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/envoygateway" "github.com/envoyproxy/gateway/internal/gatewayapi" + "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy" "github.com/envoyproxy/gateway/internal/logging" "github.com/envoyproxy/gateway/internal/provider/kubernetes/test" ) @@ -498,7 +499,7 @@ func TestValidateServiceForReconcile(t *testing.T) { configs: []client.Object{ test.GetGatewayClass("test-gc", v1alpha1.GatewayControllerName, nil), sampleGateway, - test.GetGatewayDeployment(types.NamespacedName{Name: infraName(sampleGateway, false)}, nil), + test.GetGatewayDeployment(types.NamespacedName{Name: proxy.ExpectedResourceHashedName("default/scheduled-status-test")}, nil), }, service: test.GetService(types.NamespacedName{Name: "service"}, map[string]string{ gatewayapi.OwningGatewayNameLabel: "scheduled-status-test", From 46aa837e65846e59238933dc7bf9e61d9de68bf8 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Wed, 5 Jun 2024 17:25:05 -0700 Subject: [PATCH 4/7] fix mergeGateway e2e Signed-off-by: Arko Dasgupta --- internal/gatewayapi/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index d410489f79b..f1b81c4edc8 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -231,7 +231,7 @@ func GatewayClassOwnerLabel(name string) map[string]string { // OwnerLabels returns the owner labels based on the mergeGateways setting func OwnerLabels(gateway *gwapiv1.Gateway, mergeGateways bool) map[string]string { if mergeGateways { - return GatewayClassOwnerLabel(gateway.Name) + return GatewayClassOwnerLabel(gateway.Spec.GatewayClassName) } return GatewayOwnerLabels(gateway.Namespace, gateway.Name) From cd1b726d6f8d83aa580fbd2b6b00238a4f3213e6 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Wed, 5 Jun 2024 17:45:25 -0700 Subject: [PATCH 5/7] build fix Signed-off-by: Arko Dasgupta --- internal/gatewayapi/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index f1b81c4edc8..e2fba715378 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -231,7 +231,7 @@ func GatewayClassOwnerLabel(name string) map[string]string { // OwnerLabels returns the owner labels based on the mergeGateways setting func OwnerLabels(gateway *gwapiv1.Gateway, mergeGateways bool) map[string]string { if mergeGateways { - return GatewayClassOwnerLabel(gateway.Spec.GatewayClassName) + return GatewayClassOwnerLabel(string(gateway.Spec.GatewayClassName)) } return GatewayOwnerLabels(gateway.Namespace, gateway.Name) From a526784813d27c22a1cd577ad0477d01bef90de4 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 6 Jun 2024 16:24:13 -0700 Subject: [PATCH 6/7] fix hpa deployment target Signed-off-by: Arko Dasgupta --- .../kubernetes/proxy/resource_provider.go | 9 +++++++- .../proxy/resource_provider_test.go | 16 +++++++++++++- .../testdata/hpa/with-deployment-name.yaml | 22 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index d8a1b99ec29..36bdf3e0c2d 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -383,7 +383,6 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{ APIVersion: "apps/v1", Kind: "Deployment", - Name: r.Name(), }, MinReplicas: hpaConfig.MinReplicas, MaxReplicas: ptr.Deref(hpaConfig.MaxReplicas, 1), @@ -392,6 +391,14 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod }, } + // set deployment target ref name + deploymentConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDeployment + if deploymentConfig.Name != nil { + hpa.Spec.ScaleTargetRef.Name = *deploymentConfig.Name + } else { + hpa.Spec.ScaleTargetRef.Name = r.Name() + } + return hpa, nil } diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go index 6eff14d2584..36862d4c55c 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go @@ -1228,6 +1228,7 @@ func TestHorizontalPodAutoscaler(t *testing.T) { caseName string infra *ir.Infra hpa *egv1a1.KubernetesHorizontalPodAutoscalerSpec + deploy *egv1a1.KubernetesDeploymentSpec }{ { caseName: "default", @@ -1266,6 +1267,17 @@ func TestHorizontalPodAutoscaler(t *testing.T) { }, }, }, + { + caseName: "with-deployment-name", + infra: newTestInfra(), + hpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{ + MinReplicas: ptr.To[int32](5), + MaxReplicas: ptr.To[int32](10), + }, + deploy: &egv1a1.KubernetesDeploymentSpec{ + Name: ptr.To("custom-deployment-name"), + }, + }, } for _, tc := range cases { @@ -1276,7 +1288,9 @@ func TestHorizontalPodAutoscaler(t *testing.T) { if tc.hpa != nil { provider.Kubernetes.EnvoyHpa = tc.hpa } - + if tc.deploy != nil { + provider.Kubernetes.EnvoyDeployment = tc.deploy + } provider.GetEnvoyProxyKubeProvider() r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) diff --git a/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml new file mode 100644 index 00000000000..afc58a74f95 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml @@ -0,0 +1,22 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + metrics: + - resource: + name: cpu + target: + averageUtilization: 80 + type: Utilization + type: Resource + minReplicas: 5 + maxReplicas: 10 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: custom-deployment-name From 767b10e29222e835cf110da841d2c4c25ce1b95d Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 6 Jun 2024 16:34:10 -0700 Subject: [PATCH 7/7] lint Signed-off-by: Arko Dasgupta --- .../kubernetes/proxy/testdata/hpa/with-deployment-name.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml index afc58a74f95..b421873f681 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/hpa/with-deployment-name.yaml @@ -14,9 +14,9 @@ spec: averageUtilization: 80 type: Utilization type: Resource - minReplicas: 5 - maxReplicas: 10 + minReplicas: 5 + maxReplicas: 10 scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: custom-deployment-name + name: custom-deployment-name