Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Test the module-catalog-improvements changes #1895

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/actions/deploy-template-operator/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ runs:
run: |
kubectl apply -f tests/moduletemplates/moduletemplate_template_operator_v2_fast.yaml
kubectl apply -f tests/moduletemplates/moduletemplate_template_operator_v1_regular.yaml
- name: Create Template Operator Module for installation by version
working-directory: lifecycle-manager
if: ${{ matrix.e2e-test == 'module-install-by-version' }}
shell: bash
run: |
kubectl apply -f tests/moduletemplates/moduletemplate_template_operator_v2_fast.yaml
kubectl apply -f tests/moduletemplates/moduletemplate_template_operator_v1_regular.yaml
kubectl apply -f tests/moduletemplates/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' ||
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
- module-upgrade-channel-switch
- module-upgrade-new-version
- unmanage-module
- module-install-by-version
- skip-manifest-reconciliation
- ca-certificate-rotation
- self-signed-certificate-rotation
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To use Lifecycle Manager in a local setup, install the following:

### Steps

1. To set up the environment, provision a local k3d cluster and install Kyma. Run:
1. To set up the environment, provision a local k3d cluster and install Kyma. Run the following command:

```bash
k3d registry create kyma-registry --port 5001
Expand Down
2 changes: 2 additions & 0 deletions api-version-compatibility-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ operator.kyma-project.io_moduletemplates.yaml:
- .spec.properties.target
- .spec.required[]|select(.=="target")
v1beta2:
- .spec.properties.version
- .spec.properties.moduleName
- .spec.properties.customStateCheck.description
14 changes: 14 additions & 0 deletions api/shared/channel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package shared

import "strings"

type Channel string

const (
// NoneChannel when this value is defined for the ModuleTemplate, it means that the ModuleTemplate is not assigned to any channel.
NoneChannel Channel = "none"
)

func (c Channel) Equals(value string) bool {
return string(c) == strings.ToLower(value)
}
46 changes: 8 additions & 38 deletions api/v1beta2/kyma_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ type Module struct {
// +kubebuilder:validation:MinLength:=3
Channel string `json:"channel,omitempty"`

// Version is the desired version of the Module. If this changes or is set, it will be used to resolve a new
// ModuleTemplate based on this specific version.
// The Version and Channel are mutually exclusive options.
// The regular expression come from here: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
// json:"-" to disable installation of specific versions until decided to roll this out
// see https://github.com/kyma-project/lifecycle-manager/issues/1847
Version string `json:"-"`

// RemoteModuleTemplateRef is deprecated and will no longer have any functionality.
// It will be removed in the upcoming API version.
RemoteModuleTemplateRef string `json:"remoteModuleTemplateRef,omitempty"`
Expand Down Expand Up @@ -211,14 +219,6 @@ type PartialMeta struct {

const DefaultChannel = "regular"

func PartialMetaFromObject(object apimetav1.Object) PartialMeta {
return PartialMeta{
Name: object.GetName(),
Namespace: object.GetNamespace(),
Generation: object.GetGeneration(),
}
}

func (m PartialMeta) GetName() string {
return m.Name
}
Expand Down Expand Up @@ -389,36 +389,6 @@ func (kyma *Kyma) IsBeta() bool {
return found && shared.IsEnabled(beta)
}

type AvailableModule struct {
Module
Enabled bool
Unmanaged bool
}

func (kyma *Kyma) GetAvailableModules() []AvailableModule {
moduleMap := make(map[string]bool)
modules := make([]AvailableModule, 0)
for _, module := range kyma.Spec.Modules {
moduleMap[module.Name] = true
modules = append(modules, AvailableModule{Module: module, Enabled: true, Unmanaged: !module.Managed})
}

for _, module := range kyma.Status.Modules {
_, exist := moduleMap[module.Name]
if exist {
continue
}
modules = append(modules, AvailableModule{
Module: Module{
Name: module.Name,
Channel: module.Channel,
},
Enabled: false,
})
}
return modules
}

func (kyma *Kyma) EnsureLabelsAndFinalizers() bool {
if controllerutil.ContainsFinalizer(kyma, "foregroundDeletion") {
return false
Expand Down
51 changes: 51 additions & 0 deletions api/v1beta2/moduletemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package v1beta2

import (
"errors"
"fmt"
"strings"

"github.com/Masterminds/semver/v3"
"github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc"
apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -78,6 +81,18 @@ type ModuleTemplateSpec struct {
// +kubebuilder:validation:MinLength:=3
Channel string `json:"channel"`

// Version identifies the version of the Module. Can be empty, or a semantic version.
// +optional
// +kubebuilder:validation:Pattern:=`^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[a-zA-Z-][0-9a-zA-Z-]*)?)?$`
// +kubebuilder:validation:MaxLength:=32
Version string `json:"version"`

// ModuleName is the name of the Module. Can be empty.
// +optional
// +kubebuilder:validation:Pattern:=`^([a-z]{3,}(-[a-z]{3,})*)?$`
// +kubebuilder:validation:MaxLength:=64
ModuleName string `json:"moduleName"`

// Mandatory indicates whether the module is mandatory. It is used to enforce the installation of the module with
// its configuration in all runtime clusters.
// +optional
Expand Down Expand Up @@ -172,6 +187,42 @@ func (m *ModuleTemplate) IsInternal() bool {
return false
}

var ErrInvalidVersion = errors.New("can't find valid semantic version")

// getVersionLegacy() returns the version of the ModuleTemplate from the annotation on the object.
// Remove once shared.ModuleVersionAnnotation is removed
func (m *ModuleTemplate) getVersionLegacy() (string, error) {
if m.Annotations != nil {
moduleVersion, found := m.Annotations[shared.ModuleVersionAnnotation]
if found {
return moduleVersion, nil
}
}
return "", ErrInvalidVersion
}

// GetVersion returns the declared version of the ModuleTemplate from it's Spec.
func (m *ModuleTemplate) GetVersion() (*semver.Version, error) {
var versionValue string
var err error

if m.Spec.Version == "" {
versionValue, err = m.getVersionLegacy()
if err != nil {
return nil, err
}
} else {
versionValue = m.Spec.Version

}

version, err := semver.NewVersion(versionValue)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrInvalidVersion, err.Error())
}
return version, nil
}

func (m *ModuleTemplate) IsBeta() bool {
if isBeta, found := m.Labels[shared.BetaLabel]; found {
return strings.ToLower(isBeta) == shared.EnableLabelValue
Expand Down
105 changes: 105 additions & 0 deletions api/v1beta2/moduletemplate_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package v1beta2

import (
"strings"
"testing"

"github.com/kyma-project/lifecycle-manager/api/shared"
apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func Test_GetVersion(t *testing.T) {
const testVersion = "1.0.1"
const otherVersion = "0.0.1"
tests := []struct {
name string
m *ModuleTemplate
expectedVersion string
expectedErr string
}{
{
name: "Test GetVersion() by annotation (legacy)",
m: &ModuleTemplate{
ObjectMeta: apimetav1.ObjectMeta{
Annotations: map[string]string{
shared.ModuleVersionAnnotation: testVersion,
},
},
},
expectedVersion: testVersion,
},
{
name: "Test GetVersion() by explicit version in Spec",
m: &ModuleTemplate{
Spec: ModuleTemplateSpec{
Version: testVersion,
},
},
expectedVersion: testVersion,
},
{
name: "Test GetVersion() with both version in Spec and annotation",
m: &ModuleTemplate{
ObjectMeta: apimetav1.ObjectMeta{
Annotations: map[string]string{
shared.ModuleVersionAnnotation: otherVersion,
},
},
Spec: ModuleTemplateSpec{
Version: testVersion,
},
},
expectedVersion: testVersion,
},
{
name: "Test GetVersion without any version info",
m: &ModuleTemplate{
ObjectMeta: apimetav1.ObjectMeta{
Annotations: map[string]string{},
},
Spec: ModuleTemplateSpec{},
},
expectedErr: ErrInvalidVersion.Error(),
},
{
name: "Test GetVersion with invalid version",
m: &ModuleTemplate{
Spec: ModuleTemplateSpec{
Version: "invalid",
},
},
expectedErr: "Invalid Semantic Version",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
tt := tt
actualVersion, err := tt.m.GetVersion()
if err != nil {
if actualVersion != nil {
t.Errorf("GetVersion(): Returned version should be nil when error is not nil")
}
if tt.expectedErr == "" {
t.Errorf("GetVersion(): Unexpected error: %v", err)
}
if !strings.Contains(err.Error(), tt.expectedErr) {
t.Errorf("GetVersion(): Actual error = %v, expected error: %v", err, tt.expectedErr)
}
return
}

if actualVersion == nil {
t.Errorf("GetVersion(): Returned version should not be nil when error is nil")
}

if tt.expectedVersion == "" {
t.Errorf("GetVersion(): Expected version is empty but non-nil version is returned")
}

if actualVersion.String() != tt.expectedVersion {
t.Errorf("GetVersion(): actual version = %v, expected version: %v", actualVersion.String(), tt.expectedVersion)
}
})
}
}
16 changes: 0 additions & 16 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions config/crd/bases/operator.kyma-project.io_moduletemplates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,17 @@ spec:
Mandatory indicates whether the module is mandatory. It is used to enforce the installation of the module with
its configuration in all runtime clusters.
type: boolean
moduleName:
description: ModuleName is the name of the Module. Can be empty.
maxLength: 64
pattern: ^([a-z]{3,}(-[a-z]{3,})*)?$
type: string
version:
description: Version identifies the version of the Module. Can be
empty, or a semantic version.
maxLength: 32
pattern: ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[a-zA-Z-][0-9a-zA-Z-]*)?)?$
type: string
required:
- channel
- descriptor
Expand Down
Loading
Loading