Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c5179e5
add kyma alpha module list stub
anoipm Apr 15, 2026
776b712
add under construction note to list cmd help
anoipm Apr 15, 2026
dab68f2
add ListService with InstalledModulesRepository
anoipm Apr 15, 2026
e3f7919
ListService returns core modules from InstalledModulesRepository
anoipm Apr 15, 2026
4655864
wire ListService to list command, print module names
anoipm Apr 15, 2026
cdbc343
add version and channel to ListResult
anoipm Apr 15, 2026
c144aa6
render list as table with module, version, channel columns
anoipm Apr 15, 2026
45ff5dc
update generated docs for alpha module list
anoipm Apr 15, 2026
3bed849
add output format support to list command (table, json)
anoipm Apr 15, 2026
20599de
add yaml output format to list command
anoipm Apr 15, 2026
b506c6b
extract convertListToOutputFormat
anoipm Apr 15, 2026
647f66c
extract convertListToRows
anoipm Apr 15, 2026
0128efc
add -o output format flag to list command
anoipm Apr 15, 2026
4ee5762
sort list results by name
anoipm Apr 15, 2026
9575398
add state field to ListResult
anoipm Apr 17, 2026
0b618c8
add state field to list rendering
anoipm Apr 17, 2026
d290973
change InstalledModulesRepository to return KymaModuleInfo
anoipm Apr 17, 2026
af5a6de
add managed field to ListResult
anoipm Apr 17, 2026
2099c34
add managed field to list rendering
anoipm Apr 17, 2026
8a17cf7
add customResourcePolicy field to ListResult
anoipm Apr 17, 2026
b080993
add customResourcePolicy field to list rendering
anoipm Apr 17, 2026
a068923
align list table columns with ADR-003
anoipm Apr 17, 2026
94f45ef
add installation state via ModuleInstallationStateRepository
anoipm Apr 17, 2026
f82ff85
render installationState in all output formats
anoipm Apr 17, 2026
210ab90
combine module and installation status when they differ
anoipm Apr 17, 2026
3fd52e5
update list command description
anoipm Apr 17, 2026
18e0bba
align JSON/YAML keys with column names
anoipm Apr 17, 2026
65e2a4f
rename State to ModuleState in ListResult
anoipm Apr 17, 2026
cc073ec
introduce ModuleInstallation entity, move business logic to service
anoipm Apr 28, 2026
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
1 change: 1 addition & 0 deletions docs/user/gen-docs/_sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default [
{ text: 'kyma alpha kubeconfig generate', link: './gen-docs/kyma_alpha_kubeconfig_generate' },
{ text: 'kyma alpha module', link: './gen-docs/kyma_alpha_module' },
{ text: 'kyma alpha module catalog', link: './gen-docs/kyma_alpha_module_catalog' },
{ text: 'kyma alpha module list', link: './gen-docs/kyma_alpha_module_list' },
{ text: 'kyma alpha module pull', link: './gen-docs/kyma_alpha_module_pull' },
{ text: 'kyma alpha provision', link: './gen-docs/kyma_alpha_provision' },
{ text: 'kyma alpha reference-instance', link: './gen-docs/kyma_alpha_reference-instance' },
Expand Down
2 changes: 2 additions & 0 deletions docs/user/gen-docs/kyma_alpha_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ kyma alpha module <command> [flags]

```text
catalog - Lists modules catalog
list - Lists installed modules
pull - Pulls a module from a remote repository
```

Expand All @@ -31,4 +32,5 @@ kyma alpha module <command> [flags]

* [kyma alpha](kyma_alpha.md) - Groups command prototypes for which the API may still change
* [kyma alpha module catalog](kyma_alpha_module_catalog.md) - Lists modules catalog
* [kyma alpha module list](kyma_alpha_module_list.md) - Lists installed modules
* [kyma alpha module pull](kyma_alpha_module_pull.md) - Pulls a module from a remote repository
29 changes: 29 additions & 0 deletions docs/user/gen-docs/kyma_alpha_module_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# kyma alpha module list

Lists installed modules.

## Synopsis

Use this command to list the installed Kyma modules.

NOTE: functionality under construction
- community modules not yet supported

```bash
kyma alpha module list [flags]
```

## Flags

```text
-o, --output string Output format (Possible values: table, json, yaml)
--context string The name of the kubeconfig context to use
-h, --help Help for the command
--kubeconfig string Path to the Kyma kubeconfig file
--show-extensions-error Prints a possible error when fetching extensions fails
--skip-extensions Skips fetching extensions from the target Kyma environment
```

## See also

* [kyma alpha module](kyma_alpha_module.md) - Manages Kyma modules
58 changes: 58 additions & 0 deletions internal/cmd/alpha/module/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package module

import (
"github.com/kyma-project/cli.v3/internal/clierror"
"github.com/kyma-project/cli.v3/internal/cmdcommon"
"github.com/kyma-project/cli.v3/internal/cmdcommon/types"
"github.com/kyma-project/cli.v3/internal/modulesv2"
"github.com/kyma-project/cli.v3/internal/out"
"github.com/spf13/cobra"
)

type listConfig struct {
*cmdcommon.KymaConfig
outputFormat types.Format
}

func NewListV2CMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {
cfg := listConfig{
KymaConfig: kymaConfig,
}

cmd := &cobra.Command{
Use: "list [flags]",
Short: "Lists installed modules",
Long: `Use this command to list the installed Kyma modules.

NOTE: functionality under construction
- community modules not yet supported`,
Run: func(_ *cobra.Command, _ []string) {
clierror.Check(listModulesV2(&cfg))
},
}

cmd.Flags().VarP(&cfg.outputFormat, "output", "o", "Output format (Possible values: table, json, yaml)")

return cmd
}

func listModulesV2(cfg *listConfig) clierror.Error {
moduleOperations := modulesv2.NewModuleOperations(cfg.KymaConfig)

listService, err := moduleOperations.List()
if err != nil {
return clierror.Wrap(err, clierror.New("failed to execute the list command"))
}

results, err := listService.Run(cfg.Ctx)
if err != nil {
return clierror.Wrap(err, clierror.New("failed to list installed modules"))
}

err = modulesv2.RenderList(results, cfg.outputFormat, out.Default)
if err != nil {
return clierror.Wrap(err, clierror.New("failed to render module list"))
}

return nil
}
19 changes: 19 additions & 0 deletions internal/cmd/alpha/module/list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package module

import (
"testing"

"github.com/kyma-project/cli.v3/internal/cmdcommon"
"github.com/stretchr/testify/require"
)

func TestListCmd_Exists(t *testing.T) {
cmd := NewListV2CMD(&cmdcommon.KymaConfig{})
require.NotNil(t, cmd)
require.Equal(t, "list [flags]", cmd.Use)
}

func TestListCmd_HasOutputFlag(t *testing.T) {
cmd := NewListV2CMD(&cmdcommon.KymaConfig{})
require.NotNil(t, cmd.Flags().Lookup("output"))
}
1 change: 1 addition & 0 deletions internal/cmd/alpha/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func NewModuleCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {

cmd.AddCommand(NewCatalogV2CMD(kymaConfig))
cmd.AddCommand(NewPullV2CMD(kymaConfig))
cmd.AddCommand(NewListV2CMD(kymaConfig))

return cmd
}
49 changes: 44 additions & 5 deletions internal/modulesv2/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ import (
type ModuleOperations interface {
Catalog() (*CatalogService, error)
Pull() (*PullService, error)
// TODO
// Add() (*AddService, error)
// Install() (*InstallService, error)
// Pull() (*PullService, error)
// etc.
List() (*ListService, error)
}

type moduleOperations struct {
Expand All @@ -38,6 +34,17 @@ func (m *moduleOperations) Catalog() (*CatalogService, error) {
return catalogService, nil
}

func (m *moduleOperations) List() (*ListService, error) {
c := setupDIContainer(m.kymaConfig)

listService, err := di.GetTyped[*ListService](c)
if err != nil {
return nil, errors.New("failed to execute the list command")
}

return listService, nil
}

func (m *moduleOperations) Pull() (*PullService, error) {
c := setupDIContainer(m.kymaConfig)

Expand Down Expand Up @@ -83,6 +90,24 @@ func setupDIContainer(kymaConfig *cmdcommon.KymaConfig) *di.Container {
return repository.NewClusterMetadataRepository(kubeClient), nil
})

di.RegisterTyped(container, func(c *di.Container) (repository.InstalledModulesRepository, error) {
kubeClient, err := di.GetTyped[kube.Client](c)
if err != nil {
return nil, err
}

return repository.NewInstalledModulesRepository(kubeClient.Kyma()), nil
})

di.RegisterTyped(container, func(c *di.Container) (repository.ModuleInstallationStateRepository, error) {
kubeClient, err := di.GetTyped[kube.Client](c)
if err != nil {
return nil, err
}

return repository.NewModuleInstallationStateRepository(kubeClient), nil
})

// Services:

di.RegisterTyped(container, func(c *di.Container) (*CatalogService, error) {
Expand All @@ -108,5 +133,19 @@ func setupDIContainer(kymaConfig *cmdcommon.KymaConfig) *di.Container {
return NewPullService(moduleRepo), nil
})

di.RegisterTyped(container, func(c *di.Container) (*ListService, error) {
installedModulesRepo, err := di.GetTyped[repository.InstalledModulesRepository](c)
if err != nil {
return nil, err
}

installationStateRepo, err := di.GetTyped[repository.ModuleInstallationStateRepository](c)
if err != nil {
return nil, err
}

return NewListService(installedModulesRepo, installationStateRepo), nil
})

return container
}
11 changes: 11 additions & 0 deletions internal/modulesv2/dtos/listresult.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dtos

type ListResult struct {
Name string
Version string
Channel string
ModuleState string
Managed bool
CustomResourcePolicy string
InstallationState string
}
29 changes: 29 additions & 0 deletions internal/modulesv2/entities/moduleinstallation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package entities

import "github.com/kyma-project/cli.v3/internal/kube/kyma"

type ModuleInstallation struct {
Name string
Version string
Channel string
ModuleState string
Managed *bool
CustomResourcePolicy string
Template kyma.ModuleStatus
}

func NewModuleInstallationFromRaw(raw kyma.KymaModuleInfo) *ModuleInstallation {
return &ModuleInstallation{
Name: raw.Status.Name,
Version: raw.Status.Version,
Channel: raw.Status.Channel,
ModuleState: raw.Status.State,
Managed: raw.Spec.Managed,
CustomResourcePolicy: raw.Spec.CustomResourcePolicy,
Template: raw.Status,
}
}

func (m *ModuleInstallation) IsManaged() bool {
return m.Managed == nil || *m.Managed
}
71 changes: 71 additions & 0 deletions internal/modulesv2/entities/moduleinstallation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package entities

import (
"testing"

"github.com/kyma-project/cli.v3/internal/kube/kyma"
"github.com/stretchr/testify/require"
)

func TestModuleInstallation_IsManaged_TrueWhenManagedIsNil(t *testing.T) {
m := ModuleInstallation{Managed: nil}
require.True(t, m.IsManaged())
}

func TestModuleInstallation_IsManaged_TrueWhenManagedIsTrue(t *testing.T) {
managed := true
m := ModuleInstallation{Managed: &managed}
require.True(t, m.IsManaged())
}

func TestModuleInstallation_IsManaged_FalseWhenManagedIsFalse(t *testing.T) {
managed := false
m := ModuleInstallation{Managed: &managed}
require.False(t, m.IsManaged())
}

func TestNewModuleInstallationFromRaw_MapsNameVersionChannel(t *testing.T) {
raw := kyma.KymaModuleInfo{
Status: kyma.ModuleStatus{Name: "api-gateway", Version: "3.5.1", Channel: "regular"},
}

m := NewModuleInstallationFromRaw(raw)

require.Equal(t, "api-gateway", m.Name)
require.Equal(t, "3.5.1", m.Version)
require.Equal(t, "regular", m.Channel)
}

func TestNewModuleInstallationFromRaw_MapsModuleState(t *testing.T) {
raw := kyma.KymaModuleInfo{
Status: kyma.ModuleStatus{Name: "api-gateway", State: "Ready"},
}

m := NewModuleInstallationFromRaw(raw)

require.Equal(t, "Ready", m.ModuleState)
}

func TestNewModuleInstallationFromRaw_MapsManaged(t *testing.T) {
managed := false
raw := kyma.KymaModuleInfo{
Spec: kyma.Module{Managed: &managed},
Status: kyma.ModuleStatus{Name: "api-gateway"},
}

m := NewModuleInstallationFromRaw(raw)

require.NotNil(t, m.Managed)
require.False(t, *m.Managed)
}

func TestNewModuleInstallationFromRaw_MapsCustomResourcePolicy(t *testing.T) {
raw := kyma.KymaModuleInfo{
Spec: kyma.Module{CustomResourcePolicy: "CreateAndDelete"},
Status: kyma.ModuleStatus{Name: "api-gateway"},
}

m := NewModuleInstallationFromRaw(raw)

require.Equal(t, "CreateAndDelete", m.CustomResourcePolicy)
}
16 changes: 16 additions & 0 deletions internal/modulesv2/fake/installedmodules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fake

import (
"context"

"github.com/kyma-project/cli.v3/internal/modulesv2/entities"
)

type InstalledModulesRepository struct {
ListInstalledModulesResult []entities.ModuleInstallation
ListInstalledModulesError error
}

func (f *InstalledModulesRepository) ListInstalledModules(_ context.Context) ([]entities.ModuleInstallation, error) {
return f.ListInstalledModulesResult, f.ListInstalledModulesError
}
16 changes: 16 additions & 0 deletions internal/modulesv2/fake/moduleinstallationstate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fake

import (
"context"

"github.com/kyma-project/cli.v3/internal/modulesv2/entities"
)

type ModuleInstallationStateRepository struct {
GetInstallationStateResult string
GetInstallationStateError error
}

func (f *ModuleInstallationStateRepository) GetInstallationState(_ context.Context, _ entities.ModuleInstallation) (string, error) {
return f.GetInstallationStateResult, f.GetInstallationStateError
}
Loading
Loading