Skip to content

Commit

Permalink
Add module enable command (#2283)
Browse files Browse the repository at this point in the history
  • Loading branch information
pPrecel authored Dec 16, 2024
1 parent 2c669bc commit beaca2f
Show file tree
Hide file tree
Showing 16 changed files with 611 additions and 54 deletions.
72 changes: 72 additions & 0 deletions internal/cmd/alpha/module/enable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
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/kube/resources"
"github.com/kyma-project/cli.v3/internal/modules"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type enableConfig struct {
*cmdcommon.KymaConfig

module string
channel string
crPath string
defaultCR bool
}

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

cmd := &cobra.Command{
Use: "enable <module>",
Short: "Enable module.",
Long: "Use this command to enable module.",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cfg.module = args[0]
clierror.Check(runEnable(&cfg))
},
}

cmd.Flags().StringVar(&cfg.channel, "channel", "", "Name of the Kyma channel to use for the module")
cmd.Flags().StringVar(&cfg.crPath, "cr-path", "", "Path to the custom resource file")
cmd.Flags().BoolVar(&cfg.defaultCR, "default-cr", false, "Use this flag to deploy module with default cr")

cmd.MarkFlagsMutuallyExclusive("cr-path", "default-cr")

return cmd
}

func runEnable(cfg *enableConfig) clierror.Error {
client, clierr := cfg.GetKubeClientWithClierr()
if clierr != nil {
return clierr
}

crs, clierr := loadCustomCRs(cfg.crPath)
if clierr != nil {
return clierr
}

return modules.Enable(cfg.Ctx, client, cfg.module, cfg.channel, cfg.defaultCR, crs...)
}

func loadCustomCRs(crPath string) ([]unstructured.Unstructured, clierror.Error) {
if crPath == "" {
// skip if not set
return nil, nil
}

crs, err := resources.ReadFromFiles(crPath)
if err != nil {
return nil, clierror.Wrap(err, clierror.New("failed to read object from file"))
}

return crs, nil
}
2 changes: 1 addition & 1 deletion internal/cmd/alpha/module/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type modulesConfig struct {
*cmdcommon.KymaConfig
}

func NewListCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {
func newListCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {
cfg := modulesConfig{
KymaConfig: kymaConfig,
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/alpha/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ func NewModuleCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {
Long: `Use this command to manage modules on a kyma cluster.`,
}

cmd.AddCommand(NewListCMD(kymaConfig))
cmd.AddCommand(newListCMD(kymaConfig))
cmd.AddCommand(newEnableCMD(kymaConfig))

return cmd
}
6 changes: 3 additions & 3 deletions internal/cmdcommon/extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func TestListFromCluster(t *testing.T) {
t.Run("list extensions from cluster", func(t *testing.T) {
kubeClientConfig := &KubeClientConfig{
KubeClient: &fake.FakeKubeClient{
KubeClient: &fake.KubeClient{
TestKubernetesInterface: k8s_fake.NewSimpleClientset(
fixTestExtensionConfigmap("test-1"),
fixTestExtensionConfigmap("test-2"),
Expand Down Expand Up @@ -45,7 +45,7 @@ func TestListFromCluster(t *testing.T) {

t.Run("missing rootCommand error", func(t *testing.T) {
kubeClientConfig := &KubeClientConfig{
KubeClient: &fake.FakeKubeClient{
KubeClient: &fake.KubeClient{
TestKubernetesInterface: k8s_fake.NewSimpleClientset(
&corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Expand All @@ -71,7 +71,7 @@ func TestListFromCluster(t *testing.T) {

t.Run("skip optional fields", func(t *testing.T) {
kubeClientConfig := &KubeClientConfig{
KubeClient: &fake.FakeKubeClient{
KubeClient: &fake.KubeClient{
TestKubernetesInterface: k8s_fake.NewSimpleClientset(
&corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Expand Down
20 changes: 10 additions & 10 deletions internal/kube/fake/client.go → internal/kube/fake/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// Fake client for testing purposes
// It implements the Client interface and returns given values only
type FakeKubeClient struct {
type KubeClient struct {
TestKubernetesInterface kubernetes.Interface
TestDynamicInterface dynamic.Interface
TestIstioInterface istio.Interface
Expand All @@ -25,38 +25,38 @@ type FakeKubeClient struct {
TestRootlessDynamicInterface rootlessdynamic.Interface
}

func (f *FakeKubeClient) Static() kubernetes.Interface {
func (f *KubeClient) Static() kubernetes.Interface {
return f.TestKubernetesInterface
}

func (f *FakeKubeClient) Dynamic() dynamic.Interface {
func (f *KubeClient) Dynamic() dynamic.Interface {
return f.TestDynamicInterface
}

func (f *FakeKubeClient) Istio() istio.Interface {
func (f *KubeClient) Istio() istio.Interface {
return f.TestIstioInterface
}

func (f *FakeKubeClient) Btp() btp.Interface {
func (f *KubeClient) Btp() btp.Interface {
return f.TestBtpInterface
}

func (f *FakeKubeClient) RestClient() *rest.RESTClient {
func (f *KubeClient) RestClient() *rest.RESTClient {
return f.TestRestClient
}

func (f *FakeKubeClient) RestConfig() *rest.Config {
func (f *KubeClient) RestConfig() *rest.Config {
return f.TestRestConfig
}

func (f *FakeKubeClient) APIConfig() *api.Config {
func (f *KubeClient) APIConfig() *api.Config {
return f.TestAPIConfig
}

func (f *FakeKubeClient) Kyma() kyma.Interface {
func (f *KubeClient) Kyma() kyma.Interface {
return f.TestKymaInterface
}

func (f *FakeKubeClient) RootlessDynamic() rootlessdynamic.Interface {
func (f *KubeClient) RootlessDynamic() rootlessdynamic.Interface {
return f.TestRootlessDynamicInterface
}
80 changes: 80 additions & 0 deletions internal/kube/fake/kyma.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package fake

import (
"context"

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

type FakeEnabledModule struct {
Name string
Channel string
CustomResourcePolicy string
}

type KymaClient struct {
// outputs
ReturnErr error
ReturnGetModuleInfoErr error
ReturnDisableModuleErr error
ReturnGetModuleTemplateErr error
ReturnWaitForModuleErr error
ReturnModuleReleaseMetaList kyma.ModuleReleaseMetaList
ReturnModuleTemplateList kyma.ModuleTemplateList
ReturnModuleReleaseMeta kyma.ModuleReleaseMeta
ReturnModuleTemplate kyma.ModuleTemplate
ReturnDefaultKyma kyma.Kyma
ReturnModuleInfo kyma.KymaModuleInfo

// input arguments
UpdateDefaultKymas []kyma.Kyma
DisabledModules []string
EnabledModules []FakeEnabledModule
}

func (c *KymaClient) ListModuleReleaseMeta(_ context.Context) (*kyma.ModuleReleaseMetaList, error) {
return &c.ReturnModuleReleaseMetaList, c.ReturnErr
}

func (c *KymaClient) ListModuleTemplate(_ context.Context) (*kyma.ModuleTemplateList, error) {
return &c.ReturnModuleTemplateList, c.ReturnErr
}

func (c *KymaClient) GetModuleReleaseMetaForModule(_ context.Context, _ string) (*kyma.ModuleReleaseMeta, error) {
return &c.ReturnModuleReleaseMeta, c.ReturnErr
}

func (c *KymaClient) GetModuleTemplateForModule(_ context.Context, _, _ string) (*kyma.ModuleTemplate, error) {
return &c.ReturnModuleTemplate, c.ReturnGetModuleTemplateErr
}

func (c *KymaClient) GetDefaultKyma(_ context.Context) (*kyma.Kyma, error) {
return &c.ReturnDefaultKyma, c.ReturnErr
}

func (c *KymaClient) UpdateDefaultKyma(_ context.Context, kyma *kyma.Kyma) error {
c.UpdateDefaultKymas = append(c.UpdateDefaultKymas, *kyma)
return c.ReturnErr
}

func (c *KymaClient) GetModuleInfo(_ context.Context, _ string) (*kyma.KymaModuleInfo, error) {
return &c.ReturnModuleInfo, c.ReturnGetModuleInfoErr
}

func (c *KymaClient) WaitForModuleState(_ context.Context, _ string, _ ...string) error {
return c.ReturnWaitForModuleErr
}

func (c *KymaClient) EnableModule(_ context.Context, module string, channel string, customResourcePolicy string) error {
c.EnabledModules = append(c.EnabledModules, FakeEnabledModule{
Name: module,
Channel: channel,
CustomResourcePolicy: customResourcePolicy,
})
return c.ReturnErr
}

func (c *KymaClient) DisableModule(_ context.Context, module string) error {
c.DisabledModules = append(c.DisabledModules, module)
return c.ReturnDisableModuleErr
}
52 changes: 52 additions & 0 deletions internal/kube/fake/rootlessdynamic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package fake

import (
"context"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type RootlessDynamicClient struct {
// outputs
ReturnErr error
ReturnGetErr error
ReturnRemoveErr error
ReturnGetObj unstructured.Unstructured
ReturnListObjs *unstructured.UnstructuredList

// inputs summary
GetObjs []unstructured.Unstructured
ListObjs []unstructured.Unstructured
RemovedObjs []unstructured.Unstructured
ApplyObjs []unstructured.Unstructured
}

func (m *RootlessDynamicClient) Apply(_ context.Context, obj *unstructured.Unstructured) error {
m.ApplyObjs = append(m.ApplyObjs, *obj)
return m.ReturnErr
}

func (m *RootlessDynamicClient) ApplyMany(_ context.Context, objs []unstructured.Unstructured) error {
m.ApplyObjs = append(m.ApplyObjs, objs...)
return m.ReturnErr
}

func (m *RootlessDynamicClient) Get(_ context.Context, obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
m.GetObjs = append(m.GetObjs, *obj)
return &m.ReturnGetObj, m.ReturnGetErr
}

func (m *RootlessDynamicClient) List(_ context.Context, obj *unstructured.Unstructured) (*unstructured.UnstructuredList, error) {
m.ListObjs = append(m.ListObjs, *obj)
return m.ReturnListObjs, m.ReturnErr
}

func (m *RootlessDynamicClient) Remove(_ context.Context, obj *unstructured.Unstructured) error {
m.RemovedObjs = append(m.RemovedObjs, *obj)
return m.ReturnRemoveErr
}

func (m *RootlessDynamicClient) RemoveMany(_ context.Context, objs []unstructured.Unstructured) error {
m.RemovedObjs = append(m.RemovedObjs, objs...)
return m.ReturnRemoveErr
}
Loading

0 comments on commit beaca2f

Please sign in to comment.