diff --git a/controllers/istio_controller.go b/controllers/istio_controller.go index 78e5d1ee52..b2bdf70bc5 100644 --- a/controllers/istio_controller.go +++ b/controllers/istio_controller.go @@ -19,9 +19,10 @@ package controllers import ( "context" "fmt" - istiocrmetrics "github.com/kyma-project/istio/operator/internal/metrics" "time" + istiocrmetrics "github.com/kyma-project/istio/operator/internal/metrics" + "github.com/pkg/errors" "github.com/kyma-project/istio/operator/internal/images" @@ -122,9 +123,9 @@ func (r *IstioReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl return r.terminateReconciliation(ctx, &istioCR, describederrors.NewDescribedError(imgErr, "Unable to get Istio images environments"), operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonReconcileFailed)) } - hub, imgErr := istioImages.GetHub() + registryAndTag, imgErr := istioImages.GetImageRegistryAndTag() if imgErr != nil { - return r.terminateReconciliation(ctx, &istioCR, describederrors.NewDescribedError(imgErr, "Unable to get Istio images hub"), + return r.terminateReconciliation(ctx, &istioCR, describederrors.NewDescribedError(imgErr, "Unable to get Istio images registryAndTag"), operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonReconcileFailed)) } @@ -179,7 +180,7 @@ func (r *IstioReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl } } - istioImageVersion, installationErr := r.istioInstallation.Reconcile(ctx, &istioCR, r.statusHandler, hub) + istioImageVersion, installationErr := r.istioInstallation.Reconcile(ctx, &istioCR, r.statusHandler, registryAndTag) if installationErr != nil { return r.requeueReconciliation(ctx, &istioCR, installationErr, operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonIstioInstallUninstallFailed), diff --git a/controllers/istio_controller_test.go b/controllers/istio_controller_test.go index b709fae54a..9c8f53ebd0 100644 --- a/controllers/istio_controller_test.go +++ b/controllers/istio_controller_test.go @@ -6,6 +6,7 @@ import ( "os" "time" + "github.com/kyma-project/istio/operator/internal/images" "istio.io/api/networking/v1alpha3" "k8s.io/utils/ptr" @@ -1198,7 +1199,7 @@ type istioInstallationReconciliationMock struct { err describederrors.DescribedError } -func (i *istioInstallationReconciliationMock) Reconcile(_ context.Context, _ *operatorv1alpha2.Istio, _ status.Status, _ string) (istiooperator.IstioImageVersion, describederrors.DescribedError) { +func (i *istioInstallationReconciliationMock) Reconcile(_ context.Context, _ *operatorv1alpha2.Istio, _ status.Status, _ images.RegistryAndTag) (istiooperator.IstioImageVersion, describederrors.DescribedError) { version, err := istiooperator.NewIstioImageVersionFromTag("1.16.0-distroless") if err != nil { i.err = describederrors.NewDescribedError(err, "error creating IstioImageVersion") diff --git a/docs/release-notes/1.24.0.md b/docs/release-notes/1.24.0.md index 5961d07f81..9cecf2aa2e 100644 --- a/docs/release-notes/1.24.0.md +++ b/docs/release-notes/1.24.0.md @@ -12,3 +12,5 @@ See [#1710](https://github.com/kyma-project/istio/pull/1710). - We've added support for **forwardClientCertDetails**. See [#1715](https://github.com/kyma-project/istio/pull/1715) and [Istio Custom Resource](https://kyma-project.io/external-content/istio/docs/user/04-00-istio-custom-resource.html). +- Add support for the **KYMA_FIPS_MODE_ENABLED** environment variable, which allows configuring separate Istio FIPS images. + See [#1721](https://github.com/kyma-project/istio/pull/1721). \ No newline at end of file diff --git a/internal/images/env.go b/internal/images/env.go index 1d72c283c6..0223399d67 100644 --- a/internal/images/env.go +++ b/internal/images/env.go @@ -2,13 +2,21 @@ package images import ( "fmt" + "os" "strings" "github.com/caarlos0/env/v11" ) +const kymaFipsModeEnabledEnv = "KYMA_FIPS_MODE_ENABLED" + type Image string +type RegistryAndTag struct { + Registry string + Tag string +} + func (i Image) GetHub() (string, error) { if i == "" { return "", fmt.Errorf("image can not be empty") @@ -22,6 +30,19 @@ func (i Image) GetHub() (string, error) { return strings.Join(parts[:len(parts)-1], "/"), nil } +func (i Image) GetTag() (string, error) { + if i == "" { + return "", fmt.Errorf("image can not be empty") + } + + parts := strings.Split(string(i), ":") + if len(parts) != 2 { + return "", fmt.Errorf("image %s does not contain a valid tag", i) + } + + return strings.Join(parts[len(parts)-1:], "/"), nil +} + type Images struct { Pilot Image `env:"pilot,notEmpty"` InstallCNI Image `env:"install-cni,notEmpty"` @@ -29,7 +50,23 @@ type Images struct { Ztunnel Image `env:"ztunnel,notEmpty"` } +type ImagesFips struct { + Pilot Image `env:"pilot-fips,notEmpty"` + InstallCNI Image `env:"install-cni-fips,notEmpty"` + ProxyV2 Image `env:"proxyv2-fips,notEmpty"` + Ztunnel Image `env:"ztunnel-fips,notEmpty"` +} + func GetImages() (*Images, error) { + kymaFipsModeEnabled := os.Getenv(kymaFipsModeEnabledEnv) + if kymaFipsModeEnabled == "true" { + environments, err := env.ParseAs[ImagesFips]() + if err != nil { + return nil, fmt.Errorf("missing required environment variables %w", err) + } + return (*Images)(&environments), nil + } + environments, err := env.ParseAs[Images]() if err != nil { return nil, fmt.Errorf("missing required environment variables %w", err) @@ -38,23 +75,36 @@ func GetImages() (*Images, error) { return &environments, nil } -func (e *Images) GetHub() (string, error) { - environments := []Image{e.Pilot, e.InstallCNI, e.ProxyV2} +func (e *Images) GetImageRegistryAndTag() (RegistryAndTag, error) { + environments := []Image{e.Pilot, e.InstallCNI, e.ProxyV2, e.Ztunnel} initialHub, err := environments[0].GetHub() if err != nil { - return "", fmt.Errorf("failed to get hub for image %s: %w", environments[0], err) + return RegistryAndTag{}, fmt.Errorf("failed to get hub for image %s: %w", environments[0], err) } - // Ensure that all required images are from the same hub + initialTag, err := environments[0].GetTag() + if err != nil { + return RegistryAndTag{}, fmt.Errorf("failed to get tag for image %s: %w", environments[0], err) + } + + // Ensure that all required images are from the same hub and have the same version tag for _, image := range environments { currentHub, err := image.GetHub() if err != nil { - return "", fmt.Errorf("failed to get hub for image %s: %w", image, err) + return RegistryAndTag{}, fmt.Errorf("failed to get hub for image %s: %w", image, err) } - if currentHub != initialHub { - return "", fmt.Errorf("image %s is not from the same hub as %s", image, initialHub) + return RegistryAndTag{}, fmt.Errorf("image %s is not from the same hub as %s", image, environments[0]) + } + + currentTag, err := image.GetTag() + if err != nil { + return RegistryAndTag{}, fmt.Errorf("failed to get tag for image %s: %w", image, err) + } + if currentTag != initialTag { + return RegistryAndTag{}, fmt.Errorf("image %s does not have the same tag as %s", image, environments[0]) } } - return initialHub, nil + + return RegistryAndTag{Registry: initialHub, Tag: initialTag}, nil } diff --git a/internal/images/env_test.go b/internal/images/env_test.go index 111de0aac8..6d984c1643 100644 --- a/internal/images/env_test.go +++ b/internal/images/env_test.go @@ -2,6 +2,7 @@ package images_test import ( "fmt" + "os" "testing" . "github.com/onsi/ginkgo/v2" @@ -16,7 +17,7 @@ func TestEnvs(t *testing.T) { RunSpecs(t, "Environment Suite") } -var _ = Describe("Images.GetHub", func() { +var _ = Describe("Images.GetImageRegistryAndTag", func() { type fields struct { Pilot images.Image InstallCNI images.Image @@ -24,18 +25,19 @@ var _ = Describe("Images.GetHub", func() { Ztunnel images.Image } - DescribeTable("GetHub", - func(f fields, want string, wantErr bool, err error) { + DescribeTable("GetImageRegistryAndTag", + func(f fields, want images.RegistryAndTag, wantErr bool, expErr error) { e := &images.Images{ Pilot: f.Pilot, InstallCNI: f.InstallCNI, ProxyV2: f.ProxyV2, Ztunnel: f.Ztunnel, } - got, err := e.GetHub() + got, err := e.GetImageRegistryAndTag() if wantErr { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("image")) + Expect(err.Error()).To(ContainSubstring(expErr.Error())) } else { Expect(err).NotTo(HaveOccurred()) Expect(got).To(Equal(want)) @@ -48,21 +50,32 @@ var _ = Describe("Images.GetHub", func() { ProxyV2: "docker.io/istio/proxyv2:1.10.0", Ztunnel: "docker.io/istio/ztunnel:1.10.0", }, - "docker.io/istio", + images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10.0"}, false, nil, ), - Entry("invalid image format", + Entry("invalid image hub", fields{ Pilot: "pilot:1.10.0", InstallCNI: "docker.io/istio/cni:1.10.0", ProxyV2: "docker.io/istio/proxyv2:1.10.0", Ztunnel: "docker.io/istio/ztunnel:1.10.0", }, - "", + images.RegistryAndTag{}, true, fmt.Errorf("image pilot:1.10.0 does not contain a valid hub URL"), ), + Entry("missing image tag", + fields{ + Pilot: "docker.io/istio/pilot1.10.0", + InstallCNI: "docker.io/istio/cni:1.10.0", + ProxyV2: "docker.io/istio/proxyv2:1.10.0", + Ztunnel: "docker.io/istio/ztunnel:1.10.0", + }, + images.RegistryAndTag{}, + true, + fmt.Errorf("image docker.io/istio/pilot1.10.0 does not contain a valid tag"), + ), Entry("images from different hubs", fields{ Pilot: "docker.io/istio/pilot:1.10.0", @@ -70,9 +83,87 @@ var _ = Describe("Images.GetHub", func() { ProxyV2: "foo.bar/istio/proxyv2:1.10.0", Ztunnel: "docker.io/istio/ztunnel:1.10.0", }, - "", + images.RegistryAndTag{}, true, fmt.Errorf("image foo.bar/istio/proxyv2:1.10.0 is not from the same hub as docker.io/istio/pilot:1.10.0"), ), + Entry("images with different tags", + fields{ + Pilot: "docker.io/istio/pilot:1.10.0", + InstallCNI: "docker.io/istio/cni:1.10.0", + ProxyV2: "docker.io/istio/proxyv2:1.11.0", + Ztunnel: "docker.io/istio/ztunnel:1.10.0", + }, + images.RegistryAndTag{}, + true, + fmt.Errorf("image docker.io/istio/proxyv2:1.11.0 does not have the same tag as docker.io/istio/pilot:1.10.0"), + ), + Entry("empty image", + fields{ + Pilot: "", + InstallCNI: "docker.io/istio/cni:1.10.0", + ProxyV2: "docker.io/istio/proxyv2:1.10.0", + }, + images.RegistryAndTag{}, + true, + fmt.Errorf("image can not be empty"), + ), ) }) + +var _ = Describe("Images.GetFipsImages", func() { + _ = os.Setenv("pilot", "docker.io/istio/pilot:1.10.0") + _ = os.Setenv("install-cni", "docker.io/istio/cni:1.10.0") + _ = os.Setenv("proxyv2", "docker.io/istio/proxyv2:1.10.0") + _ = os.Setenv("ztunnel", "docker.io/istio/ztunnel:1.10.0") + + Context("when KYMA_FIPS_MODE_ENABLED is true", func() { + It("should set the FIPS images", func() { + _ = os.Setenv("KYMA_FIPS_MODE_ENABLED", "true") + _ = os.Setenv("pilot-fips", "docker.io/istio/pilot-fips:1.10.0") + _ = os.Setenv("install-cni-fips", "docker.io/istio/cni-fips:1.10.0") + _ = os.Setenv("proxyv2-fips", "docker.io/istio/proxyv2-fips:1.10.0") + _ = os.Setenv("ztunnel-fips", "docker.io/istio/ztunnel-fips:1.10.0") + + e, err := images.GetImages() + Expect(err).NotTo(HaveOccurred()) + Expect(e.Pilot).To(Equal(images.Image("docker.io/istio/pilot-fips:1.10.0"))) + Expect(e.InstallCNI).To(Equal(images.Image("docker.io/istio/cni-fips:1.10.0"))) + Expect(e.ProxyV2).To(Equal(images.Image("docker.io/istio/proxyv2-fips:1.10.0"))) + Expect(e.Ztunnel).To(Equal(images.Image("docker.io/istio/ztunnel-fips:1.10.0"))) + }) + + It("should return an error when FIPS image environment variables are missing", func() { + _ = os.Setenv("KYMA_FIPS_MODE_ENABLED", "true") + _ = os.Unsetenv("pilot-fips") + _ = os.Unsetenv("install-cni-fips") + _ = os.Unsetenv("proxyv2-fips") + _ = os.Unsetenv("ztunnel-fips") + + _, err := images.GetImages() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("environment variable \"pilot-fips\" should not be empty")) + Expect(err.Error()).To(ContainSubstring("environment variable \"install-cni-fips\" should not be empty")) + Expect(err.Error()).To(ContainSubstring("environment variable \"proxyv2-fips\" should not be empty")) + Expect(err.Error()).To(ContainSubstring("environment variable \"ztunnel-fips\" should not be empty")) + }) + }) + + Context("when KYMA_FIPS_MODE_ENABLED is false", func() { + It("should use standard images", func() { + _ = os.Setenv("KYMA_FIPS_MODE_ENABLED", "false") + _ = os.Setenv("pilot-fips", "docker.io/istio/pilot-fips:1.10.0") + _ = os.Setenv("install-cni-fips", "docker.io/istio/cni-fips:1.10.0") + _ = os.Setenv("proxyv2-fips", "docker.io/istio/proxyv2-fips:1.10.0") + _ = os.Setenv("ztunnel-fips", "docker.io/istio/ztunnel-fips:1.10.0") + + e, err := images.GetImages() + Expect(err).NotTo(HaveOccurred()) + Expect(e.Pilot).To(Equal(images.Image("docker.io/istio/pilot:1.10.0"))) + Expect(e.InstallCNI).To(Equal(images.Image("docker.io/istio/cni:1.10.0"))) + Expect(e.ProxyV2).To(Equal(images.Image("docker.io/istio/proxyv2:1.10.0"))) + Expect(e.Ztunnel).To(Equal(images.Image("docker.io/istio/ztunnel:1.10.0"))) + + }) + }) +}) diff --git a/internal/images/merge.go b/internal/images/merge.go index 010f66ad65..3ba036e0d2 100644 --- a/internal/images/merge.go +++ b/internal/images/merge.go @@ -9,8 +9,8 @@ import ( const pullSecretEnvVar = "SKR_IMG_PULL_SECRET" -// MergeHubConfiguration merges the Istio hub configuration to the provided manifest. -func MergeHubConfiguration(manifest []byte, istioImagesHub string) ([]byte, error) { +// MergeRegistryAndTagConfiguration merges the Istio hub and tag configuration to the provided manifest. +func MergeRegistryAndTagConfiguration(manifest []byte, istioImagesRegistryAndTag RegistryAndTag) ([]byte, error) { var templateMap map[string]interface{} err := yaml.Unmarshal(manifest, &templateMap) if err != nil { @@ -19,7 +19,8 @@ func MergeHubConfiguration(manifest []byte, istioImagesHub string) ([]byte, erro err = mergo.Merge(&templateMap, map[string]interface{}{ "spec": map[string]interface{}{ - "hub": istioImagesHub, + "hub": istioImagesRegistryAndTag.Registry, + "tag": istioImagesRegistryAndTag.Tag, }, }, mergo.WithOverride) if err != nil { diff --git a/internal/images/merge_test.go b/internal/images/merge_test.go index 85a61d958c..e08c4e63dc 100644 --- a/internal/images/merge_test.go +++ b/internal/images/merge_test.go @@ -13,11 +13,11 @@ import ( var _ = Describe("Images merging", func() { - Describe("MergeHubConfiguration", func() { + Describe("MergeRegistryAndTagConfiguration", func() { DescribeTable("merges hub correctly", - func(input string, hub string, expectedHub string, expectsError bool) { - out, err := images.MergeHubConfiguration([]byte(input), hub) + func(input string, registryAndTag images.RegistryAndTag, expectedHub string, expectedTag string, expectsError bool) { + out, err := images.MergeRegistryAndTagConfiguration([]byte(input), registryAndTag) if expectsError { Expect(err).To(HaveOccurred()) @@ -31,6 +31,7 @@ var _ = Describe("Images merging", func() { spec := parsed["spec"].(map[string]interface{}) Expect(spec["hub"]).To(Equal(expectedHub)) + Expect(spec["tag"]).To(Equal(expectedTag)) }, Entry("adds hub when missing", @@ -38,8 +39,9 @@ var _ = Describe("Images merging", func() { spec: profile: default `, + images.RegistryAndTag{Registry: "my-hub", Tag: "my-tag"}, "my-hub", - "my-hub", + "my-tag", false, ), @@ -47,15 +49,18 @@ spec: ` spec: hub: old-hub + tag: old-tag `, + images.RegistryAndTag{Registry: "new-hub", Tag: "new-tag"}, "new-hub", - "new-hub", + "new-tag", false, ), Entry("fails on invalid yaml", `::: bad yaml :::`, - "hub", + images.RegistryAndTag{}, + "", "", true, ), diff --git a/internal/istiooperator/istiooperator.go b/internal/istiooperator/istiooperator.go index 441262daba..7b38d4733d 100644 --- a/internal/istiooperator/istiooperator.go +++ b/internal/istiooperator/istiooperator.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/coreos/go-semver/semver" + "github.com/kyma-project/istio/operator/internal/images" iopv1alpha1 "istio.io/istio/operator/pkg/apis" "sigs.k8s.io/yaml" @@ -52,7 +53,7 @@ func (i *IstioImageVersion) Empty() bool { } type Merger interface { - Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesHub string) (string, error) + Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesRegistryAndTag images.RegistryAndTag) (string, error) GetIstioOperator(clusterSize clusterconfig.ClusterSize) (iopv1alpha1.IstioOperator, error) GetIstioImageVersion() (IstioImageVersion, error) } diff --git a/internal/istiooperator/istiooperator_test.go b/internal/istiooperator/istiooperator_test.go index 4e3231ddf0..51ab0713cf 100644 --- a/internal/istiooperator/istiooperator_test.go +++ b/internal/istiooperator/istiooperator_test.go @@ -5,6 +5,7 @@ import ( "path" "testing" + "github.com/kyma-project/istio/operator/internal/images" meshv1alpha1 "istio.io/api/mesh/v1alpha1" "istio.io/istio/operator/pkg/values" "istio.io/istio/pkg/util/protomarshal" @@ -53,7 +54,7 @@ var _ = Describe("Merge", func() { sut := istiooperator.NewDefaultIstioMerger() // when - mergedIstioOperatorPath, err := sut.Merge(clusterSize, istioCR, clusterconfig.ClusterConfiguration{}, "docker.io/istio") + mergedIstioOperatorPath, err := sut.Merge(clusterSize, istioCR, clusterconfig.ClusterConfiguration{}, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.27.1-distroless"}) // then if shouldError { @@ -107,7 +108,7 @@ var _ = Describe("Merge", func() { sut := istiooperator.NewDefaultIstioMerger() // when - mergedIstioOperatorPath, err := sut.Merge(clusterconfig.Production, istioCR, clusterConfig, "docker.io/istio") + mergedIstioOperatorPath, err := sut.Merge(clusterconfig.Production, istioCR, clusterConfig, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.27.1-distroless"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -139,7 +140,7 @@ var _ = Describe("Merge", func() { It("should return merged istio hub", func() { // given - istioImagesHub := "docker.io/overridden/istio-hub" + istioImagesHub := images.RegistryAndTag{Registry: "docker.io/overridden/istio-hub", Tag: "1.27.1-overridden"} sut := istiooperator.NewDefaultIstioMerger() @@ -163,7 +164,8 @@ var _ = Describe("Merge", func() { Expect(err).ShouldNot(HaveOccurred()) Expect(mergedIstioOperatorPath).To(Equal(path.Join("/tmp", istiooperator.MergedIstioOperatorFile))) iop := readIOP(mergedIstioOperatorPath) - Expect(iop.Spec.Hub).To(Equal(istioImagesHub)) + Expect(iop.Spec.Hub).To(Equal(istioImagesHub.Registry)) + Expect(iop.Spec.Tag).To(Equal(istioImagesHub.Tag)) }) }) diff --git a/internal/istiooperator/merge.go b/internal/istiooperator/merge.go index 2e8e4edf07..fa88392f36 100644 --- a/internal/istiooperator/merge.go +++ b/internal/istiooperator/merge.go @@ -11,7 +11,7 @@ import ( "github.com/kyma-project/istio/operator/internal/images" ) -func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesHub string) (string, error) { +func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesRegistryAndTag images.RegistryAndTag) (string, error) { toBeInstalledIop, err := m.GetIstioOperator(clusterSize) if err != nil { return "", err @@ -20,7 +20,7 @@ func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *oper if err != nil { return "", err } - manifestWithOverrideImagesHub, err := images.MergeHubConfiguration(mergedManifest, istioImagesHub) + manifestWithOverrideImagesHub, err := images.MergeRegistryAndTagConfiguration(mergedManifest, istioImagesRegistryAndTag) if err != nil { return "", err } diff --git a/internal/istiooperator/merge_experimental.go b/internal/istiooperator/merge_experimental.go index a219ce6cd3..995bdf9628 100644 --- a/internal/istiooperator/merge_experimental.go +++ b/internal/istiooperator/merge_experimental.go @@ -16,7 +16,7 @@ import ( "github.com/kyma-project/istio/operator/internal/images" ) -func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesHub string) (string, error) { +func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *operatorv1alpha2.Istio, overrides clusterconfig.ClusterConfiguration, istioImagesRegistryAndTag images.RegistryAndTag) (string, error) { toBeInstalledIop, err := m.GetIstioOperator(clusterSize) if err != nil { return "", err @@ -30,11 +30,11 @@ func (m *IstioMerger) Merge(clusterSize clusterconfig.ClusterSize, istioCR *oper return "", err } - manifestWithOverrideImagesHub, err := images.MergeHubConfiguration(mergedManifest, istioImagesHub) + manifestWithOverrideImagesRegistryAndTag, err := images.MergeRegistryAndTagConfiguration(mergedManifest, istioImagesRegistryAndTag) if err != nil { return "", err } - manifestWithOverridePullSecret, err := images.MergePullSecretEnv(manifestWithOverrideImagesHub) + manifestWithOverridePullSecret, err := images.MergePullSecretEnv(manifestWithOverrideImagesRegistryAndTag) if err != nil { return "", err } diff --git a/internal/istiooperator/merge_experimental_test.go b/internal/istiooperator/merge_experimental_test.go index 5a0a69442c..c80ba922fe 100644 --- a/internal/istiooperator/merge_experimental_test.go +++ b/internal/istiooperator/merge_experimental_test.go @@ -13,6 +13,7 @@ import ( "github.com/kyma-project/istio/operator/api/v1alpha2" "github.com/kyma-project/istio/operator/internal/clusterconfig" + "github.com/kyma-project/istio/operator/internal/images" "github.com/kyma-project/istio/operator/internal/istiooperator" ) @@ -31,7 +32,7 @@ var _ = Describe("Merge", func() { } merger := istiooperator.NewDefaultIstioMerger() - p, err := merger.Merge(clusterconfig.Evaluation, &istioCR, clusterconfig.ClusterConfiguration{}, "docker.io/istio") + p, err := merger.Merge(clusterconfig.Evaluation, &istioCR, clusterconfig.ClusterConfiguration{}, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.27.1-distroless"}) Expect(err).ShouldNot(HaveOccurred()) iop := readIOP(p) Expect(iop.Spec.Components.Pilot).ToNot(BeNil()) diff --git a/internal/reconciliations/istio/install.go b/internal/reconciliations/istio/install.go index 5086874186..a9a21cd5cd 100644 --- a/internal/reconciliations/istio/install.go +++ b/internal/reconciliations/istio/install.go @@ -3,6 +3,7 @@ package istio import ( "context" + "github.com/kyma-project/istio/operator/internal/images" "github.com/kyma-project/istio/operator/pkg/lib/gatherer" ctrl "sigs.k8s.io/controller-runtime" @@ -19,13 +20,13 @@ import ( ) type installArgs struct { - client client.Client - istioCR *operatorv1alpha2.Istio - statusHandler status.Status - istioOperatorMerger istiooperator.Merger - istioImageVersion istiooperator.IstioImageVersion - istioClient libraryClient - istioImagesHub string + client client.Client + istioCR *operatorv1alpha2.Istio + statusHandler status.Status + istioOperatorMerger istiooperator.Merger + istioImageVersion istiooperator.IstioImageVersion + istioClient libraryClient + istioImagesRegistryAndTag images.RegistryAndTag } //nolint:funlen // Function 'installIstio' has too many statements (51 > 50) TODO: refactor. @@ -36,7 +37,7 @@ func installIstio(ctx context.Context, args installArgs) (istiooperator.IstioIma statusHandler := args.statusHandler iopMerger := args.istioOperatorMerger istioClient := args.istioClient - istioImagesHub := args.istioImagesHub + istioImagesRegistryAndTag := args.istioImagesRegistryAndTag ctrl.Log.Info("Starting Istio install", "istio version", istioImageVersion.Version()) @@ -80,7 +81,7 @@ func installIstio(ctx context.Context, args installArgs) (istiooperator.IstioIma ctrl.Log.Info("Installing Istio with", "profile", clusterSize.String()) - mergedIstioOperatorPath, err := iopMerger.Merge(clusterSize, istioCR, clusterConfiguration, istioImagesHub) + mergedIstioOperatorPath, err := iopMerger.Merge(clusterSize, istioCR, clusterConfiguration, istioImagesRegistryAndTag) if err != nil { statusHandler.SetCondition(istioCR, operatorv1alpha2.NewReasonWithMessage(operatorv1alpha2.ConditionReasonCustomResourceMisconfigured)) return istioImageVersion, describederrors.NewDescribedError(err, "Could not merge Istio operator configuration").SetCondition(false) diff --git a/internal/reconciliations/istio/reconciliation.go b/internal/reconciliations/istio/reconciliation.go index b2f0c124ae..7cf0659649 100644 --- a/internal/reconciliations/istio/reconciliation.go +++ b/internal/reconciliations/istio/reconciliation.go @@ -3,6 +3,7 @@ package istio import ( "context" + "github.com/kyma-project/istio/operator/internal/images" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -13,7 +14,7 @@ import ( ) type InstallationReconciliation interface { - Reconcile(ctx context.Context, istioCR *operatorv1alpha2.Istio, statusHandler status.Status, istioImageHub string) (istiooperator.IstioImageVersion, describederrors.DescribedError) + Reconcile(ctx context.Context, istioCR *operatorv1alpha2.Istio, statusHandler status.Status, istioImageHub images.RegistryAndTag) (istiooperator.IstioImageVersion, describederrors.DescribedError) } type Installation struct { @@ -27,7 +28,7 @@ func (i *Installation) Reconcile( ctx context.Context, istioCR *operatorv1alpha2.Istio, statusHandler status.Status, - istioImagesHub string, + istioImagesRegistryAndTag images.RegistryAndTag, ) (istiooperator.IstioImageVersion, describederrors.DescribedError) { istioImageVersion, err := i.Merger.GetIstioImageVersion() if err != nil { @@ -37,13 +38,13 @@ func (i *Installation) Reconcile( if istioCR.DeletionTimestamp.IsZero() { args := installArgs{ - client: i.Client, - istioCR: istioCR, - statusHandler: statusHandler, - istioOperatorMerger: i.Merger, - istioImageVersion: istioImageVersion, - istioClient: i.IstioClient, - istioImagesHub: istioImagesHub, + client: i.Client, + istioCR: istioCR, + statusHandler: statusHandler, + istioOperatorMerger: i.Merger, + istioImageVersion: istioImageVersion, + istioClient: i.IstioClient, + istioImagesRegistryAndTag: istioImagesRegistryAndTag, } return installIstio(ctx, args) } diff --git a/internal/reconciliations/istio/reconciliation_test.go b/internal/reconciliations/istio/reconciliation_test.go index ce9d1bbb93..eab720141b 100644 --- a/internal/reconciliations/istio/reconciliation_test.go +++ b/internal/reconciliations/istio/reconciliation_test.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/kyma-project/istio/operator/internal/images" networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "github.com/kyma-project/istio/operator/pkg/labels" @@ -76,7 +77,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -121,7 +122,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -163,7 +164,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -210,7 +211,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -250,7 +251,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -292,7 +293,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -334,7 +335,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -372,7 +373,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -423,7 +424,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -465,7 +466,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -512,7 +513,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -556,7 +557,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -600,7 +601,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -646,7 +647,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -686,7 +687,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -725,7 +726,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -775,7 +776,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).ShouldNot(HaveOccurred()) @@ -824,7 +825,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) // then Expect(err).Should(HaveOccurred()) @@ -870,7 +871,7 @@ var _ = Describe("Installation reconciliation", func() { statusHandler := status.NewStatusHandler(c) // when - _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, "docker.io/istio") + _, err := installation.Reconcile(context.Background(), &istioCR, statusHandler, images.RegistryAndTag{Registry: "docker.io/istio", Tag: "1.10"}) Expect(err).ShouldNot(HaveOccurred()) Expect(mockClient.installCalled).To(BeTrue()) Expect(mockClient.uninstallCalled).To(BeFalse()) @@ -978,7 +979,7 @@ type MergerMock struct { tag string } -func (m MergerMock) Merge(_ clusterconfig.ClusterSize, _ *operatorv1alpha2.Istio, _ clusterconfig.ClusterConfiguration, _ string) (string, error) { +func (m MergerMock) Merge(_ clusterconfig.ClusterSize, _ *operatorv1alpha2.Istio, _ clusterconfig.ClusterConfiguration, _ images.RegistryAndTag) (string, error) { return "mocked istio operator merge result", m.mergeError } diff --git a/internal/restarter/sidecars_test.go b/internal/restarter/sidecars_test.go index b6175e465c..4a7e3e0e4a 100644 --- a/internal/restarter/sidecars_test.go +++ b/internal/restarter/sidecars_test.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/go-logr/logr" + "github.com/kyma-project/istio/operator/internal/images" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/pkg/errors" @@ -277,7 +278,7 @@ type MergerMock struct { tag string } -func (m MergerMock) Merge(_ clusterconfig.ClusterSize, _ *operatorv1alpha2.Istio, _ clusterconfig.ClusterConfiguration, _ string) (string, error) { +func (m MergerMock) Merge(_ clusterconfig.ClusterSize, _ *operatorv1alpha2.Istio, _ clusterconfig.ClusterConfiguration, _ images.RegistryAndTag) (string, error) { return "mocked istio operator merge result", nil }