diff --git a/Dockerfile b/Dockerfile index bc055c52a..eac3cf1da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM --platform=$BUILDPLATFORM golang:1.25.3-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.4-alpine AS builder ARG TARGETOS ARG TARGETARCH ARG GO_BUILD_TAGS diff --git a/api/v1alpha2/experimental.go b/api/v1alpha2/experimental.go index 2880c9146..dd0d49df1 100644 --- a/api/v1alpha2/experimental.go +++ b/api/v1alpha2/experimental.go @@ -2,6 +2,10 @@ package v1alpha2 type Experimental struct { PilotFeatures `json:"pilot"` + + // Enables the Dual Stack support + // +kubebuilder:validation:Optional + EnableDualStack *bool `json:"enableDualStack,omitempty"` } type PilotFeatures struct { diff --git a/api/v1alpha2/istio_merge.go b/api/v1alpha2/istio_merge.go index c09a7bb38..2fd61072b 100644 --- a/api/v1alpha2/istio_merge.go +++ b/api/v1alpha2/istio_merge.go @@ -3,7 +3,6 @@ package v1alpha2 import ( "encoding/json" "github.com/golang/protobuf/ptypes/duration" - "istio.io/istio/operator/pkg/values" "istio.io/istio/pkg/util/protomarshal" appsv1 "k8s.io/api/apps/v1" @@ -77,6 +76,17 @@ func (m *meshConfigBuilder) BuildPrometheusMergeConfig(prometheusMerge bool) *me return m } +func (m *meshConfigBuilder) BuildDualStackConfig(enableDualStack bool) *meshConfigBuilder { + if enableDualStack { + err := m.c.SetPath("defaultConfig.proxyMetadata.ISTIO_DUAL_STACK", "true") + if err != nil { + return nil + } + } + + return m +} + func (m *meshConfigBuilder) AddProxyMetadata(key, value string) (*meshConfigBuilder, error) { err := m.c.SetPath("defaultConfig.proxyMetadata."+key, value) if err != nil { @@ -183,15 +193,23 @@ func (i *Istio) mergeConfig(op iopv1alpha1.IstioOperator) (iopv1alpha1.IstioOper return op, err } + dualStackEnabled := i.Spec.Experimental != nil && i.Spec.Experimental.EnableDualStack != nil && *i.Spec.Experimental.EnableDualStack + newMeshConfig := mcb. BuildNumTrustedProxies(i.Spec.Config.NumTrustedProxies). BuildExternalAuthorizerConfiguration(i.Spec.Config.Authorizers). BuildPrometheusMergeConfig(i.Spec.Config.Telemetry.Metrics.PrometheusMerge). + BuildDualStackConfig(dualStackEnabled). Build() op.Spec.MeshConfig = newMeshConfig op = applyGatewayExternalTrafficPolicy(op, i) + + op, err = applyDualStack(op, i) + if err != nil { + return op, err + } return op, nil } @@ -228,6 +246,48 @@ func applyGatewayExternalTrafficPolicy(op iopv1alpha1.IstioOperator, i *Istio) i return op } +func applyDualStack(op iopv1alpha1.IstioOperator, i *Istio) (iopv1alpha1.IstioOperator, error) { + if i.Spec.Experimental != nil && i.Spec.Experimental.EnableDualStack != nil && *i.Spec.Experimental.EnableDualStack { + return enableDualStack(op, i) + } + return op, nil +} + +func enableDualStack(op iopv1alpha1.IstioOperator, i *Istio) (iopv1alpha1.IstioOperator, error) { + valuesMap, err := values.MapFromObject(op.Spec.Values) + if err != nil { + return op, err + } + + if valuesMap == nil { + valuesMap = make(values.Map) + } + + err = valuesMap.SetPath("pilot.env.ISTIO_DUAL_STACK", "true") + if err != nil { + return iopv1alpha1.IstioOperator{}, err + } + err = valuesMap.SetPath("pilot.ipFamilyPolicy", "RequireDualStack") + if err != nil { + return iopv1alpha1.IstioOperator{}, err + } + err = valuesMap.SetPath("gateways.istio-ingressgateway.ipFamilyPolicy", "RequireDualStack") + if err != nil { + return iopv1alpha1.IstioOperator{}, err + } + err = valuesMap.SetPath("gateways.istio-egressgateway.ipFamilyPolicy", "RequireDualStack") + if err != nil { + return iopv1alpha1.IstioOperator{}, err + } + + op.Spec.Values, err = values.ConvertMap[json.RawMessage](valuesMap) + if err != nil { + return op, err + } + + return op, nil +} + //nolint:gocognit,gocyclo,cyclop,funlen // cognitive complexity 189 of func `(*Istio).mergeResources` is high (> 20), cyclomatic complexity 70 of func `(*Istio).mergeResources` is high (> 30), Function 'mergeResources' has too many statements (129 > 50) TODO: refactor this function func (i *Istio) mergeResources(op iopv1alpha1.IstioOperator) (iopv1alpha1.IstioOperator, error) { if i.Spec.Components == nil { diff --git a/api/v1alpha2/merge_test.go b/api/v1alpha2/merge_test.go index bfe6e2ed9..30b7273be 100644 --- a/api/v1alpha2/merge_test.go +++ b/api/v1alpha2/merge_test.go @@ -664,6 +664,76 @@ var _ = Describe("Merge", func() { }) + It("should set ipFamilyPolicy to RequireDualStack if dualStack is enabled in the Istio CR", func() { + // given + enableDualStack := true + iop := iopv1alpha1.IstioOperator{ + Spec: iopv1alpha1.IstioOperatorSpec{}, + } + istioCR := istiov1alpha2.Istio{Spec: istiov1alpha2.IstioSpec{ + Config: istiov1alpha2.Config{}, + Experimental: &istiov1alpha2.Experimental{ + EnableDualStack: &enableDualStack, + }, + }} + + // when + out, err := istioCR.MergeInto(iop) + + valuesMap, err := values.MapFromObject(out.Spec.Values) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(values.TryGetPathAs[string](valuesMap, "pilot.ipFamilyPolicy")).To(Equal("RequireDualStack")) + Expect(values.TryGetPathAs[string](valuesMap, "gateways.istio-ingressgateway.ipFamilyPolicy")).To(Equal("RequireDualStack")) + Expect(values.TryGetPathAs[string](valuesMap, "gateways.istio-egressgateway.ipFamilyPolicy")).To(Equal("RequireDualStack")) + }) + + It("should set dual stack env for Istio pilot if dualStack is enabled in the Istio CR", func() { + // given + enableDualStack := true + iop := iopv1alpha1.IstioOperator{ + Spec: iopv1alpha1.IstioOperatorSpec{}, + } + istioCR := istiov1alpha2.Istio{Spec: istiov1alpha2.IstioSpec{ + Config: istiov1alpha2.Config{}, + Experimental: &istiov1alpha2.Experimental{ + EnableDualStack: &enableDualStack, + }, + }} + + // when + out, err := istioCR.MergeInto(iop) + + valuesMap, err := values.MapFromObject(out.Spec.Values) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(values.TryGetPathAs[string](valuesMap, "pilot.env.ISTIO_DUAL_STACK")).To(Equal("true")) + }) + + It("should set dual stack in the mesh Config if dualStack is enabled in the Istio CR", func() { + // given + enableDualStack := true + iop := iopv1alpha1.IstioOperator{ + Spec: iopv1alpha1.IstioOperatorSpec{}, + } + istioCR := istiov1alpha2.Istio{Spec: istiov1alpha2.IstioSpec{ + Config: istiov1alpha2.Config{}, + Experimental: &istiov1alpha2.Experimental{ + EnableDualStack: &enableDualStack, + }, + }} + + // when + out, err := istioCR.MergeInto(iop) + + meshConfig, err := values.MapFromObject(out.Spec.MeshConfig) + Expect(err).ShouldNot(HaveOccurred()) + + dualStack, exists := meshConfig.GetPath("defaultConfig.proxyMetadata.ISTIO_DUAL_STACK") + Expect(exists).To(BeTrue()) + Expect(dualStack).To(Equal("true")) + }) + Context("Pilot", func() { Context("When Istio CR has 500m configured for CPU limits", func() { It("should set CPU limits to 500m in IOP", func() { diff --git a/api/v1alpha2/zz_generated.deepcopy.go b/api/v1alpha2/zz_generated.deepcopy.go index 5321b55fc..452cf9fb2 100644 --- a/api/v1alpha2/zz_generated.deepcopy.go +++ b/api/v1alpha2/zz_generated.deepcopy.go @@ -208,6 +208,11 @@ func (in *EgressGateway) DeepCopy() *EgressGateway { func (in *Experimental) DeepCopyInto(out *Experimental) { *out = *in out.PilotFeatures = in.PilotFeatures + if in.EnableDualStack != nil { + in, out := &in.EnableDualStack, &out.EnableDualStack + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Experimental. @@ -393,7 +398,7 @@ func (in *IstioSpec) DeepCopyInto(out *IstioSpec) { if in.Experimental != nil { in, out := &in.Experimental, &out.Experimental *out = new(Experimental) - **out = **in + (*in).DeepCopyInto(*out) } } diff --git a/config/crd/bases/operator.kyma-project.io_istios.yaml b/config/crd/bases/operator.kyma-project.io_istios.yaml index 38be46639..8fa605bd2 100644 --- a/config/crd/bases/operator.kyma-project.io_istios.yaml +++ b/config/crd/bases/operator.kyma-project.io_istios.yaml @@ -1434,6 +1434,9 @@ spec: experimental: description: Defines experimental configuration options. properties: + enableDualStack: + description: Enables the Dual Stack support + type: boolean pilot: properties: enableAlphaGatewayAPI: diff --git a/controllers/istio_controller.go b/controllers/istio_controller.go index 56e8b1fe9..42b366ba4 100644 --- a/controllers/istio_controller.go +++ b/controllers/istio_controller.go @@ -106,6 +106,10 @@ func (r *IstioReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl r.statusHandler.SetCondition(&istioCR, operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonReconcileUnknown)) + if err := r.validate(&istioCR); err != nil { + return ctrl.Result{}, r.statusHandler.UpdateToError(ctx, &istioCR, err) + } + istioImages, imgErr := images.GetImages() if imgErr != nil { return r.terminateReconciliation(ctx, &istioCR, describederrors.NewDescribedError(imgErr, "Unable to get Istio images environments"), @@ -299,9 +303,6 @@ func (r *IstioReconciler) finishReconcile(ctx context.Context, istioCR *operator r.statusHandler.SetCondition(istioCR, operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonReconcileSucceeded)) r.statusHandler.SetCondition(istioCR, operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonIngressTargetingUserResourceNotFound)) - if err := r.validate(istioCR); err != nil { - return ctrl.Result{}, r.statusHandler.UpdateToError(ctx, istioCR, err) - } if err := r.statusHandler.UpdateToReady(ctx, istioCR); err != nil { r.log.Error(err, "Error during updating status to ready") diff --git a/controllers/validate.go b/controllers/validate.go index 1ddd2a0f1..69abd18dd 100644 --- a/controllers/validate.go +++ b/controllers/validate.go @@ -13,9 +13,9 @@ func (r *IstioReconciler) validate(istioCR *operatorv1alpha2.Istio) describederr if istioCR.Spec.Experimental != nil { // user has experimental field applied in their CR // return error with description - r.log.Info("Experimental features are not supported in this image flavour") - return describederrors.NewDescribedError(errors.New("istio CR contains experimental feature"), "Experimental features are not supported in this image flavour"). - SetWarning(). + err := errors.New("istio CR contains experimental feature") + r.log.Error(err, "Experimental features are not supported in this image flavour") + return describederrors.NewDescribedError(err, "Experimental features are not supported in this image flavour"). SetCondition(false) } return nil diff --git a/controllers/validate_test.go b/controllers/validate_test.go index 74ab21a36..2976a9995 100644 --- a/controllers/validate_test.go +++ b/controllers/validate_test.go @@ -19,7 +19,7 @@ import ( ) var _ = Describe("Istio Controller", func() { - It("should set CR status to warning if experimental fields have been defined", func() { + It("should set CR status to error if experimental fields have been defined", func() { // given istioCR := &operatorv1alpha2.Istio{ ObjectMeta: metav1.ObjectMeta{ @@ -70,7 +70,7 @@ var _ = Describe("Istio Controller", func() { err = fakeClient.Get(context.Background(), client.ObjectKeyFromObject(istioCR), &updatedIstioCR) Expect(err).To(Not(HaveOccurred())) - Expect(updatedIstioCR.Status.State).Should(Equal(operatorv1alpha2.Warning)) + Expect(updatedIstioCR.Status.State).Should(Equal(operatorv1alpha2.Error)) Expect(updatedIstioCR.Status.Description).To(ContainSubstring("Experimental features are not supported in this image flavour")) }) }) diff --git a/docs/contributor/adr/0005-suppoert-for-experimental-configuration-parameters-in-istio-cr.md b/docs/contributor/adr/0005-support-for-experimental-configuration-parameters-in-istio-cr.md similarity index 93% rename from docs/contributor/adr/0005-suppoert-for-experimental-configuration-parameters-in-istio-cr.md rename to docs/contributor/adr/0005-support-for-experimental-configuration-parameters-in-istio-cr.md index 8f09c1bdf..805f35633 100644 --- a/docs/contributor/adr/0005-suppoert-for-experimental-configuration-parameters-in-istio-cr.md +++ b/docs/contributor/adr/0005-support-for-experimental-configuration-parameters-in-istio-cr.md @@ -19,7 +19,7 @@ spec: #[...] ``` -The experimental features should be only available to be used with a separately built controller image. Using the experimental features with production image should result in setting the Istio rustom resource to the `Warning` state. +The experimental features should be only available to be used with a separately built controller image. Using the experimental features with production image should result in setting the Istio custom resource to the `Error` state and break the reconciliation to avoid unintended changes. ### SAP BTP, Kyma Runtime In context of SAP BTP, Kyma runtime, experimental features should only be available in the experimental release channel. diff --git a/docs/release-notes/1.23.1.md b/docs/release-notes/1.23.1.md new file mode 100644 index 000000000..10c8d519c --- /dev/null +++ b/docs/release-notes/1.23.1.md @@ -0,0 +1,6 @@ +## New Features + +- We've added dual-stack experimental support. + See [#1700](https://github.com/kyma-project/istio/pull/1700). + +## Fixed Bugs diff --git a/docs/user/04-00-istio-custom-resource.md b/docs/user/04-00-istio-custom-resource.md index 0d7a4a679..9b0bbf07e 100644 --- a/docs/user/04-00-istio-custom-resource.md +++ b/docs/user/04-00-istio-custom-resource.md @@ -50,6 +50,7 @@ This table lists all the possible parameters of Istio CR together with their des | **config.gatewayExternalTrafficPolicy** | string | Defines the external traffic policy for Istio Ingress Gateway Service. Valid configurations are `Local` or `Cluster`. The external traffic policy set to `Local` preserves the client IP in the request but also introduces the risk of unbalanced traffic distribution. | | **config.telemetry.metrics.prometheusMerge** | bool | Enables the [prometheusMerge](https://istio.io/latest/docs/ops/integrations/prometheus/#option-1-metrics-merging) feature from Istio, which merges the application's and Istio's metrics and exposes them together at `:15020/stats/prometheus` for scraping using plain HTTP. Updating the field causes a restart of the Istio sidecar proxies. | | **experimental** | object | Defines additional experimental features that can be enabled in experimental builds. | +| **experimental.enableDualStack** | bool | Enables dual-stack support. | | **experimental.pilot** | object | Defines additional experimental features that can be enabled in Istio pilot component. | | **experimental.pilot.enableAlphaGatewayAPI** | bool | Enables support for alpha Kubernetes Gateway API. | | **experimental.pilot.enableMultiNetworkDiscoverGatewayAPI** | bool | Enables support for multi-network discovery in Kubernetes Gateway API. | diff --git a/internal/clusterconfig/clusterconfig.go b/internal/clusterconfig/clusterconfig.go index f33bdbf23..859f09c36 100644 --- a/internal/clusterconfig/clusterconfig.go +++ b/internal/clusterconfig/clusterconfig.go @@ -140,9 +140,14 @@ const ( loadBalancerNlbTargetType = "instance" loadBalancerTypeAnnotation = "service.beta.kubernetes.io/aws-load-balancer-type" loadBalancerType = "nlb" + loadBalancerDualStackAnnotation = "service.beta.kubernetes.io/aws-load-balancer-ip-address-type" + loadBalancerDualStack = "dualstack" loadBalancerProxyProtocolOpenStackAnnotation = "loadbalancer.openstack.org/proxy-protocol" loadBalancerProxyProtocolOpenStack = "v1" + + istioIngressServiceName = "istio-ingressgateway" + istioIngressNamespace = "istio-system" ) func ShouldUseNLB(ctx context.Context, k8sClient client.Client) (bool, error) { @@ -156,7 +161,7 @@ func ShouldUseNLB(ctx context.Context, k8sClient client.Client) (bool, error) { } var ingressGatewaySvc corev1.Service - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "istio-system", Name: "istio-ingressgateway"}, &ingressGatewaySvc) + err = k8sClient.Get(ctx, client.ObjectKey{Namespace: istioIngressNamespace, Name: istioIngressServiceName}, &ingressGatewaySvc) if err != nil { if errors.IsNotFound(err) { return false, nil @@ -171,6 +176,26 @@ func ShouldUseNLB(ctx context.Context, k8sClient client.Client) (bool, error) { return false, nil } +// IsDualStack checks whether the Ingress service has an IP address type annotation set to 'dualstack' +// This annotation is set automatically by 'gardener-extension-provider-aws' on the Gardener side +// if the cluster infrastructure supports IPv6 +func IsDualStack(ctx context.Context, k8sClient client.Client) (bool, error) { + var ingressGatewaySvc corev1.Service + err := k8sClient.Get(ctx, client.ObjectKey{Namespace: istioIngressNamespace, Name: istioIngressServiceName}, &ingressGatewaySvc) + if err != nil { + if errors.IsNotFound(err) { + return false, nil + } + return false, err + } + + if value, ok := ingressGatewaySvc.Annotations[loadBalancerDualStackAnnotation]; ok && value == loadBalancerDualStack { + return true, nil + } + + return false, nil +} + // awsConfig returns config specific to AWS cluster. // The function evaluates whether to use NLB or ELB load balancer, based on: // diff --git a/internal/clusterconfig/clusterconfig_test.go b/internal/clusterconfig/clusterconfig_test.go index 6df6f4c71..34a7a83a9 100644 --- a/internal/clusterconfig/clusterconfig_test.go +++ b/internal/clusterconfig/clusterconfig_test.go @@ -406,6 +406,72 @@ var _ = Describe("EvaluateClusterSize", func() { Expect(err).To(Not(HaveOccurred())) Expect(size).To(Equal(clusterconfig.Production)) }) + + It("should detect dual stack Ingress if an ip-address-type annotation is set to dual stack", func() { + //given + ingressSvc := corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + Annotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "dualstack", + }, + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&ingressSvc) + + //when + ds, err := clusterconfig.IsDualStack(context.Background(), client) + + //then + Expect(err).To(Not(HaveOccurred())) + Expect(ds).To(Equal(true)) + }) + + It("should detect single stack Ingress if an ip-address-type annotation is not set dual stack", func() { + //given + ingressSvc := corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + Annotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "ipv4", + }, + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&ingressSvc) + + //when + ds, err := clusterconfig.IsDualStack(context.Background(), client) + + //then + Expect(err).To(Not(HaveOccurred())) + Expect(ds).To(Equal(false)) + }) + + It("should detect single stack Ingress if an ip-address-type annotation is not set", func() { + //given + ingressSvc := corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&ingressSvc) + + //when + ds, err := clusterconfig.IsDualStack(context.Background(), client) + + //then + Expect(err).To(Not(HaveOccurred())) + Expect(ds).To(Equal(false)) + }) }) func createFakeClient(objects ...client.Object) client.Client { diff --git a/internal/reconciliations/istioresources/reconciliation.go b/internal/reconciliations/istioresources/reconciliation.go index 59abf99c3..7261a46bf 100644 --- a/internal/reconciliations/istioresources/reconciliation.go +++ b/internal/reconciliations/istioresources/reconciliation.go @@ -78,12 +78,30 @@ func getResources(k8sClient client.Client, provider string) ([]Resource, error) switch provider { case clusterconfig.Aws: + var shouldDelete bool shouldUseNLB, err := clusterconfig.ShouldUseNLB(context.Background(), k8sClient) if err != nil { return nil, err } - istioResources = append(istioResources, NewProxyProtocolEnvoyFilter(k8sClient, shouldUseNLB)) + if shouldUseNLB { + isDualStack, err := clusterconfig.IsDualStack(context.Background(), k8sClient) + if err != nil { + return nil, err + } + if isDualStack { + // NLB with DualStack, so Proxy Protocol enabled + shouldDelete = false + } else { + // NLB without DualStack, so Proxy Protocol disabled + shouldDelete = true + } + } else { + // ELB, so Proxy Protocol enabled + shouldDelete = false + } + + istioResources = append(istioResources, NewProxyProtocolEnvoyFilter(k8sClient, shouldDelete)) case clusterconfig.Openstack: // NLB is a default only for AWS clusters so for OpenStack we need to set the usage of NLB to false diff --git a/internal/reconciliations/istioresources/reconciliation_test.go b/internal/reconciliations/istioresources/reconciliation_test.go index 4992d6735..bef9c5894 100644 --- a/internal/reconciliations/istioresources/reconciliation_test.go +++ b/internal/reconciliations/istioresources/reconciliation_test.go @@ -120,6 +120,86 @@ var _ = Describe("Reconciliation", func() { Expect(client.Get(context.Background(), ctrlclient.ObjectKey{Name: "proxy-protocol", Namespace: "istio-system"}, &e)).Should(Not(Succeed())) }) + It("should be created when hyperscaler is AWS, and the dual stack is enabled", func() { + //given + n := corev1.Node{Spec: corev1.NodeSpec{ProviderID: "aws://asdasdads"}} + ingressSvc := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + Annotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "dualstack", + }, + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&n, &ingressSvc) + reconciler := NewReconciler(client) + + //when + err := reconciler.Reconcile(context.Background(), istioCR) + + //then + Expect(err).To(Not(HaveOccurred())) + Expect(client.Get(context.Background(), ctrlclient.ObjectKey{Name: "proxy-protocol", Namespace: "istio-system"}, &networkingv1alpha3.EnvoyFilter{})).Should(Succeed()) + }) + + It("should not be created when hyperscaler is AWS, but the dual stack is disabled", func() { + //given + n := corev1.Node{Spec: corev1.NodeSpec{ProviderID: "aws://asdasdads"}} + ingressSvc := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + Annotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "ipv4", + }, + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&n, &ingressSvc) + reconciler := NewReconciler(client) + + //when + err := reconciler.Reconcile(context.Background(), istioCR) + + //then + Expect(err).To(Not(HaveOccurred())) + + var e networkingv1alpha3.EnvoyFilter + Expect(client.Get(context.Background(), ctrlclient.ObjectKey{Name: "proxy-protocol", Namespace: "istio-system"}, &e)).Should(Not(Succeed())) + }) + + It("should not be created when hyperscaler is AWS, even if proxy-protocol is set but the dual stack is not enabled", func() { + //given + n := corev1.Node{Spec: corev1.NodeSpec{ProviderID: "aws://asdasdads"}} + ingressSvc := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "istio-ingressgateway", + Namespace: "istio-system", + Annotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "ipv4", + "service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*", + }, + }, + Spec: corev1.ServiceSpec{}, + } + + client := createFakeClient(&n, &ingressSvc) + reconciler := NewReconciler(client) + + //when + err := reconciler.Reconcile(context.Background(), istioCR) + + //then + Expect(err).To(Not(HaveOccurred())) + + var e networkingv1alpha3.EnvoyFilter + Expect(client.Get(context.Background(), ctrlclient.ObjectKey{Name: "proxy-protocol", Namespace: "istio-system"}, &e)).Should(Not(Succeed())) + }) + It("should be created when hyperscaler is OpenStack", func() { //given n := corev1.Node{Spec: corev1.NodeSpec{ProviderID: "openstack://example"}} diff --git a/sec-scanners-config.yaml b/sec-scanners-config.yaml index 88a30bf4f..3eabdb5ca 100644 --- a/sec-scanners-config.yaml +++ b/sec-scanners-config.yaml @@ -1,7 +1,7 @@ module-name: istio kind: kyma bdba: - - europe-docker.pkg.dev/kyma-project/prod/istio/main/istio-manager:9e6acdf692d9250ae360095243989534b14847e0 + - europe-docker.pkg.dev/kyma-project/prod/istio/releases/istio-manager:1.23.1 - europe-docker.pkg.dev/kyma-project/prod/external/istio/install-cni:1.27.1-distroless - europe-docker.pkg.dev/kyma-project/prod/external/istio/proxyv2:1.27.1-distroless - europe-docker.pkg.dev/kyma-project/prod/external/istio/pilot:1.27.1-distroless