Skip to content

Commit

Permalink
fix: Add module version annotation to the ModuleTemplate (#1799)
Browse files Browse the repository at this point in the history
* add test

* Addressing test comment

* PR comments
  • Loading branch information
nesmabadr authored Oct 9, 2023
1 parent 5145bb1 commit dd62557
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 26 deletions.
61 changes: 40 additions & 21 deletions cmd/kyma/alpha/create/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"context"
"errors"
"fmt"
"maps"
"os"
"path/filepath"
"strings"

"github.com/kyma-project/lifecycle-manager/api/v1beta2"
"github.com/mandelsoft/vfs/pkg/memoryfs"
"github.com/mandelsoft/vfs/pkg/osfs"
"github.com/mandelsoft/vfs/pkg/vfs"
Expand All @@ -16,7 +18,6 @@ import (
"github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/comparch"
"github.com/spf13/cobra"
"go.uber.org/zap"
"golang.org/x/exp/maps"
"gopkg.in/yaml.v3"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"

Expand Down Expand Up @@ -382,29 +383,9 @@ func (cmd *command) Run(ctx context.Context) error {

cmd.NewStep("Generating module template")

labels := map[string]string{}
annotations := map[string]string{}

var resourceName = ""

if modCnf != nil {
resourceName = modCnf.ResourceName

maps.Copy(labels, modCnf.Labels)
maps.Copy(annotations, modCnf.Annotations)

if modCnf.Beta {
labels["operator.kyma-project.io/beta"] = "true"
}
if modCnf.Internal {
labels["operator.kyma-project.io/internal"] = "true"
}
}
isClusterScoped := isCrdClusterScoped(crValidator.GetCrd())
if isClusterScoped {
annotations["operator.kyma-project.io/is-cluster-scoped"] = "true"
} else {
annotations["operator.kyma-project.io/is-cluster-scoped"] = "false"
}

var channel = cmd.opts.Channel
Expand All @@ -417,6 +398,9 @@ func (cmd *command) Run(ctx context.Context) error {
namespace = modCnf.Namespace
}

labels := cmd.getModuleTemplateLabels(modCnf)
annotations := cmd.getModuleTemplateAnnotations(modCnf, crValidator)

t, err := module.Template(componentVersionAccess, resourceName, namespace,
channel, modDef.DefaultCR, labels, annotations, modDef.CustomStateChecks)

Expand All @@ -435,6 +419,41 @@ func (cmd *command) Run(ctx context.Context) error {
return nil
}

func (cmd *command) getModuleTemplateLabels(modCnf *Config) map[string]string {
labels := map[string]string{}
if modCnf != nil {
maps.Copy(labels, modCnf.Labels)

if modCnf.Beta {
labels[v1beta2.BetaLabel] = v1beta2.EnableLabelValue
}
if modCnf.Internal {
labels[v1beta2.InternalLabel] = v1beta2.EnableLabelValue
}
}

return labels
}

func (cmd *command) getModuleTemplateAnnotations(modCnf *Config, crValidator validator) map[string]string {
annotations := map[string]string{}
moduleVersion := cmd.opts.Version
if modCnf != nil {
maps.Copy(annotations, modCnf.Annotations)

moduleVersion = modCnf.Version
}

isClusterScoped := isCrdClusterScoped(crValidator.GetCrd())
if isClusterScoped {
annotations[v1beta2.IsClusterScopedAnnotation] = v1beta2.EnableLabelValue
} else {
annotations[v1beta2.IsClusterScopedAnnotation] = v1beta2.DisableLabelValue
}
annotations["operator.kyma-project.io/module-version"] = moduleVersion
return annotations
}

func (cmd *command) validateDefaultCR(ctx context.Context, modDef *module.Definition, l *zap.SugaredLogger) (validator, error) {
cmd.NewStep("Validating Default CR")

Expand Down
162 changes: 162 additions & 0 deletions cmd/kyma/alpha/create/module/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ package module

import (
_ "embed"
"reflect"
"testing"

"github.com/kyma-project/cli/internal/cli"
"github.com/kyma-project/cli/pkg/module"
"github.com/kyma-project/lifecycle-manager/api/v1beta2"
)

//go:embed testdata/clusterScopedCRD.yaml
Expand Down Expand Up @@ -43,3 +48,160 @@ func Test_isCrdClusterScoped(t *testing.T) {
})
}
}

func Test_command_getModuleTemplateLabels(t *testing.T) {
type fields struct {
Command cli.Command
opts *Options
}
type args struct {
modCnf *Config
}
tests := []struct {
name string
fields fields
args args
want map[string]string
}{
{
name: "beta module with moduleConfig labels set",
fields: fields{
opts: &Options{},
},
args: args{
modCnf: &Config{
Beta: true,
Labels: map[string]string{
"label1": "value1",
"label2": "value2",
},
Version: "1.1.1",
},
},
want: map[string]string{
"label1": "value1",
"label2": "value2",
v1beta2.BetaLabel: v1beta2.EnableLabelValue,
},
},
{
name: "internal module",
fields: fields{
opts: &Options{},
},
args: args{
modCnf: &Config{
Internal: true,
Version: "1.1.1",
},
},
want: map[string]string{
v1beta2.InternalLabel: v1beta2.EnableLabelValue,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := &command{
Command: tt.fields.Command,
opts: tt.fields.opts,
}
if got := cmd.getModuleTemplateLabels(tt.args.modCnf); !reflect.DeepEqual(got, tt.want) {
t.Errorf("getModuleTemplateLabels() = %v, want %v", got, tt.want)
}
})
}
}

func Test_command_getModuleTemplateAnnotations(t *testing.T) {
type fields struct {
Command cli.Command
opts *Options
}
type args struct {
modCnf *Config
crValidator validator
}
tests := []struct {
name string
fields fields
args args
want map[string]string
}{
{
name: "module with moduleConfig annotations set",
fields: fields{
opts: &Options{},
},
args: args{
modCnf: &Config{
Internal: true,
Annotations: map[string]string{
"annotation1": "value1",
"annotation2": "value2",
},
Version: "1.1.1",
},
crValidator: &module.SingleManifestFileCRValidator{
Crd: namespacedScopedCrd,
},
},
want: map[string]string{
"annotation1": "value1",
"annotation2": "value2",
"operator.kyma-project.io/module-version": "1.1.1",
v1beta2.IsClusterScopedAnnotation: v1beta2.DisableLabelValue,
},
},
{
name: "cluster scoped module with moduleConfig annotations set",
fields: fields{
opts: &Options{},
},
args: args{
modCnf: &Config{
Annotations: map[string]string{
"annotation1": "value1",
"annotation2": "value2",
},
Version: "1.1.1",
},
crValidator: &module.SingleManifestFileCRValidator{
Crd: clusterScopedCrd,
},
},
want: map[string]string{
"annotation1": "value1",
"annotation2": "value2",
v1beta2.IsClusterScopedAnnotation: v1beta2.EnableLabelValue,
"operator.kyma-project.io/module-version": "1.1.1",
},
},
{
name: "module versions set from version flag",
fields: fields{
opts: &Options{Version: "1.0.0"},
},
args: args{
crValidator: &module.SingleManifestFileCRValidator{
Crd: namespacedScopedCrd,
},
},
want: map[string]string{
"operator.kyma-project.io/module-version": "1.0.0",
v1beta2.IsClusterScopedAnnotation: v1beta2.DisableLabelValue,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := &command{
Command: tt.fields.Command,
opts: tt.fields.opts,
}
if got := cmd.getModuleTemplateAnnotations(tt.args.modCnf, tt.args.crValidator); !reflect.DeepEqual(got, tt.want) {
t.Errorf("getModuleTemplateAnnotations() = %v, want %v", got, tt.want)
}
})
}
}
6 changes: 3 additions & 3 deletions pkg/module/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ func ValidateName(name string) error {
type SingleManifestFileCRValidator struct {
manifestPath string
crData []byte
crd []byte
Crd []byte
}

func NewSingleManifestFileCRValidator(cr []byte, manifestPath string) *SingleManifestFileCRValidator {
Expand Down Expand Up @@ -390,7 +390,7 @@ func (v *SingleManifestFileCRValidator) Run(ctx context.Context, log *zap.Sugare
if crdBytes == nil {
return fmt.Errorf("can't find the CRD for (group: %q, kind %q)", group, kind)
}
v.crd = crdBytes
v.Crd = crdBytes

// store extracted CRD in a temp file
tempDir, err := os.MkdirTemp("", "temporary-crd")
Expand All @@ -414,7 +414,7 @@ func (v *SingleManifestFileCRValidator) Run(ctx context.Context, log *zap.Sugare
}

func (v *SingleManifestFileCRValidator) GetCrd() []byte {
return v.crd
return v.Crd
}

func (v *DefaultCRValidator) GetCrd() []byte {
Expand Down
9 changes: 7 additions & 2 deletions tests/e2e/create_module/kyma_create_module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
)

func Test_ModuleTemplate(t *testing.T) {
moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION")
ociRepoURL := os.Getenv("OCI_REPOSITORY_URL")
testRepoURL := os.Getenv("TEST_REPOSITORY_URL")

Expand All @@ -29,6 +28,12 @@ func Test_ModuleTemplate(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, descriptor.SchemaVersion(), v2.SchemaVersion)

// test annotations
annotations := template.Annotations
expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION")
assert.Equal(t, annotations["operator.kyma-project.io/module-version"], expectedModuleTemplateVersion)
assert.Equal(t, annotations["operator.kyma-project.io/is-cluster-scoped"], "false")

// test descriptor.component.repositoryContexts
assert.Equal(t, len(descriptor.RepositoryContexts), 1)
unstructuredRepo := descriptor.GetEffectiveRepositoryContext()
Expand All @@ -46,7 +51,7 @@ func Test_ModuleTemplate(t *testing.T) {
assert.Equal(t, resource.Name, module.RawManifestLayerName)
assert.Equal(t, resource.Relation, ocmMetaV1.LocalRelation)
assert.Equal(t, resource.Type, module.TypeYaml)
assert.Equal(t, resource.Version, moduleTemplateVersion)
assert.Equal(t, resource.Version, expectedModuleTemplateVersion)

// test descriptor.component.resources[0].access
resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(resource.Access)
Expand Down

0 comments on commit dd62557

Please sign in to comment.