From c29e819652e6cd67837a2389acfb60c4c477ef16 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Thu, 12 Dec 2024 17:19:06 +0100 Subject: [PATCH 01/22] Adjust mandatory lookup code to handle multiple versions --- pkg/templatelookup/mandatory.go | 64 +++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/pkg/templatelookup/mandatory.go b/pkg/templatelookup/mandatory.go index 976c5852ca..da26befac2 100644 --- a/pkg/templatelookup/mandatory.go +++ b/pkg/templatelookup/mandatory.go @@ -7,6 +7,7 @@ import ( k8slabels "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/Masterminds/semver/v3" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/api/v1beta2" ) @@ -25,11 +26,70 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate mandatoryModules := make(map[string]*ModuleTemplateInfo) for _, moduleTemplate := range mandatoryModuleTemplateList.Items { if moduleTemplate.DeletionTimestamp.IsZero() { - mandatoryModules[moduleTemplate.Name] = &ModuleTemplateInfo{ - ModuleTemplate: &moduleTemplate, + currentModuleTemplate := &moduleTemplate + if mandatoryModules[currentModuleTemplate.Name] != nil { + var err error + currentModuleTemplate, err = getDesiredModuleTemplateForMultipleVersions(currentModuleTemplate, + mandatoryModules[currentModuleTemplate.Name].ModuleTemplate) + if err != nil { + mandatoryModules[getModuleName(currentModuleTemplate)] = &ModuleTemplateInfo{ + ModuleTemplate: nil, + Err: err, + } + continue + } + } + mandatoryModules[getModuleName(currentModuleTemplate)] = &ModuleTemplateInfo{ + ModuleTemplate: currentModuleTemplate, Err: nil, } } } return mandatoryModules, nil } + +// TODO: Create an issue to remove this function and only use the spec.ModuleName when mandatory modules use modulectl +func getModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { + if moduleTemplate.Spec.ModuleName != "" { + return moduleTemplate.Spec.ModuleName + } + + return moduleTemplate.Labels[shared.ModuleName] +} + +// TODO: Create an issue to remove this function and only use the spec.Version when mandatory modules use modulectl +func getModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Version, error) { + if moduleTemplate.Spec.Version != "" { + version, err := semver.NewVersion(moduleTemplate.Spec.Version) + if err != nil { + return &semver.Version{}, fmt.Errorf("could not parse version %s: %w", moduleTemplate.Spec.Version, err) + } + return version, nil + } + + version, err := semver.NewVersion(moduleTemplate.Annotations[shared.ModuleVersionAnnotation]) + if err != nil { + return &semver.Version{}, fmt.Errorf("could not parse version %s: %w", + moduleTemplate.Annotations[shared.ModuleVersionAnnotation], err) + } + return version, nil +} + +func getDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, + error) { + firstVersion, err := getModuleSemverVersion(firstModuleTemplate) + if err != nil { + return nil, err + } + + secondVersion, err := getModuleSemverVersion(secondModuleTemplate) + if err != nil { + return nil, err + } + + if firstVersion.GreaterThan(secondVersion) { + return firstModuleTemplate, nil + } + + return secondModuleTemplate, nil +} From e961bd9fb337c6f144268ee38690d574c69e9007 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Fri, 13 Dec 2024 15:24:26 +0100 Subject: [PATCH 02/22] Add unit tests --- pkg/templatelookup/mandatory.go | 26 ++++--- pkg/templatelookup/mandatory_test.go | 106 +++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 pkg/templatelookup/mandatory_test.go diff --git a/pkg/templatelookup/mandatory.go b/pkg/templatelookup/mandatory.go index da26befac2..6e9a39bd8f 100644 --- a/pkg/templatelookup/mandatory.go +++ b/pkg/templatelookup/mandatory.go @@ -27,19 +27,20 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate for _, moduleTemplate := range mandatoryModuleTemplateList.Items { if moduleTemplate.DeletionTimestamp.IsZero() { currentModuleTemplate := &moduleTemplate - if mandatoryModules[currentModuleTemplate.Name] != nil { + moduleName := GetModuleName(currentModuleTemplate) + if mandatoryModules[moduleName] != nil { var err error - currentModuleTemplate, err = getDesiredModuleTemplateForMultipleVersions(currentModuleTemplate, - mandatoryModules[currentModuleTemplate.Name].ModuleTemplate) + currentModuleTemplate, err = GetDesiredModuleTemplateForMultipleVersions(currentModuleTemplate, + mandatoryModules[moduleName].ModuleTemplate) if err != nil { - mandatoryModules[getModuleName(currentModuleTemplate)] = &ModuleTemplateInfo{ + mandatoryModules[moduleName] = &ModuleTemplateInfo{ ModuleTemplate: nil, Err: err, } continue } } - mandatoryModules[getModuleName(currentModuleTemplate)] = &ModuleTemplateInfo{ + mandatoryModules[moduleName] = &ModuleTemplateInfo{ ModuleTemplate: currentModuleTemplate, Err: nil, } @@ -49,7 +50,7 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate } // TODO: Create an issue to remove this function and only use the spec.ModuleName when mandatory modules use modulectl -func getModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { +func GetModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { if moduleTemplate.Spec.ModuleName != "" { return moduleTemplate.Spec.ModuleName } @@ -58,31 +59,32 @@ func getModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { } // TODO: Create an issue to remove this function and only use the spec.Version when mandatory modules use modulectl -func getModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Version, error) { +func GetModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Version, error) { if moduleTemplate.Spec.Version != "" { version, err := semver.NewVersion(moduleTemplate.Spec.Version) if err != nil { - return &semver.Version{}, fmt.Errorf("could not parse version %s: %w", moduleTemplate.Spec.Version, err) + return nil, fmt.Errorf("could not parse version as a semver: %s: %w", + moduleTemplate.Spec.Version, err) } return version, nil } version, err := semver.NewVersion(moduleTemplate.Annotations[shared.ModuleVersionAnnotation]) if err != nil { - return &semver.Version{}, fmt.Errorf("could not parse version %s: %w", + return nil, fmt.Errorf("could not parse version as a semver %s: %w", moduleTemplate.Annotations[shared.ModuleVersionAnnotation], err) } return version, nil } -func getDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, +func GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, error) { - firstVersion, err := getModuleSemverVersion(firstModuleTemplate) + firstVersion, err := GetModuleSemverVersion(firstModuleTemplate) if err != nil { return nil, err } - secondVersion, err := getModuleSemverVersion(secondModuleTemplate) + secondVersion, err := GetModuleSemverVersion(secondModuleTemplate) if err != nil { return nil, err } diff --git a/pkg/templatelookup/mandatory_test.go b/pkg/templatelookup/mandatory_test.go new file mode 100644 index 0000000000..6176c156db --- /dev/null +++ b/pkg/templatelookup/mandatory_test.go @@ -0,0 +1,106 @@ +package templatelookup_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/kyma-project/lifecycle-manager/pkg/templatelookup" + "github.com/kyma-project/lifecycle-manager/pkg/testutils/builder" +) + +func TestGetDesiredModuleTemplateForMultipleVersions_ReturnCorrectValue(t *testing.T) { + firstModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden"). + WithVersion("1.0.0-dev"). + WithLabel("module-diff", "first"). + Build() + + secondModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden"). + WithVersion("1.0.1-dev"). + WithLabel("module-diff", "second"). + Build() + + result, err := templatelookup.GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate) + require.NoError(t, err) + require.Equal(t, secondModuleTemplate, result) +} + +func TestGetDesiredModuleTemplateForMultipleVersions_ReturnError_NotSemver(t *testing.T) { + firstModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden"). + WithVersion("test"). + WithLabel("module-diff", "first"). + Build() + + secondModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden"). + WithVersion("1.0.1-dev"). + WithLabel("module-diff", "second"). + Build() + + result, err := templatelookup.GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate) + require.ErrorContains(t, err, "could not parse version as a semver") + require.Nil(t, result) +} + +func TestGetModuleName_withModuleName(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithModuleName("warden"). + WithLabelModuleName("warden-dev"). + Build() + + result := templatelookup.GetModuleName(moduleTemplate) + require.Equal(t, "warden", result) +} + +func TestGetModuleName_withModuleNameLabel(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithModuleName(""). + WithLabelModuleName("warden"). + Build() + + result := templatelookup.GetModuleName(moduleTemplate) + require.Equal(t, "warden", result) +} + +func TestGetModuleSemverVersion_WithCorrectSemVer_SpecVersion(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithVersion("1.0.0-dev"). + Build() + + result, err := templatelookup.GetModuleSemverVersion(moduleTemplate) + require.NoError(t, err) + require.Equal(t, "1.0.0-dev", result.String()) +} + +func TestGetModuleSemverVersion_WithCorrectSemVer_VersionAnnotation(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithAnnotation("operator.kyma-project.io/module-version", "1.0.0-dev"). + Build() + + result, err := templatelookup.GetModuleSemverVersion(moduleTemplate) + require.NoError(t, err) + require.Equal(t, "1.0.0-dev", result.String()) +} + +func TestGetModuleSemverVersion_ReturnError_NotSemver_SpecVersion(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithVersion("dev"). + Build() + + result, err := templatelookup.GetModuleSemverVersion(moduleTemplate) + require.ErrorContains(t, err, "could not parse version as a semver") + require.Nil(t, result) +} + +func TestGetModuleSemverVersion_ReturnError_NotSemver_VersionAnnotation(t *testing.T) { + moduleTemplate := builder.NewModuleTemplateBuilder(). + WithAnnotation("operator.kyma-project.io/module-version", "dev"). + Build() + + result, err := templatelookup.GetModuleSemverVersion(moduleTemplate) + require.ErrorContains(t, err, "could not parse version as a semver") + require.Nil(t, result) +} From 708003292554dc12e1c55700034b7423e50b7f5d Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Fri, 13 Dec 2024 16:14:17 +0100 Subject: [PATCH 03/22] E2E test --- .../action.yml | 6 ++-- .../test-e2e-with-modulereleasemeta.yml | 2 ++ pkg/testutils/manifest.go | 30 +++++++++++++++++++ scripts/tests/deploy_moduletemplate.sh | 7 +++++ tests/e2e/mandatory_module_test.go | 7 +++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index eeffd278f4..47bf794fd6 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -70,14 +70,16 @@ runs: shell: bash run: | ./deploy_modulereleasemeta.sh ${{ env.ModuleName }} fast:${{ env.NewerVersion }} regular:${{ env.OlderVersion }} + - name: Create Template Operator Module as Mandatory Module - working-directory: lifecycle-manager + working-directory: template-operator if: ${{ matrix.e2e-test == 'mandatory-module' || matrix.e2e-test == 'mandatory-module-metrics' }} shell: bash run: | - kubectl apply -f tests/e2e/moduletemplate/mandatory_moduletemplate_template_operator_v1.yaml + ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true + ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel working-directory: template-operator if: ${{ matrix.e2e-test == 'non-blocking-deletion' }} diff --git a/.github/workflows/test-e2e-with-modulereleasemeta.yml b/.github/workflows/test-e2e-with-modulereleasemeta.yml index be91c3547c..3731b512de 100644 --- a/.github/workflows/test-e2e-with-modulereleasemeta.yml +++ b/.github/workflows/test-e2e-with-modulereleasemeta.yml @@ -115,6 +115,8 @@ jobs: ModuleDeploymentNameInOlderVersion: template-operator-v1-controller-manager NewerVersion: 2.4.2-e2e-test OlderVersion: 1.1.1-e2e-test + OlderVersionForMandatoryModule: 1.0.0-smoke-test + NewerVersionForMandatoryModule: 1.1.0-smoke-test VersionForStatefulSetInWarning: 1.0.0-warning-statefulset VersionForDeploymentInWarning: 1.0.0-warning-deployment VersionForMisconfiguredDeploymentImage: 1.0.0-misconfigured-deployment diff --git a/pkg/testutils/manifest.go b/pkg/testutils/manifest.go index c1cb38b0e5..98e92adfe7 100644 --- a/pkg/testutils/manifest.go +++ b/pkg/testutils/manifest.go @@ -44,6 +44,7 @@ var ( errManifestOperationNotContainMessage = errors.New("manifest last operation does not contain expected message") errManifestVersionIsIncorrect = errors.New("manifest version is incorrect") errManifestConditionNotExists = errors.New("manifest condition does not exist") + errManifestNotFound = errors.New("manifest does not exist") ) func NewTestManifest(prefix string) *v1beta2.Manifest { @@ -292,6 +293,35 @@ func SetSkipLabelToMandatoryManifests(ctx context.Context, clnt client.Client, i return nil } +func MandatoryModuleManifestExistWithCorrectVersion(ctx context.Context, clnt client.Client, + moduleName, expectedVersion string) error { + manifestList := v1beta2.ManifestList{} + if err := clnt.List(ctx, &manifestList, &client.ListOptions{ + LabelSelector: k8slabels.SelectorFromSet(k8slabels.Set{shared.IsMandatoryModule: "true"}), + }); err != nil { + return fmt.Errorf("failed to list manifests: %w", err) + } + + manifestFound := false + for _, manifest := range manifestList.Items { + manifestModuleName, err := manifest.GetModuleName() + if err != nil { + return fmt.Errorf("failed to get manifest module name, %w", err) + } + if manifestModuleName == moduleName { + manifestFound = true + if manifest.Spec.Version != expectedVersion { + return errManifestVersionIsIncorrect + } + } + } + + if !manifestFound { + return errManifestNotFound + } + return nil +} + func SkipLabelExistsInManifest(ctx context.Context, clnt client.Client, kymaName, diff --git a/scripts/tests/deploy_moduletemplate.sh b/scripts/tests/deploy_moduletemplate.sh index df7714a339..8671c68b17 100755 --- a/scripts/tests/deploy_moduletemplate.sh +++ b/scripts/tests/deploy_moduletemplate.sh @@ -7,6 +7,7 @@ set -o pipefail MODULE_NAME=$1 RELEASE_VERSION=$2 INCLUDE_DEFAULT_CR=${3:-true} +MANDATORY=${4:-false} cat < module-config-for-e2e.yaml name: kyma-project.io/module/${MODULE_NAME} @@ -26,6 +27,12 @@ defaultCR: https://localhost:8080/config/samples/default-sample-cr.yaml EOF fi +if [ "${MANDATORY}" == "true" ]; then + cat <> module-config-for-e2e.yaml +mandatory: true +EOF +fi + cat module-config-for-e2e.yaml modulectl create --config-file ./module-config-for-e2e.yaml --registry http://localhost:5111 --insecure sed -i 's/localhost:5111/k3d-kcp-registry.localhost:5000/g' ./template.yaml diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index baf8b98059..a890676bb1 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -54,6 +54,13 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { shared.OperatorGroup, "v1beta2", string(shared.ModuleTemplateKind), skrClient). Should(Not(Succeed())) }) + + By("And the mandatory module manifest is installed with the correct version", func() { + Consistently(MandatoryModuleManifestExistWithCorrectVersion). + WithContext(ctx). + WithArguments(kcpClient, "template-operator", "1.1.0-smoke-test"). + Should(Succeed()) + }) }) It("When the mandatory Manifest is labelled to skip reconciliation", func() { From 68ff1524183b2fb48afd17f807c93d5d2d8ceda9 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Fri, 13 Dec 2024 16:46:58 +0100 Subject: [PATCH 04/22] Remove TODO + add more unit tests coverage --- .../action.yml | 15 ++++++- pkg/templatelookup/mandatory.go | 2 - pkg/templatelookup/mandatory_test.go | 43 +++++++++++++++++-- unit-test-coverage.yaml | 2 +- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index 47bf794fd6..5a5e307d90 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -20,6 +20,9 @@ runs: cp ../lifecycle-manager/scripts/tests/deploy_modulereleasemeta.sh . - name: Create and apply Template Operator ModuleTemplate from the latest release working-directory: template-operator + if: ${{ matrix.e2e-test != 'mandatory-module' || + matrix.e2e-test != 'mandatory-module-metrics' + }} shell: bash run: | modulectl create --config-file ./module-config.yaml --registry http://localhost:5111 --insecure @@ -28,6 +31,9 @@ runs: kubectl apply -f template.yaml - name: Create and apply Template Operator ModuleTemplate with ModuleDeploymentNameInOlderVersion working-directory: template-operator + if: ${{ matrix.e2e-test != 'mandatory-module' || + matrix.e2e-test != 'mandatory-module-metrics' + }} shell: bash run: | make build-manifests @@ -35,6 +41,9 @@ runs: ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersion }} - name: Create and apply Template Operator ModuleTemplate with ModuleDeploymentNameInNewerVersion working-directory: template-operator + if: ${{ matrix.e2e-test != 'mandatory-module' || + matrix.e2e-test != 'mandatory-module-metrics' + }} shell: bash run: | make build-manifests @@ -71,14 +80,18 @@ runs: run: | ./deploy_modulereleasemeta.sh ${{ env.ModuleName }} fast:${{ env.NewerVersion }} regular:${{ env.OlderVersion }} - - name: Create Template Operator Module as Mandatory Module + - name: Create Template Operator Module in two versions as Mandatory Module working-directory: template-operator if: ${{ matrix.e2e-test == 'mandatory-module' || matrix.e2e-test == 'mandatory-module-metrics' }} shell: bash run: | + make build-manifests + yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true + + yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel working-directory: template-operator diff --git a/pkg/templatelookup/mandatory.go b/pkg/templatelookup/mandatory.go index 6e9a39bd8f..6fd597ed9f 100644 --- a/pkg/templatelookup/mandatory.go +++ b/pkg/templatelookup/mandatory.go @@ -49,7 +49,6 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate return mandatoryModules, nil } -// TODO: Create an issue to remove this function and only use the spec.ModuleName when mandatory modules use modulectl func GetModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { if moduleTemplate.Spec.ModuleName != "" { return moduleTemplate.Spec.ModuleName @@ -58,7 +57,6 @@ func GetModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { return moduleTemplate.Labels[shared.ModuleName] } -// TODO: Create an issue to remove this function and only use the spec.Version when mandatory modules use modulectl func GetModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Version, error) { if moduleTemplate.Spec.Version != "" { version, err := semver.NewVersion(moduleTemplate.Spec.Version) diff --git a/pkg/templatelookup/mandatory_test.go b/pkg/templatelookup/mandatory_test.go index 56542eaa04..e1780e1569 100644 --- a/pkg/templatelookup/mandatory_test.go +++ b/pkg/templatelookup/mandatory_test.go @@ -149,10 +149,10 @@ func TestGetMandatory_OneVersion(t *testing.T) { require.Contains(t, result, "mandatory") require.Equal(t, result["warden"].ModuleTemplate.Name, firstModuleTemplate.Name) require.Equal(t, result["warden"].ModuleTemplate.Spec.Version, firstModuleTemplate.Spec.Version) - require.Nil(t, result["warden"].Err) + require.NoError(t, result["warden"].Err) require.Equal(t, result["mandatory"].ModuleTemplate.Name, thirdModuleTemplate.Name) require.Equal(t, result["mandatory"].ModuleTemplate.Spec.Version, thirdModuleTemplate.Spec.Version) - require.Nil(t, result["mandatory"].Err) + require.NoError(t, result["mandatory"].Err) require.NotContains(t, result, "template-operator") } @@ -204,9 +204,44 @@ func TestGetMandatory_MultipleVersions(t *testing.T) { require.Contains(t, result, "mandatory") require.Equal(t, result["warden"].ModuleTemplate.Name, fourthModuleTemplate.Name) require.Equal(t, result["warden"].ModuleTemplate.Spec.Version, fourthModuleTemplate.Spec.Version) - require.Nil(t, result["warden"].Err) + require.NoError(t, result["warden"].Err) require.Equal(t, result["mandatory"].ModuleTemplate.Name, thirdModuleTemplate.Name) require.Equal(t, result["mandatory"].ModuleTemplate.Spec.Version, thirdModuleTemplate.Spec.Version) - require.Nil(t, result["mandatory"].Err) + require.NoError(t, result["mandatory"].Err) require.NotContains(t, result, "template-operator") } + +func TestGetMandatory_WithErrorNotSemVer(t *testing.T) { + scheme := runtime.NewScheme() + err := v1beta2.AddToScheme(scheme) + require.NoError(t, err) + + firstModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden-test"). + WithModuleName("warden"). + WithMandatory(true). + WithLabel("operator.kyma-project.io/mandatory-module", "true"). + WithVersion("test"). + Build() + + secondModuleTemplate := builder.NewModuleTemplateBuilder(). + WithName("warden-1.0.0"). + WithModuleName("warden"). + WithMandatory(true). + WithLabel("operator.kyma-project.io/mandatory-module", "true"). + WithVersion("1.0.0"). + Build() + + fakeClient := fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(firstModuleTemplate, secondModuleTemplate). + Build() + + result, err := templatelookup.GetMandatory(context.TODO(), fakeClient) + + require.NoError(t, err) + require.Len(t, result, 1) + + require.Contains(t, result, "warden") + require.ErrorContains(t, result["warden"].Err, "could not parse version as a semver") +} diff --git a/unit-test-coverage.yaml b/unit-test-coverage.yaml index bc30cff1d1..53789c97af 100644 --- a/unit-test-coverage.yaml +++ b/unit-test-coverage.yaml @@ -18,4 +18,4 @@ packages: internal/pkg/resources: 91.7 internal/remote: 20.2 internal/util/collections: 86 - pkg/templatelookup: 77.1 + pkg/templatelookup: 85 From cacb76a7352b1a01d98b7ddad2b13c2d576d36f8 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 16:45:20 +0100 Subject: [PATCH 05/22] Fix coverage --- unit-test-coverage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-test-coverage.yaml b/unit-test-coverage.yaml index 53789c97af..f57ceb995c 100644 --- a/unit-test-coverage.yaml +++ b/unit-test-coverage.yaml @@ -18,4 +18,4 @@ packages: internal/pkg/resources: 91.7 internal/remote: 20.2 internal/util/collections: 86 - pkg/templatelookup: 85 + pkg/templatelookup: 83.3 From 10f48a4f4944d5aba12bb7283e0dd6cbce628d02 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 16:46:48 +0100 Subject: [PATCH 06/22] Fix linting --- pkg/templatelookup/mandatory.go | 5 +++-- pkg/templatelookup/mandatory_test.go | 6 +++--- pkg/testutils/manifest.go | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkg/templatelookup/mandatory.go b/pkg/templatelookup/mandatory.go index 6fd597ed9f..ba2d6d7c01 100644 --- a/pkg/templatelookup/mandatory.go +++ b/pkg/templatelookup/mandatory.go @@ -4,10 +4,10 @@ import ( "context" "fmt" + "github.com/Masterminds/semver/v3" k8slabels "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/Masterminds/semver/v3" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/api/v1beta2" ) @@ -76,7 +76,8 @@ func GetModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Ver } func GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, - error) { + error, +) { firstVersion, err := GetModuleSemverVersion(firstModuleTemplate) if err != nil { return nil, err diff --git a/pkg/templatelookup/mandatory_test.go b/pkg/templatelookup/mandatory_test.go index e1780e1569..56ea41f3b8 100644 --- a/pkg/templatelookup/mandatory_test.go +++ b/pkg/templatelookup/mandatory_test.go @@ -1,16 +1,16 @@ package templatelookup_test import ( + "context" "testing" "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client/fake" - "context" "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/kyma-project/lifecycle-manager/pkg/templatelookup" "github.com/kyma-project/lifecycle-manager/pkg/testutils/builder" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client/fake" ) func TestGetDesiredModuleTemplateForMultipleVersions_ReturnCorrectValue(t *testing.T) { diff --git a/pkg/testutils/manifest.go b/pkg/testutils/manifest.go index 98e92adfe7..663cd8dd58 100644 --- a/pkg/testutils/manifest.go +++ b/pkg/testutils/manifest.go @@ -294,7 +294,8 @@ func SetSkipLabelToMandatoryManifests(ctx context.Context, clnt client.Client, i } func MandatoryModuleManifestExistWithCorrectVersion(ctx context.Context, clnt client.Client, - moduleName, expectedVersion string) error { + moduleName, expectedVersion string, +) error { manifestList := v1beta2.ManifestList{} if err := clnt.List(ctx, &manifestList, &client.ListOptions{ LabelSelector: k8slabels.SelectorFromSet(k8slabels.Set{shared.IsMandatoryModule: "true"}), From 09f10f6726bb0e6a10eacc2673baf837ca302df0 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 16:49:59 +0100 Subject: [PATCH 07/22] Debug E2E test --- pkg/testutils/manifest.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/testutils/manifest.go b/pkg/testutils/manifest.go index 663cd8dd58..0a43b8ed6c 100644 --- a/pkg/testutils/manifest.go +++ b/pkg/testutils/manifest.go @@ -18,6 +18,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/types" templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" + "github.com/onsi/ginkgo/v2" apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" k8slabels "k8s.io/apimachinery/pkg/labels" @@ -312,6 +313,7 @@ func MandatoryModuleManifestExistWithCorrectVersion(ctx context.Context, clnt cl if manifestModuleName == moduleName { manifestFound = true if manifest.Spec.Version != expectedVersion { + ginkgo.GinkgoWriter.Printf("expected version: %s, but got: %s", expectedVersion, manifest.Spec.Version) return errManifestVersionIsIncorrect } } From b44bc9db05b57b06228b39b60a8e982dc79b29ab Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 17:07:05 +0100 Subject: [PATCH 08/22] Fix E2E test --- pkg/templatelookup/mandatory_test.go | 8 ++++---- pkg/testutils/manifest.go | 2 -- tests/e2e/mandatory_module_test.go | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pkg/templatelookup/mandatory_test.go b/pkg/templatelookup/mandatory_test.go index 56ea41f3b8..997d18488e 100644 --- a/pkg/templatelookup/mandatory_test.go +++ b/pkg/templatelookup/mandatory_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/runtime" + machineryruntime "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/kyma-project/lifecycle-manager/api/v1beta2" @@ -110,7 +110,7 @@ func TestGetModuleSemverVersion_ReturnError_NotSemver_VersionAnnotation(t *testi } func TestGetMandatory_OneVersion(t *testing.T) { - scheme := runtime.NewScheme() + scheme := machineryruntime.NewScheme() err := v1beta2.AddToScheme(scheme) require.NoError(t, err) @@ -157,7 +157,7 @@ func TestGetMandatory_OneVersion(t *testing.T) { } func TestGetMandatory_MultipleVersions(t *testing.T) { - scheme := runtime.NewScheme() + scheme := machineryruntime.NewScheme() err := v1beta2.AddToScheme(scheme) require.NoError(t, err) @@ -212,7 +212,7 @@ func TestGetMandatory_MultipleVersions(t *testing.T) { } func TestGetMandatory_WithErrorNotSemVer(t *testing.T) { - scheme := runtime.NewScheme() + scheme := machineryruntime.NewScheme() err := v1beta2.AddToScheme(scheme) require.NoError(t, err) diff --git a/pkg/testutils/manifest.go b/pkg/testutils/manifest.go index 0a43b8ed6c..663cd8dd58 100644 --- a/pkg/testutils/manifest.go +++ b/pkg/testutils/manifest.go @@ -18,7 +18,6 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/types" templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" - "github.com/onsi/ginkgo/v2" apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" k8slabels "k8s.io/apimachinery/pkg/labels" @@ -313,7 +312,6 @@ func MandatoryModuleManifestExistWithCorrectVersion(ctx context.Context, clnt cl if manifestModuleName == moduleName { manifestFound = true if manifest.Spec.Version != expectedVersion { - ginkgo.GinkgoWriter.Printf("expected version: %s, but got: %s", expectedVersion, manifest.Spec.Version) return errManifestVersionIsIncorrect } } diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index a890676bb1..71598df8be 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -58,7 +58,7 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { By("And the mandatory module manifest is installed with the correct version", func() { Consistently(MandatoryModuleManifestExistWithCorrectVersion). WithContext(ctx). - WithArguments(kcpClient, "template-operator", "1.1.0-smoke-test"). + WithArguments(kcpClient, "template-operator", "v1.1.0-smoke-test"). Should(Succeed()) }) }) From 246c5b12b2e4bafea130b0b8ab192324f66454a5 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 17:27:54 +0100 Subject: [PATCH 09/22] Fix E2E test --- .../action.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index 5a5e307d90..58cf9fd3ba 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -20,7 +20,7 @@ runs: cp ../lifecycle-manager/scripts/tests/deploy_modulereleasemeta.sh . - name: Create and apply Template Operator ModuleTemplate from the latest release working-directory: template-operator - if: ${{ matrix.e2e-test != 'mandatory-module' || + if: ${{ matrix.e2e-test != 'mandatory-module' && matrix.e2e-test != 'mandatory-module-metrics' }} shell: bash @@ -31,7 +31,7 @@ runs: kubectl apply -f template.yaml - name: Create and apply Template Operator ModuleTemplate with ModuleDeploymentNameInOlderVersion working-directory: template-operator - if: ${{ matrix.e2e-test != 'mandatory-module' || + if: ${{ matrix.e2e-test != 'mandatory-module' && matrix.e2e-test != 'mandatory-module-metrics' }} shell: bash @@ -41,7 +41,7 @@ runs: ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersion }} - name: Create and apply Template Operator ModuleTemplate with ModuleDeploymentNameInNewerVersion working-directory: template-operator - if: ${{ matrix.e2e-test != 'mandatory-module' || + if: ${{ matrix.e2e-test != 'mandatory-module' && matrix.e2e-test != 'mandatory-module-metrics' }} shell: bash @@ -91,6 +91,7 @@ runs: yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true + make build-manifests yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel From cd4beb318722ff9ef07edecb1550ff1a8ec67403 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Sun, 15 Dec 2024 18:00:36 +0100 Subject: [PATCH 10/22] debug E2E test --- .../action.yml | 4 ++-- pkg/testutils/deployment.go | 4 +++- tests/e2e/mandatory_module_test.go | 9 ++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index 58cf9fd3ba..5085637208 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -88,11 +88,11 @@ runs: shell: bash run: | make build-manifests - yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml + yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true make build-manifests - yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml + yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel working-directory: template-operator diff --git a/pkg/testutils/deployment.go b/pkg/testutils/deployment.go index a5dbc304be..21c96d0bc7 100644 --- a/pkg/testutils/deployment.go +++ b/pkg/testutils/deployment.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + "github.com/onsi/ginkgo/v2" apiappsv1 "k8s.io/api/apps/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -24,7 +25,7 @@ func DeploymentIsReady(ctx context.Context, clnt client.Client, name, namespace } return fmt.Errorf("could not get deployment: %w", err) } - + ginkgo.GinkgoWriter.Printf("deploy: %v\n", deploy.Status) if deploy.Spec.Replicas != nil && *deploy.Spec.Replicas == deploy.Status.ReadyReplicas { return nil @@ -75,4 +76,5 @@ func GetDeployment(ctx context.Context, clnt client.Client, } return deploy, nil } + func int32Ptr(i int32) *int32 { return &i } diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index 71598df8be..fa6908c8bd 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -3,15 +3,14 @@ package e2e_test import ( "os/exec" - templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/api/v1beta2" + templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" + apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" . "github.com/kyma-project/lifecycle-manager/pkg/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ) var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { From 091c3dafef98ab5477133dec058813dad17987f3 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 12:15:26 +0100 Subject: [PATCH 11/22] fix E2E test --- .../deploy-template-operator/action.yml | 4 +- .github/workflows/test-e2e.yml | 4 +- pkg/testutils/deployment.go | 2 - tests/e2e/Makefile | 6 + tests/e2e/mandatory_module_test.go | 19 +- ...tory_module_without_version_naming_test.go | 223 ++++++++++++++++++ tests/e2e/mandatory_modules_metrics_test.go | 16 +- ...les_without_version_naming_metrics_test.go | 105 +++++++++ 8 files changed, 368 insertions(+), 11 deletions(-) create mode 100644 tests/e2e/mandatory_module_without_version_naming_test.go create mode 100644 tests/e2e/mandatory_modules_without_version_naming_metrics_test.go diff --git a/.github/actions/deploy-template-operator/action.yml b/.github/actions/deploy-template-operator/action.yml index cc36ff2009..53c0c68a69 100644 --- a/.github/actions/deploy-template-operator/action.yml +++ b/.github/actions/deploy-template-operator/action.yml @@ -47,8 +47,8 @@ runs: kubectl apply -f tests/e2e/moduletemplate/moduletemplate_template_operator_v2_direct_version.yaml - name: Create Template Operator Module as Mandatory Module working-directory: lifecycle-manager - if: ${{ matrix.e2e-test == 'mandatory-module' || - matrix.e2e-test == 'mandatory-module-metrics' + if: ${{ matrix.e2e-test == 'mandatory-module-without-version-naming' || + matrix.e2e-test == 'mandatory-module-metrics-without-version-naming' }} shell: bash run: | diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index abd6f28b17..76a21bedf1 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -58,8 +58,8 @@ jobs: - ca-certificate-rotation - istio-gateway-secret-rotation - self-signed-certificate-rotation - - mandatory-module - - mandatory-module-metrics + - mandatory-module-without-version-naming + - mandatory-module-metrics-without-version-naming - misconfigured-kyma-secret - rbac-privileges - ocm-compatible-module-template diff --git a/pkg/testutils/deployment.go b/pkg/testutils/deployment.go index 21c96d0bc7..4cd691ab0c 100644 --- a/pkg/testutils/deployment.go +++ b/pkg/testutils/deployment.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" - "github.com/onsi/ginkgo/v2" apiappsv1 "k8s.io/api/apps/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -25,7 +24,6 @@ func DeploymentIsReady(ctx context.Context, clnt client.Client, name, namespace } return fmt.Errorf("could not get deployment: %w", err) } - ginkgo.GinkgoWriter.Printf("deploy: %v\n", deploy.Status) if deploy.Spec.Replicas != nil && *deploy.Spec.Replicas == deploy.Status.ReadyReplicas { return nil diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 7c4d3f166f..953687c4f1 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -79,6 +79,9 @@ kyma-metrics: mandatory-module-metrics: go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Metrics" +mandatory-module-metrics-without-version-naming: + go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Without Version In Naming Metrics" + watcher-enqueue: go test -timeout 20m -ginkgo.v -ginkgo.focus "Enqueue Event from Watcher" @@ -97,6 +100,9 @@ module-consistency: mandatory-module: go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Installation and Deletion" +mandatory-module-without-version-naming: + go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Without Version In Naming Installation and Deletion" + non-blocking-deletion: go test -timeout 20m -ginkgo.v -ginkgo.focus "Non Blocking Kyma Module Deletion" diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index fa6908c8bd..26879b4ba6 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -57,7 +57,7 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { By("And the mandatory module manifest is installed with the correct version", func() { Consistently(MandatoryModuleManifestExistWithCorrectVersion). WithContext(ctx). - WithArguments(kcpClient, "template-operator", "v1.1.0-smoke-test"). + WithArguments(kcpClient, "template-operator", "1.1.0-smoke-test"). Should(Succeed()) }) }) @@ -143,10 +143,10 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }). Should(Succeed()) }) - It("Then Kyma is in a \"Error\" State", func() { + It("Then Kyma is in a \"Warning\" State", func() { Eventually(KymaIsInState). WithContext(ctx). - WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateError). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateWarning). Should(Succeed()) }) @@ -198,7 +198,18 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { WithArguments(kcpClient, &v1beta2.ModuleTemplate{ ObjectMeta: apimetav1.ObjectMeta{ - Name: "template-operator-mandatory", + Name: "template-operator-1.0.0-smoke-test", + Namespace: ControlPlaneNamespace, + }, + }). + Should(Succeed()) + + Eventually(DeleteCR). + WithContext(ctx). + WithArguments(kcpClient, + &v1beta2.ModuleTemplate{ + ObjectMeta: apimetav1.ObjectMeta{ + Name: "template-operator-1.1.0-smoke-test", Namespace: ControlPlaneNamespace, }, }). diff --git a/tests/e2e/mandatory_module_without_version_naming_test.go b/tests/e2e/mandatory_module_without_version_naming_test.go new file mode 100644 index 0000000000..9d9a0cd0f5 --- /dev/null +++ b/tests/e2e/mandatory_module_without_version_naming_test.go @@ -0,0 +1,223 @@ +package e2e_test + +import ( + "os/exec" + + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/kyma-project/lifecycle-manager/api/v1beta2" + templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" + apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + . "github.com/kyma-project/lifecycle-manager/pkg/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Mandatory Module Without Version In Naming Installation and Deletion", Ordered, func() { + kyma := NewKymaWithSyncLabel("kyma-sample", ControlPlaneNamespace, v1beta2.DefaultChannel) + + InitEmptyKymaBeforeAll(kyma) + CleanupKymaAfterAll(kyma) + + Context("Given kyma deployed in KCP", func() { + It("Then mandatory module is installed on the SKR cluster", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Succeed()) + By("And the SKR Module Default CR is in a \"Ready\" State", func() { + Eventually(CheckSampleCRIsInState). + WithContext(ctx). + WithArguments(TestModuleCRName, RemoteNamespace, skrClient, shared.StateReady). + Should(Succeed()) + }) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Consistently(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + By("And the Mandatory ModuleTemplate has the correct mandatory-module label", func() { + Eventually(MandatoryModuleTemplateHasExpectedLabel). + WithContext(ctx). + WithArguments(kcpClient, "template-operator", shared.IsMandatoryModule, + shared.EnableLabelValue). + Should(Succeed()) + }) + + By("And the mandatory ModuleTemplate is not synchronised to the SKR cluster", func() { + Consistently(CheckIfExists). + WithContext(ctx). + WithArguments("template-operator-mandatory", RemoteNamespace, + shared.OperatorGroup, "v1beta2", string(shared.ModuleTemplateKind), skrClient). + Should(Not(Succeed())) + }) + }) + + It("When the mandatory Manifest is labelled to skip reconciliation", func() { + Eventually(SetSkipLabelToMandatoryManifests). + WithContext(ctx). + WithArguments(kcpClient, true). + Should(Succeed()) + + By("And deleting the mandatory SKR Default CR", func() { + Eventually(DeleteCRWithGVK). + WithContext(ctx). + WithArguments(skrClient, TestModuleCRName, RemoteNamespace, templatev1alpha1.GroupVersion.Group, + "v1alpha1", string(templatev1alpha1.SampleKind)). + Should(Succeed()) + }) + }) + It("Then mandatory SKR Module Default CR is not recreated", func() { + Consistently(CheckIfExists). + WithContext(ctx). + WithArguments(TestModuleCRName, RemoteNamespace, templatev1alpha1.GroupVersion.Group, + "v1alpha1", string(templatev1alpha1.SampleKind), skrClient). + Should(Equal(ErrNotFound)) + }) + + It("When deleting the mandatory SKR Module Manager Deployment", func() { + err := DeleteCRWithGVK(ctx, skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace, "apps", "v1", "Deployment") + Expect(err).ToNot(HaveOccurred()) + }) + It("Then Module Manager Deployment is not recreated on the SKR cluster", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Equal(ErrNotFound)) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Consistently(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + }) + + It("When the mandatory Manifest skip reconciliation label is removed", func() { + Eventually(SetSkipLabelToMandatoryManifests). + WithContext(ctx). + WithArguments(kcpClient, false). + Should(Succeed()) + }) + It("Then mandatory SKR Module Default CR is recreated", func() { + Eventually(CheckIfExists). + WithContext(ctx). + WithArguments(TestModuleCRName, RemoteNamespace, + templatev1alpha1.GroupVersion.Group, "v1alpha1", string(templatev1alpha1.SampleKind), + skrClient). + Should(Succeed()) + + By("And mandatory SKR Module Deployment is recreated", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Succeed()) + }) + + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Consistently(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + }) + + It("When mandatory Module is enabled on SKR Kyma CR", func() { + Eventually(EnableModule). + WithContext(ctx). + WithArguments(skrClient, defaultRemoteKymaName, RemoteNamespace, v1beta2.Module{ + Name: TestModuleName, + Channel: v1beta2.DefaultChannel, + Managed: true, + }). + Should(Succeed()) + }) + It("Then Kyma is in a \"Error\" State", func() { + Eventually(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateError). + Should(Succeed()) + }) + + It("When mandatory Module is disabled on SKR Kyma CR", func() { + Eventually(DisableModule). + WithContext(ctx). + WithArguments(skrClient, defaultRemoteKymaName, RemoteNamespace, TestModuleName). + Should(Succeed()) + + By("Then Kyma is back in a \"Ready\" State", func() { + Eventually(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + }) + + It("When new version of ModuleTemplate is applied", func() { + cmd := exec.Command("kubectl", "apply", "-f", + "./moduletemplate/mandatory_moduletemplate_template_operator_v2.yaml") + _, err := cmd.CombinedOutput() + Expect(err).NotTo(HaveOccurred()) + }) + It("Then Kyma mandatory Module is updated on SKR Cluster", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInNewerVersion, + TestModuleResourceNamespace). + Should(Succeed()) + + By("And old Module Operator Deployment is removed", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Equal(ErrNotFound)) + }) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Consistently(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + }) + + It("When the mandatory ModuleTemplate is removed", func() { + Eventually(DeleteCR). + WithContext(ctx). + WithArguments(kcpClient, + &v1beta2.ModuleTemplate{ + ObjectMeta: apimetav1.ObjectMeta{ + Name: "template-operator-mandatory", + Namespace: ControlPlaneNamespace, + }, + }). + Should(Succeed()) + }) + It("Then mandatory SKR module is removed", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInNewerVersion, + TestModuleResourceNamespace). + Should(Equal(ErrNotFound)) + + By("And the mandatory SKR Module Default CR is removed", func() { + Eventually(CheckIfExists). + WithContext(ctx). + WithArguments(TestModuleCRName, RemoteNamespace, + templatev1alpha1.GroupVersion.Group, "v1alpha1", string(templatev1alpha1.SampleKind), + skrClient). + Should(Equal(ErrNotFound)) + }) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Eventually(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + }) + }) +}) diff --git a/tests/e2e/mandatory_modules_metrics_test.go b/tests/e2e/mandatory_modules_metrics_test.go index fe35ce6638..091c22954a 100644 --- a/tests/e2e/mandatory_modules_metrics_test.go +++ b/tests/e2e/mandatory_modules_metrics_test.go @@ -19,6 +19,7 @@ var _ = Describe("Mandatory Module Metrics", Ordered, func() { CleanupKymaAfterAll(kyma) Context("Given SKR Cluster", func() { + //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory module is installed on the SKR cluster", func() { Eventually(DeploymentIsReady). WithContext(ctx). @@ -58,12 +59,25 @@ var _ = Describe("Mandatory Module Metrics", Ordered, func() { WithArguments(kcpClient, &v1beta2.ModuleTemplate{ ObjectMeta: apimetav1.ObjectMeta{ - Name: "template-operator-mandatory", + Name: "template-operator-1.0.0-smoke-test", + Namespace: "kcp-system", + }, + }). + Should(Succeed()) + + Eventually(DeleteCR). + WithContext(ctx). + WithArguments(kcpClient, + &v1beta2.ModuleTemplate{ + ObjectMeta: apimetav1.ObjectMeta{ + Name: "template-operator-1.1.0-smoke-test", Namespace: "kcp-system", }, }). Should(Succeed()) }) + + //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory SKR module is removed", func() { Eventually(DeploymentIsReady). WithContext(ctx). diff --git a/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go b/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go new file mode 100644 index 0000000000..af1ef4a6d4 --- /dev/null +++ b/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go @@ -0,0 +1,105 @@ +package e2e_test + +import ( + apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/kyma-project/lifecycle-manager/api/v1beta2" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "github.com/kyma-project/lifecycle-manager/pkg/testutils" +) + +var _ = Describe("Mandatory Module Without Version In Naming Metrics", Ordered, func() { + kyma := NewKymaWithSyncLabel("kyma-sample", "kcp-system", v1beta2.DefaultChannel) + + InitEmptyKymaBeforeAll(kyma) + CleanupKymaAfterAll(kyma) + + Context("Given SKR Cluster", func() { + //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 + It("Then mandatory module is installed on the SKR cluster", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Succeed()) + By("And the SKR Module Default CR is in a \"Ready\" State", func() { + Eventually(CheckSampleCRIsInState). + WithContext(ctx). + WithArguments("sample-yaml", "kyma-system", skrClient, shared.StateReady). + Should(Succeed()) + }) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Eventually(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + + By("And count of Mandatory Module State Metric in \"Ready\" State is 1", func() { + Eventually(GetMandatoryModuleStateMetric). + WithContext(ctx). + WithArguments(kyma.GetName(), TestModuleName, string(shared.StateReady)). + Should(Equal(1)) + }) + + By("And count of Mandatory ModuleTemplates Metric is 1", func() { + Eventually(GetMandatoryModuleTemplateCountMetric). + WithContext(ctx). + Should(Equal(1)) + }) + }) + + It("When the mandatory ModuleTemplate is removed", func() { + Eventually(DeleteCR). + WithContext(ctx). + WithArguments(kcpClient, + &v1beta2.ModuleTemplate{ + ObjectMeta: apimetav1.ObjectMeta{ + Name: "template-operator-mandatory", + Namespace: "kcp-system", + }, + }). + Should(Succeed()) + }) + + //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 + It("Then mandatory SKR module is removed", func() { + Eventually(DeploymentIsReady). + WithContext(ctx). + WithArguments(skrClient, ModuleDeploymentNameInOlderVersion, + TestModuleResourceNamespace). + Should(Equal(ErrNotFound)) + + By("And the mandatory SKR Module Default CR is removed", func() { + Eventually(CheckIfExists). + WithContext(ctx). + WithArguments("sample-yaml", "kyma-system", + "operator.kyma-project.io", "v1alpha1", "Sample", skrClient). + Should(Equal(ErrNotFound)) + }) + By("And the KCP Kyma CR is in a \"Ready\" State", func() { + Eventually(KymaIsInState). + WithContext(ctx). + WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). + Should(Succeed()) + }) + + By("And count of Mandatory Module State Metric in \"Ready\" State is 0", func() { + Eventually(GetMandatoryModuleStateMetric). + WithContext(ctx). + WithArguments(kyma.GetName(), TestModuleName, string(shared.StateReady)). + Should(Equal(0)) + }) + + By("And count of Mandatory ModuleTemplates Metric is 0", func() { + Eventually(GetMandatoryModuleTemplateCountMetric). + WithContext(ctx). + Should(Equal(0)) + }) + }) + }) +}) From 6a91453bfdafbccc08dc764bb2f63616fafe2dbb Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 13:52:10 +0100 Subject: [PATCH 12/22] debug E2E test --- pkg/testutils/metrics.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/testutils/metrics.go b/pkg/testutils/metrics.go index 8cea4aa988..9b2769493f 100644 --- a/pkg/testutils/metrics.go +++ b/pkg/testutils/metrics.go @@ -11,6 +11,7 @@ import ( "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/internal/pkg/metrics" + "github.com/onsi/ginkgo/v2" ) var ErrMetricNotFound = errors.New("metric was not found") @@ -139,7 +140,10 @@ func GetMandatoryModuleTemplateCountMetric(ctx context.Context) (int, error) { } re := regexp.MustCompile(metrics.MetricMandatoryTemplateCount + ` (\d+)`) - return parseCount(re, bodyString) + c, _ := parseCount(re, bodyString) + ginkgo.GinkgoWriter.Printf("Mandatory Module Template Count Metric: %d\n", c) + + return c, nil } func GetMandatoryModuleStateMetric(ctx context.Context, kymaName, moduleName, state string) (int, error) { From ac033e40d8a3bdc85ee1686384945e49d2ba2cfb Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 13:56:15 +0100 Subject: [PATCH 13/22] debug E2E test --- tests/e2e/mandatory_module_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index 26879b4ba6..7fe16e78c7 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -165,8 +165,9 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }) It("When new version of ModuleTemplate is applied", func() { - cmd := exec.Command("kubectl", "apply", "-f", - "./moduletemplate/mandatory_moduletemplate_template_operator_v2.yaml") + cmd := exec.Command("../../scripts/tests/deploy_moduletemplate.sh", "${{ env.ModuleName }}", + "${{ env.NewerVersionForMandatoryModule }}", + "true", "true") _, err := cmd.CombinedOutput() Expect(err).NotTo(HaveOccurred()) }) From 87a8cf3b22bfc7530f721f87cc1339b8762937d1 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 14:19:57 +0100 Subject: [PATCH 14/22] debug E2E test --- .../actions/deploy-lifecycle-manager-e2e/action.yml | 3 ++- .../action.yml | 11 ++++++++++- pkg/testutils/metrics.go | 6 +----- scripts/tests/deploy_moduletemplate.sh | 8 ++++++-- tests/e2e/mandatory_module_test.go | 12 +++++++++--- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/.github/actions/deploy-lifecycle-manager-e2e/action.yml b/.github/actions/deploy-lifecycle-manager-e2e/action.yml index c5a5535f50..6d37fa86b2 100644 --- a/.github/actions/deploy-lifecycle-manager-e2e/action.yml +++ b/.github/actions/deploy-lifecycle-manager-e2e/action.yml @@ -109,7 +109,8 @@ runs: matrix.e2e-test == 'module-status-decoupling-with-deployment' || matrix.e2e-test == 'purge-metrics' || matrix.e2e-test == 'self-signed-certificate-rotation' || - matrix.e2e-test == 'mandatory-module-metrics'}} + matrix.e2e-test == 'mandatory-module-metrics' || + matrix.e2e-test == 'mandatory-module-metrics-without-version-naming'}} shell: bash run: | kubectl patch svc klm-controller-manager-metrics -p '{"spec": {"type": "LoadBalancer"}}' -n kcp-system diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index 5085637208..c29de28b99 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -80,7 +80,7 @@ runs: run: | ./deploy_modulereleasemeta.sh ${{ env.ModuleName }} fast:${{ env.NewerVersion }} regular:${{ env.OlderVersion }} - - name: Create Template Operator Module in two versions as Mandatory Module + - name: Create and apply Template Operator Module in two versions as Mandatory Module working-directory: template-operator if: ${{ matrix.e2e-test == 'mandatory-module' || matrix.e2e-test == 'mandatory-module-metrics' @@ -94,6 +94,15 @@ runs: make build-manifests yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true + - name: Create ModuleTemplate in a new version for Mandatory module + if: ${{ matrix.e2e-test == 'mandatory-module'}} + working-directory: template-operator + shell: bash + run: | + make build-manifests + yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml + ./deploy_moduletemplate.sh ${{ env.ModuleName }} 2.4.1-smoke-test true true false + cp template.yaml ../lifecycle-manager/tests/e2e/mandatory_template_v2.yaml - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel working-directory: template-operator if: ${{ matrix.e2e-test == 'non-blocking-deletion' }} diff --git a/pkg/testutils/metrics.go b/pkg/testutils/metrics.go index 9b2769493f..8cea4aa988 100644 --- a/pkg/testutils/metrics.go +++ b/pkg/testutils/metrics.go @@ -11,7 +11,6 @@ import ( "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/internal/pkg/metrics" - "github.com/onsi/ginkgo/v2" ) var ErrMetricNotFound = errors.New("metric was not found") @@ -140,10 +139,7 @@ func GetMandatoryModuleTemplateCountMetric(ctx context.Context) (int, error) { } re := regexp.MustCompile(metrics.MetricMandatoryTemplateCount + ` (\d+)`) - c, _ := parseCount(re, bodyString) - ginkgo.GinkgoWriter.Printf("Mandatory Module Template Count Metric: %d\n", c) - - return c, nil + return parseCount(re, bodyString) } func GetMandatoryModuleStateMetric(ctx context.Context, kymaName, moduleName, state string) (int, error) { diff --git a/scripts/tests/deploy_moduletemplate.sh b/scripts/tests/deploy_moduletemplate.sh index 8671c68b17..f70edce432 100755 --- a/scripts/tests/deploy_moduletemplate.sh +++ b/scripts/tests/deploy_moduletemplate.sh @@ -8,6 +8,7 @@ MODULE_NAME=$1 RELEASE_VERSION=$2 INCLUDE_DEFAULT_CR=${3:-true} MANDATORY=${4:-false} +DEPLOY_MODULETEMPLATE=${5:-true} cat < module-config-for-e2e.yaml name: kyma-project.io/module/${MODULE_NAME} @@ -36,13 +37,16 @@ fi cat module-config-for-e2e.yaml modulectl create --config-file ./module-config-for-e2e.yaml --registry http://localhost:5111 --insecure sed -i 's/localhost:5111/k3d-kcp-registry.localhost:5000/g' ./template.yaml -kubectl apply -f template.yaml cat template.yaml echo "ModuleTemplate created successfully" +if [ "${DEPLOY_MODULETEMPLATE}" == "true" ]; then +kubectl apply -f template.yaml +rm -f template.yaml +fi + rm -f module-config-for-e2e.yaml rm -f template-operator.yaml -rm -f template.yaml rm -f default-sample-cr.yaml echo "Temporary files removed successfully" diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index 7fe16e78c7..46ce32aa50 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -165,9 +165,8 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }) It("When new version of ModuleTemplate is applied", func() { - cmd := exec.Command("../../scripts/tests/deploy_moduletemplate.sh", "${{ env.ModuleName }}", - "${{ env.NewerVersionForMandatoryModule }}", - "true", "true") + cmd := exec.Command("kubectl", "-f", + "mandatory_template_v2.yaml") _, err := cmd.CombinedOutput() Expect(err).NotTo(HaveOccurred()) }) @@ -191,6 +190,13 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { WithArguments(kyma.GetName(), kyma.GetNamespace(), kcpClient, shared.StateReady). Should(Succeed()) }) + + By("And the mandatory module manifest is installed with the correct version", func() { + Consistently(MandatoryModuleManifestExistWithCorrectVersion). + WithContext(ctx). + WithArguments(kcpClient, "template-operator", "2.4.1-smoke-test"). + Should(Succeed()) + }) }) It("When the mandatory ModuleTemplate is removed", func() { From e9cd3d284c98c342bff3087c09434857806e8b24 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 15:35:02 +0100 Subject: [PATCH 15/22] Fix E2E test --- tests/e2e/mandatory_module_test.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index b7637178a9..3b0dbe6625 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -199,7 +199,7 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }) }) - It("When the mandatory ModuleTemplate is removed", func() { + It("When the mandatory ModuleTemplates are removed", func() { Eventually(DeleteCR). WithContext(ctx). WithArguments(kcpClient, @@ -221,6 +221,17 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }, }). Should(Succeed()) + + Eventually(DeleteCR). + WithContext(ctx). + WithArguments(kcpClient, + &v1beta2.ModuleTemplate{ + ObjectMeta: apimetav1.ObjectMeta{ + Name: "template-operator-2.4.1-smoke-test", + Namespace: ControlPlaneNamespace, + }, + }). + Should(Succeed()) }) It("Then mandatory SKR module is removed", func() { Eventually(DeploymentIsReady). From 38f86a8d33135821a6536fcdf99ec5e378d7b276 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 15:39:56 +0100 Subject: [PATCH 16/22] Add documentation --- docs/contributor/02-controllers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributor/02-controllers.md b/docs/contributor/02-controllers.md index e7467f261f..25f6d1583e 100644 --- a/docs/contributor/02-controllers.md +++ b/docs/contributor/02-controllers.md @@ -40,7 +40,7 @@ Lifecycle Manager uses two Mandatory Modules Controllers: * [Mandatory modules installation controller](../../internal/controller/mandatorymodule/installation_controller.go) deals with the reconciliation of mandatory modules * [Mandatory modules deletion controller](../../internal/controller/mandatorymodule/deletion_controller.go) deals with the deletion of mandatory modules -Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs without any channel filtering. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), +Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs without any channel filtering. The ModuleTemplates with the label 'operator.kyma-project.io/mandatory-module' are fetched, if there are multiple ModuleTemplates for the same mandatory module, the Controller fetches the ModuleTemplate with the highest version. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), it propagates changes from the ModuleTemplate CR to the Manifest CR. The mandatory ModuleTemplate CR is not synchronized to the remote cluster and the module status does not appear in the Kyma CR status. If a mandatory module needs to be removed from all clusters, the corresponding ModuleTemplate CR needs to be deleted. The Mandatory Module Deletion Controller picks this event up and marks all associated Manifest CRs for deletion. To ensure that the ModuleTemplate CR is not removed immediately, the controller adds a finalizer to the ModuleTemplate CR. Once all associated Manifest CRs are deleted, the finalizer is removed and the ModuleTemplate CR is deleted. ## Manifest Controller From 99b606b0166d8dc5bbf737600773154820adbfb6 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 16:00:10 +0100 Subject: [PATCH 17/22] Fix E2E test --- .../action.yml | 11 ++++------- .github/workflows/test-e2e-with-modulereleasemeta.yml | 2 +- tests/e2e/mandatory_module_test.go | 11 ----------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml index c29de28b99..77ccaa2280 100644 --- a/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml +++ b/.github/actions/deploy-template-operator-with-modulereleasemeta/action.yml @@ -80,20 +80,17 @@ runs: run: | ./deploy_modulereleasemeta.sh ${{ env.ModuleName }} fast:${{ env.NewerVersion }} regular:${{ env.OlderVersion }} - - name: Create and apply Template Operator Module in two versions as Mandatory Module + - name: Create and apply Template Operator Module as Mandatory Module working-directory: template-operator if: ${{ matrix.e2e-test == 'mandatory-module' || matrix.e2e-test == 'mandatory-module-metrics' }} shell: bash run: | - make build-manifests - yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml - ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true - make build-manifests yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInOlderVersion }}"' -i template-operator.yaml - ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true + ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.OlderVersionForMandatoryModule }} true true + - name: Create ModuleTemplate in a new version for Mandatory module if: ${{ matrix.e2e-test == 'mandatory-module'}} working-directory: template-operator @@ -101,7 +98,7 @@ runs: run: | make build-manifests yq eval '(. | select(.kind == "Deployment") | .metadata.name) = "${{ env.ModuleDeploymentNameInNewerVersion }}"' -i template-operator.yaml - ./deploy_moduletemplate.sh ${{ env.ModuleName }} 2.4.1-smoke-test true true false + ./deploy_moduletemplate.sh ${{ env.ModuleName }} ${{ env.NewerVersionForMandatoryModule }} true true false cp template.yaml ../lifecycle-manager/tests/e2e/mandatory_template_v2.yaml - name: Create and apply ModuleReleaseMeta Template Operator with newer version in fast channel and older version in regular channel working-directory: template-operator diff --git a/.github/workflows/test-e2e-with-modulereleasemeta.yml b/.github/workflows/test-e2e-with-modulereleasemeta.yml index 3731b512de..152297d628 100644 --- a/.github/workflows/test-e2e-with-modulereleasemeta.yml +++ b/.github/workflows/test-e2e-with-modulereleasemeta.yml @@ -116,7 +116,7 @@ jobs: NewerVersion: 2.4.2-e2e-test OlderVersion: 1.1.1-e2e-test OlderVersionForMandatoryModule: 1.0.0-smoke-test - NewerVersionForMandatoryModule: 1.1.0-smoke-test + NewerVersionForMandatoryModule: 2.4.1-smoke-test VersionForStatefulSetInWarning: 1.0.0-warning-statefulset VersionForDeploymentInWarning: 1.0.0-warning-deployment VersionForMisconfiguredDeploymentImage: 1.0.0-misconfigured-deployment diff --git a/tests/e2e/mandatory_module_test.go b/tests/e2e/mandatory_module_test.go index 3b0dbe6625..af03f8e8b8 100644 --- a/tests/e2e/mandatory_module_test.go +++ b/tests/e2e/mandatory_module_test.go @@ -200,17 +200,6 @@ var _ = Describe("Mandatory Module Installation and Deletion", Ordered, func() { }) It("When the mandatory ModuleTemplates are removed", func() { - Eventually(DeleteCR). - WithContext(ctx). - WithArguments(kcpClient, - &v1beta2.ModuleTemplate{ - ObjectMeta: apimetav1.ObjectMeta{ - Name: "template-operator-1.0.0-smoke-test", - Namespace: ControlPlaneNamespace, - }, - }). - Should(Succeed()) - Eventually(DeleteCR). WithContext(ctx). WithArguments(kcpClient, From 69e0db22f54fac2253b28adf5e88d20d587c0640 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 17:04:51 +0100 Subject: [PATCH 18/22] Fix deletion for multiple versioned --- .github/workflows/test-e2e-with-modulereleasemeta.yml | 2 +- .../controller/mandatorymodule/deletion_controller.go | 6 ++++-- tests/e2e/mandatory_modules_metrics_test.go | 11 ----------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test-e2e-with-modulereleasemeta.yml b/.github/workflows/test-e2e-with-modulereleasemeta.yml index 152297d628..520abf6d3e 100644 --- a/.github/workflows/test-e2e-with-modulereleasemeta.yml +++ b/.github/workflows/test-e2e-with-modulereleasemeta.yml @@ -115,7 +115,7 @@ jobs: ModuleDeploymentNameInOlderVersion: template-operator-v1-controller-manager NewerVersion: 2.4.2-e2e-test OlderVersion: 1.1.1-e2e-test - OlderVersionForMandatoryModule: 1.0.0-smoke-test + OlderVersionForMandatoryModule: 1.1.0-smoke-test NewerVersionForMandatoryModule: 2.4.1-smoke-test VersionForStatefulSetInWarning: 1.0.0-warning-statefulset VersionForDeploymentInWarning: 1.0.0-warning-deployment diff --git a/internal/controller/mandatorymodule/deletion_controller.go b/internal/controller/mandatorymodule/deletion_controller.go index 43e3c907c0..60929d3cd2 100644 --- a/internal/controller/mandatorymodule/deletion_controller.go +++ b/internal/controller/mandatorymodule/deletion_controller.go @@ -117,7 +117,7 @@ func (r *DeletionReconciler) getCorrespondingManifests(ctx context.Context, if err := r.List(ctx, manifests, &client.ListOptions{ Namespace: template.Namespace, LabelSelector: k8slabels.SelectorFromSet(k8slabels.Set{shared.IsMandatoryModule: "true"}), - }); err != nil { + }); client.IgnoreNotFound(err) != nil { return nil, fmt.Errorf("not able to list mandatory module manifests: %w", err) } @@ -136,7 +136,9 @@ func (r *DeletionReconciler) removeManifests(ctx context.Context, manifests []v1 return nil } -func filterManifestsByAnnotation(manifests []v1beta2.Manifest, annotationKey, annotationValue string) []v1beta2.Manifest { +func filterManifestsByAnnotation(manifests []v1beta2.Manifest, + annotationKey, annotationValue string, +) []v1beta2.Manifest { filteredManifests := make([]v1beta2.Manifest, 0) for _, manifest := range manifests { if manifest.Annotations[annotationKey] == annotationValue { diff --git a/tests/e2e/mandatory_modules_metrics_test.go b/tests/e2e/mandatory_modules_metrics_test.go index 091c22954a..59361ad26d 100644 --- a/tests/e2e/mandatory_modules_metrics_test.go +++ b/tests/e2e/mandatory_modules_metrics_test.go @@ -54,17 +54,6 @@ var _ = Describe("Mandatory Module Metrics", Ordered, func() { }) It("When the mandatory ModuleTemplate is removed", func() { - Eventually(DeleteCR). - WithContext(ctx). - WithArguments(kcpClient, - &v1beta2.ModuleTemplate{ - ObjectMeta: apimetav1.ObjectMeta{ - Name: "template-operator-1.0.0-smoke-test", - Namespace: "kcp-system", - }, - }). - Should(Succeed()) - Eventually(DeleteCR). WithContext(ctx). WithArguments(kcpClient, From f143650c11f3a48d7779d5e6e688ffb16c113a99 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 17:38:12 +0100 Subject: [PATCH 19/22] Fix linting --- tests/e2e/mandatory_modules_metrics_test.go | 3 +-- .../mandatory_modules_without_version_naming_metrics_test.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/e2e/mandatory_modules_metrics_test.go b/tests/e2e/mandatory_modules_metrics_test.go index 59361ad26d..37c12cab3f 100644 --- a/tests/e2e/mandatory_modules_metrics_test.go +++ b/tests/e2e/mandatory_modules_metrics_test.go @@ -1,3 +1,4 @@ +//nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 package e2e_test import ( @@ -19,7 +20,6 @@ var _ = Describe("Mandatory Module Metrics", Ordered, func() { CleanupKymaAfterAll(kyma) Context("Given SKR Cluster", func() { - //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory module is installed on the SKR cluster", func() { Eventually(DeploymentIsReady). WithContext(ctx). @@ -66,7 +66,6 @@ var _ = Describe("Mandatory Module Metrics", Ordered, func() { Should(Succeed()) }) - //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory SKR module is removed", func() { Eventually(DeploymentIsReady). WithContext(ctx). diff --git a/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go b/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go index af1ef4a6d4..26d4c06050 100644 --- a/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go +++ b/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go @@ -1,3 +1,4 @@ +//nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 package e2e_test import ( @@ -19,7 +20,6 @@ var _ = Describe("Mandatory Module Without Version In Naming Metrics", Ordered, CleanupKymaAfterAll(kyma) Context("Given SKR Cluster", func() { - //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory module is installed on the SKR cluster", func() { Eventually(DeploymentIsReady). WithContext(ctx). @@ -66,7 +66,6 @@ var _ = Describe("Mandatory Module Without Version In Naming Metrics", Ordered, Should(Succeed()) }) - //nolint:dupl //this test will be deleted during this issue https://github.com/kyma-project/lifecycle-manager/issues/2060 It("Then mandatory SKR module is removed", func() { Eventually(DeploymentIsReady). WithContext(ctx). From a18de2cf1da2079f914306a1abb273d4839580a9 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Mon, 16 Dec 2024 17:54:26 +0100 Subject: [PATCH 20/22] Fix deletion to handle multiple versions --- .../mandatorymodule/deletion_controller.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/controller/mandatorymodule/deletion_controller.go b/internal/controller/mandatorymodule/deletion_controller.go index 60929d3cd2..143c3bbbba 100644 --- a/internal/controller/mandatorymodule/deletion_controller.go +++ b/internal/controller/mandatorymodule/deletion_controller.go @@ -121,7 +121,13 @@ func (r *DeletionReconciler) getCorrespondingManifests(ctx context.Context, return nil, fmt.Errorf("not able to list mandatory module manifests: %w", err) } - filtered := filterManifestsByAnnotation(manifests.Items, shared.FQDN, descriptor.GetName()) + version, err := template.GetVersion() + if err != nil { + return nil, fmt.Errorf("not able to get version from template: %w", err) + } + + filtered := filterManifestsByAnnotationAndVersion(manifests.Items, shared.FQDN, descriptor.GetName(), + version.String()) return filtered, nil } @@ -136,12 +142,11 @@ func (r *DeletionReconciler) removeManifests(ctx context.Context, manifests []v1 return nil } -func filterManifestsByAnnotation(manifests []v1beta2.Manifest, - annotationKey, annotationValue string, -) []v1beta2.Manifest { +func filterManifestsByAnnotationAndVersion(manifests []v1beta2.Manifest, + annotationKey, annotationValue string, version string) []v1beta2.Manifest { filteredManifests := make([]v1beta2.Manifest, 0) for _, manifest := range manifests { - if manifest.Annotations[annotationKey] == annotationValue { + if manifest.Annotations[annotationKey] == annotationValue && manifest.Spec.Version == version { filteredManifests = append(filteredManifests, manifest) } } From ffe957b56efe63454974ffdc17bbecc31786a82e Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Tue, 17 Dec 2024 17:12:27 +0100 Subject: [PATCH 21/22] code review comments --- .github/actions/deploy-lifecycle-manager-e2e/action.yml | 2 +- .github/actions/deploy-template-operator/action.yml | 4 ++-- .github/workflows/test-e2e.yml | 4 ++-- docs/contributor/02-controllers.md | 2 +- pkg/templatelookup/mandatory.go | 9 +++++++-- pkg/templatelookup/mandatory_test.go | 6 +++--- tests/e2e/Makefile | 8 ++++---- ... => mandatory_module_with_old_naming_pattern_test.go} | 2 +- ...tory_modules_with_old_naming_pattern_metrics_test.go} | 2 +- 9 files changed, 22 insertions(+), 17 deletions(-) rename tests/e2e/{mandatory_module_without_version_naming_test.go => mandatory_module_with_old_naming_pattern_test.go} (98%) rename tests/e2e/{mandatory_modules_without_version_naming_metrics_test.go => mandatory_modules_with_old_naming_pattern_metrics_test.go} (97%) diff --git a/.github/actions/deploy-lifecycle-manager-e2e/action.yml b/.github/actions/deploy-lifecycle-manager-e2e/action.yml index 6d37fa86b2..38714fe8a6 100644 --- a/.github/actions/deploy-lifecycle-manager-e2e/action.yml +++ b/.github/actions/deploy-lifecycle-manager-e2e/action.yml @@ -110,7 +110,7 @@ runs: matrix.e2e-test == 'purge-metrics' || matrix.e2e-test == 'self-signed-certificate-rotation' || matrix.e2e-test == 'mandatory-module-metrics' || - matrix.e2e-test == 'mandatory-module-metrics-without-version-naming'}} + matrix.e2e-test == 'mandatory-module-metrics-with-old-naming-pattern'}} shell: bash run: | kubectl patch svc klm-controller-manager-metrics -p '{"spec": {"type": "LoadBalancer"}}' -n kcp-system diff --git a/.github/actions/deploy-template-operator/action.yml b/.github/actions/deploy-template-operator/action.yml index 53c0c68a69..3f403d5d18 100644 --- a/.github/actions/deploy-template-operator/action.yml +++ b/.github/actions/deploy-template-operator/action.yml @@ -47,8 +47,8 @@ runs: kubectl apply -f tests/e2e/moduletemplate/moduletemplate_template_operator_v2_direct_version.yaml - name: Create Template Operator Module as Mandatory Module working-directory: lifecycle-manager - if: ${{ matrix.e2e-test == 'mandatory-module-without-version-naming' || - matrix.e2e-test == 'mandatory-module-metrics-without-version-naming' + if: ${{ matrix.e2e-test == 'mandatory-module-with-old-naming-pattern' || + matrix.e2e-test == 'mandatory-module-metrics-with-old-naming-pattern' }} shell: bash run: | diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 76a21bedf1..7ccb95e697 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -58,8 +58,8 @@ jobs: - ca-certificate-rotation - istio-gateway-secret-rotation - self-signed-certificate-rotation - - mandatory-module-without-version-naming - - mandatory-module-metrics-without-version-naming + - mandatory-module-with-old-naming-pattern + - mandatory-module-metrics-with-old-naming-pattern - misconfigured-kyma-secret - rbac-privileges - ocm-compatible-module-template diff --git a/docs/contributor/02-controllers.md b/docs/contributor/02-controllers.md index 25f6d1583e..71a46a5f9c 100644 --- a/docs/contributor/02-controllers.md +++ b/docs/contributor/02-controllers.md @@ -40,7 +40,7 @@ Lifecycle Manager uses two Mandatory Modules Controllers: * [Mandatory modules installation controller](../../internal/controller/mandatorymodule/installation_controller.go) deals with the reconciliation of mandatory modules * [Mandatory modules deletion controller](../../internal/controller/mandatorymodule/deletion_controller.go) deals with the deletion of mandatory modules -Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs without any channel filtering. The ModuleTemplates with the label 'operator.kyma-project.io/mandatory-module' are fetched, if there are multiple ModuleTemplates for the same mandatory module, the Controller fetches the ModuleTemplate with the highest version. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), +Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs with the label 'operator.kyma-project.io/mandatory-module'. If there are multiple ModuleTemplates for the same mandatory module, the Controller fetches the ModuleTemplate with the highest version. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), it propagates changes from the ModuleTemplate CR to the Manifest CR. The mandatory ModuleTemplate CR is not synchronized to the remote cluster and the module status does not appear in the Kyma CR status. If a mandatory module needs to be removed from all clusters, the corresponding ModuleTemplate CR needs to be deleted. The Mandatory Module Deletion Controller picks this event up and marks all associated Manifest CRs for deletion. To ensure that the ModuleTemplate CR is not removed immediately, the controller adds a finalizer to the ModuleTemplate CR. Once all associated Manifest CRs are deleted, the finalizer is removed and the ModuleTemplate CR is deleted. ## Manifest Controller diff --git a/pkg/templatelookup/mandatory.go b/pkg/templatelookup/mandatory.go index ba2d6d7c01..599868e20e 100644 --- a/pkg/templatelookup/mandatory.go +++ b/pkg/templatelookup/mandatory.go @@ -23,6 +23,7 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate return nil, fmt.Errorf("could not list mandatory ModuleTemplates: %w", err) } + // maps module name to the module template of the highest version encountered mandatoryModules := make(map[string]*ModuleTemplateInfo) for _, moduleTemplate := range mandatoryModuleTemplateList.Items { if moduleTemplate.DeletionTimestamp.IsZero() { @@ -30,7 +31,7 @@ func GetMandatory(ctx context.Context, kymaClient client.Reader) (ModuleTemplate moduleName := GetModuleName(currentModuleTemplate) if mandatoryModules[moduleName] != nil { var err error - currentModuleTemplate, err = GetDesiredModuleTemplateForMultipleVersions(currentModuleTemplate, + currentModuleTemplate, err = GetModuleTemplateWithHigherVersion(currentModuleTemplate, mandatoryModules[moduleName].ModuleTemplate) if err != nil { mandatoryModules[moduleName] = &ModuleTemplateInfo{ @@ -54,6 +55,8 @@ func GetModuleName(moduleTemplate *v1beta2.ModuleTemplate) string { return moduleTemplate.Spec.ModuleName } + // https://github.com/kyma-project/lifecycle-manager/issues/2135 + // Remove this after warden ModuleTemplate is created using modulectl return moduleTemplate.Labels[shared.ModuleName] } @@ -67,6 +70,8 @@ func GetModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Ver return version, nil } + // https://github.com/kyma-project/lifecycle-manager/issues/2135 + // Remove this after warden ModuleTemplate is created using modulectl version, err := semver.NewVersion(moduleTemplate.Annotations[shared.ModuleVersionAnnotation]) if err != nil { return nil, fmt.Errorf("could not parse version as a semver %s: %w", @@ -75,7 +80,7 @@ func GetModuleSemverVersion(moduleTemplate *v1beta2.ModuleTemplate) (*semver.Ver return version, nil } -func GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, +func GetModuleTemplateWithHigherVersion(firstModuleTemplate, secondModuleTemplate *v1beta2.ModuleTemplate) (*v1beta2.ModuleTemplate, error, ) { firstVersion, err := GetModuleSemverVersion(firstModuleTemplate) diff --git a/pkg/templatelookup/mandatory_test.go b/pkg/templatelookup/mandatory_test.go index 997d18488e..03ba8ffb81 100644 --- a/pkg/templatelookup/mandatory_test.go +++ b/pkg/templatelookup/mandatory_test.go @@ -22,11 +22,11 @@ func TestGetDesiredModuleTemplateForMultipleVersions_ReturnCorrectValue(t *testi secondModuleTemplate := builder.NewModuleTemplateBuilder(). WithName("warden-1.0.1-dev"). - WithVersion("1.0.1-dev"). WithLabel("module-diff", "second"). + WithAnnotation("operator.kyma-project.io/module-version", "1.0.1-dev"). Build() - result, err := templatelookup.GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate) + result, err := templatelookup.GetModuleTemplateWithHigherVersion(firstModuleTemplate, secondModuleTemplate) require.NoError(t, err) require.Equal(t, secondModuleTemplate, result) } @@ -44,7 +44,7 @@ func TestGetDesiredModuleTemplateForMultipleVersions_ReturnError_NotSemver(t *te WithLabel("module-diff", "second"). Build() - result, err := templatelookup.GetDesiredModuleTemplateForMultipleVersions(firstModuleTemplate, secondModuleTemplate) + result, err := templatelookup.GetModuleTemplateWithHigherVersion(firstModuleTemplate, secondModuleTemplate) require.ErrorContains(t, err, "could not parse version as a semver") require.Nil(t, result) } diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 953687c4f1..1ff6225ea9 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -79,8 +79,8 @@ kyma-metrics: mandatory-module-metrics: go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Metrics" -mandatory-module-metrics-without-version-naming: - go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Without Version In Naming Metrics" +mandatory-module-metrics-with-old-naming-pattern: + go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module With Old Naming Pattern Metrics" watcher-enqueue: go test -timeout 20m -ginkgo.v -ginkgo.focus "Enqueue Event from Watcher" @@ -100,8 +100,8 @@ module-consistency: mandatory-module: go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Installation and Deletion" -mandatory-module-without-version-naming: - go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module Without Version In Naming Installation and Deletion" +mandatory-module-with-old-naming-pattern: + go test -timeout 20m -ginkgo.v -ginkgo.focus "Mandatory Module With Old Naming Pattern Installation and Deletion" non-blocking-deletion: go test -timeout 20m -ginkgo.v -ginkgo.focus "Non Blocking Kyma Module Deletion" diff --git a/tests/e2e/mandatory_module_without_version_naming_test.go b/tests/e2e/mandatory_module_with_old_naming_pattern_test.go similarity index 98% rename from tests/e2e/mandatory_module_without_version_naming_test.go rename to tests/e2e/mandatory_module_with_old_naming_pattern_test.go index 9d9a0cd0f5..12366a2e47 100644 --- a/tests/e2e/mandatory_module_without_version_naming_test.go +++ b/tests/e2e/mandatory_module_with_old_naming_pattern_test.go @@ -13,7 +13,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Mandatory Module Without Version In Naming Installation and Deletion", Ordered, func() { +var _ = Describe("Mandatory Module With Old Naming Pattern Installation and Deletion", Ordered, func() { kyma := NewKymaWithSyncLabel("kyma-sample", ControlPlaneNamespace, v1beta2.DefaultChannel) InitEmptyKymaBeforeAll(kyma) diff --git a/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go b/tests/e2e/mandatory_modules_with_old_naming_pattern_metrics_test.go similarity index 97% rename from tests/e2e/mandatory_modules_without_version_naming_metrics_test.go rename to tests/e2e/mandatory_modules_with_old_naming_pattern_metrics_test.go index 26d4c06050..17d3b881b5 100644 --- a/tests/e2e/mandatory_modules_without_version_naming_metrics_test.go +++ b/tests/e2e/mandatory_modules_with_old_naming_pattern_metrics_test.go @@ -13,7 +13,7 @@ import ( . "github.com/kyma-project/lifecycle-manager/pkg/testutils" ) -var _ = Describe("Mandatory Module Without Version In Naming Metrics", Ordered, func() { +var _ = Describe("Mandatory Module With Old Naming Pattern Metrics", Ordered, func() { kyma := NewKymaWithSyncLabel("kyma-sample", "kcp-system", v1beta2.DefaultChannel) InitEmptyKymaBeforeAll(kyma) From bd7d58ce0551e09f4445bacd45fc9ab7423added Mon Sep 17 00:00:00 2001 From: Nesma Badr Date: Wed, 18 Dec 2024 09:18:38 +0100 Subject: [PATCH 22/22] Update docs/contributor/02-controllers.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Małgorzata Świeca --- docs/contributor/02-controllers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributor/02-controllers.md b/docs/contributor/02-controllers.md index 71a46a5f9c..848af9bc9c 100644 --- a/docs/contributor/02-controllers.md +++ b/docs/contributor/02-controllers.md @@ -40,7 +40,7 @@ Lifecycle Manager uses two Mandatory Modules Controllers: * [Mandatory modules installation controller](../../internal/controller/mandatorymodule/installation_controller.go) deals with the reconciliation of mandatory modules * [Mandatory modules deletion controller](../../internal/controller/mandatorymodule/deletion_controller.go) deals with the deletion of mandatory modules -Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs with the label 'operator.kyma-project.io/mandatory-module'. If there are multiple ModuleTemplates for the same mandatory module, the Controller fetches the ModuleTemplate with the highest version. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), +Since the channel concept does not apply to mandatory modules, the Mandatory Modules Installation Controller fetches all the Mandatory ModuleTemplate CRs with the 'operator.kyma-project.io/mandatory-module' label. If multiple ModuleTemplates exist for the same mandatory module, the Controller fetches the ModuleTemplate with the highest version. It then translates the ModuleTemplate CR for the mandatory module to a [Manifest CR](../../api/v1beta2/manifest_types.go) with an OwnerReference to the Kyma CR. Similarly to the [Kyma Controller](../../internal/controller/kyma/controller.go), it propagates changes from the ModuleTemplate CR to the Manifest CR. The mandatory ModuleTemplate CR is not synchronized to the remote cluster and the module status does not appear in the Kyma CR status. If a mandatory module needs to be removed from all clusters, the corresponding ModuleTemplate CR needs to be deleted. The Mandatory Module Deletion Controller picks this event up and marks all associated Manifest CRs for deletion. To ensure that the ModuleTemplate CR is not removed immediately, the controller adds a finalizer to the ModuleTemplate CR. Once all associated Manifest CRs are deleted, the finalizer is removed and the ModuleTemplate CR is deleted. ## Manifest Controller