Skip to content

Commit

Permalink
List plugins deactivated for a context
Browse files Browse the repository at this point in the history
  • Loading branch information
Chandra Pamuluri committed Sep 29, 2023
1 parent 44e91db commit 3c96640
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 39 deletions.
18 changes: 15 additions & 3 deletions pkg/command/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
wcpauth "github.com/vmware-tanzu/tanzu-cli/pkg/auth/wcp"
"github.com/vmware-tanzu/tanzu-cli/pkg/cli"
"github.com/vmware-tanzu/tanzu-cli/pkg/constants"
"github.com/vmware-tanzu/tanzu-cli/pkg/discovery"
"github.com/vmware-tanzu/tanzu-cli/pkg/pluginmanager"
)

Expand All @@ -56,6 +57,7 @@ const (
noActiveContextExistsForTarget = "There is no active context for the given target %v"
contextNotActiveOrNotExists = "The provided context %v is not active or does not exist"
contextForTargetSetInactive = "The context %v for the target %v has been set as inactive"
deactivatingPlugin = "Deactivating plugin '%v:%v' for context '%v'"

invalidTarget = "invalid target specified. Please specify a correct value for the `--target/-t` flag from 'kubernetes[k8s]/mission-control[tmc]"
)
Expand Down Expand Up @@ -829,13 +831,13 @@ func deleteCtx(_ *cobra.Command, args []string) error {
return nil
}
}

installed, _, _, _ := getInstalledAndMissingContextPlugins() //nolint:dogsled
log.Infof("Deleting entry for cluster %s", name)
err := config.RemoveContext(name)
if err != nil {
return err
}

listDeactivatedPlugins(installed, name)
return nil
}

Expand Down Expand Up @@ -916,8 +918,8 @@ func unsetCtx(_ *cobra.Command, args []string) error {
}

func unsetGivenContext(name string, target configtypes.Target) error {
var err error
var unset bool
installed, _, _, _ := getInstalledAndMissingContextPlugins() //nolint:dogsled
currentCtxMap, err := config.GetAllCurrentContextsMap()
if target != "" && name != "" {
ctx, ok := currentCtxMap[target]
Expand Down Expand Up @@ -953,10 +955,20 @@ func unsetGivenContext(name string, target configtypes.Target) error {
return err
} else if unset {
log.Outputf(contextForTargetSetInactive, name, target)
listDeactivatedPlugins(installed, name)
}
return nil
}

// listDeactivatedPlugins stdout the plugins that are being deactivated
func listDeactivatedPlugins(deactivatedPlugins []discovery.Discovered, ctxName string) {
for i := range deactivatedPlugins {
if (deactivatedPlugins)[i].ContextName == ctxName {
log.Outputf(deactivatingPlugin, (deactivatedPlugins)[i].Name, deactivatedPlugins[i].InstalledVersion, ctxName)
}
}
}

func displayContextListOutputListView(cfg *configtypes.ClientConfig, writer io.Writer) {
target := getTarget()

Expand Down
8 changes: 4 additions & 4 deletions test/e2e/context/k8s/context_k8s_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,15 @@ func k8sContextLifeCycleTests() bool {
It("delete context command", func() {
By("delete all contexts created in previous tests")
for _, ctx := range contextNames {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
Expect(framework.IsContextExists(tf, ctx)).To(BeFalse(), fmt.Sprintf(framework.ContextShouldNotExists, ctx))
Expect(err).To(BeNil(), "delete context should delete context without any error")
}
})
// Test case: (negative test) test 'tanzu context delete' command for context name which is not exists
It("delete context command", func() {
By("delete context command with random string")
err := tf.ContextCmd.DeleteContext(framework.RandomString(4))
_, _, err := tf.ContextCmd.DeleteContext(framework.RandomString(4))
Expect(err).ToNot(BeNil())
})
})
Expand All @@ -206,7 +206,7 @@ func k8sContextStressTests() bool {
list, err := tf.ContextCmd.ListContext()
Expect(err).To(BeNil(), "list context should not return any error")
for _, ctx := range list {
err := tf.ContextCmd.DeleteContext(ctx.Name)
_, _, err := tf.ContextCmd.DeleteContext(ctx.Name)
Expect(err).To(BeNil(), "delete context should delete context without any error")
Expect(framework.IsContextExists(tf, ctx.Name)).To(BeFalse(), fmt.Sprintf(framework.ContextShouldNotExists, ctx.Name))
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func k8sContextStressTests() bool {
It("delete context command", func() {
By("delete all contexts created in previous tests")
for _, ctx := range contextNamesStress {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
log.Infof("context: %s deleted", ctx)
Expect(framework.IsContextExists(tf, ctx)).To(BeFalse(), fmt.Sprintf(framework.ContextShouldNotExists, ctx))
Expect(err).To(BeNil(), "delete context should delete context without any error")
Expand Down
12 changes: 6 additions & 6 deletions test/e2e/context/tmc/context_tmc_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func tmcStressTestCases() bool {
It("delete context command", func() {
By("delete all contexts created in previous tests")
for _, ctx := range contextNamesStress {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
log.Infof("context: %s deleted", ctx)
Expect(framework.IsContextExists(tf, ctx)).To(BeFalse(), fmt.Sprintf(framework.ContextShouldNotExists, ctx))
Expect(err).To(BeNil(), "delete context should delete context without any error")
Expand Down Expand Up @@ -139,10 +139,10 @@ func tmcAndK8sContextTests() bool {

// Test case: d. delete both k8s and tmc contexts
It("delete context command", func() {
err := tf.ContextCmd.DeleteContext(k8sCtx)
_, _, err := tf.ContextCmd.DeleteContext(k8sCtx)
Expect(err).To(BeNil(), "delete context should delete context without any error")
Expect(framework.IsContextExists(tf, k8sCtx)).To(BeFalse(), fmt.Sprintf(ContextShouldNotExists+" as been deleted", k8sCtx))
err = tf.ContextCmd.DeleteContext(tmcCtx)
_, _, err = tf.ContextCmd.DeleteContext(tmcCtx)
Expect(err).To(BeNil(), "delete context should delete context without any error")
Expect(framework.IsContextExists(tf, tmcCtx)).To(BeFalse(), fmt.Sprintf(ContextShouldNotExists+" as been deleted", tmcCtx))
})
Expand Down Expand Up @@ -220,11 +220,11 @@ func tmcAndK8sContextTests() bool {
// Test case: e. delete all contexts
It("delete all contexts", func() {
for _, ctx := range k8sCtxs {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
Expect(err).To(BeNil(), "delete context should delete context without any error")
}
for _, ctx := range tmcCtxs {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
Expect(err).To(BeNil(), "delete context should delete context without any error")
}
})
Expand Down Expand Up @@ -387,7 +387,7 @@ func tmcLifeCycleTests() bool {
// Test case: n. test 'tanzu context delete' command, make sure to delete all context's created in previous test cases
It("delete context command", func() {
for _, ctx := range contextNames {
err := tf.ContextCmd.DeleteContext(ctx)
_, _, err := tf.ContextCmd.DeleteContext(ctx)
Expect(framework.IsContextExists(tf, ctx)).To(BeFalse(), fmt.Sprintf(ContextShouldNotExists+" as been deleted", ctx))
Expect(err).To(BeNil(), "delete context should delete context without any error")
}
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/framework/context_lifecycle_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type ContextCmdOps interface {
// ListContext helps to run `context list` command
ListContext(opts ...E2EOption) ([]*ContextListInfo, error)
// DeleteContext helps to run `context delete` command
DeleteContext(contextName string, opts ...E2EOption) error
DeleteContext(contextName string, opts ...E2EOption) (stdOutStr, stdErrStr string, err error)
// GetActiveContext returns current active context
GetActiveContext(targetType string, opts ...E2EOption) (string, error)
// GetActiveContexts returns all active contexts
Expand Down Expand Up @@ -111,13 +111,13 @@ func (cc *contextCmdOps) GetActiveContexts(opts ...E2EOption) ([]*ContextListInf
return contexts, nil
}

func (cc *contextCmdOps) DeleteContext(contextName string, opts ...E2EOption) error {
func (cc *contextCmdOps) DeleteContext(contextName string, opts ...E2EOption) (string, string, error) {
deleteContextCmd := fmt.Sprintf(DeleteContext, "%s", contextName)
stdOut, stdErr, err := cc.cmdExe.TanzuCmdExec(deleteContextCmd, opts...)
if err != nil {
log.Infof("failed to delete context:%s", contextName)
return errors.Wrapf(err, FailedToDeleteContext+", stderr:%s stdout:%s , ", stdErr.String(), stdOut.String())
return stdOut.String(), stdErr.String(), errors.Wrapf(err, FailedToDeleteContext+", stderr:%s stdout:%s , ", stdErr.String(), stdOut.String())
}
log.Infof(ContextDeleted, contextName)
return err
return stdOut.String(), stdErr.String(), err
}
1 change: 1 addition & 0 deletions test/e2e/framework/framework_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const (
NoActiveContextExistsForTarget = "There is no active context for the given target %v"
ContextNotActiveOrNotExists = "The provided context %v is not active or does not exist"
ContextForTargetSetInactive = "The context %v for the target %v has been set as inactive"
DeactivatingPlugin = "Deactivating plugin '%v:%v' for context '%v'"

KindClusterCreate = "kind create cluster --name %s"
KindClusterStatus = "kubectl cluster-info --context %s"
Expand Down
1 change: 1 addition & 0 deletions test/e2e/framework/output_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type PluginSearch struct {
}

type PluginGroup struct {
Name string `json:"name"`
Group string `json:"group"`
Description string `json:"description"`
Latest string `json:"latest"`
Expand Down
38 changes: 29 additions & 9 deletions test/e2e/plugin_sync/k8s/plugin_sync_k8s_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/vmware-tanzu/tanzu-plugin-runtime/config/types"
)

var stdOut string

// Below Use cases executed in this test suite
// cleanup and initialize the config files
// Use case 1: create a KIND cluster, don't apply CRD and CRs, create context, make sure no plugins are installed
Expand Down Expand Up @@ -76,7 +78,7 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {
})
// Test case: d. delete current context and KIND cluster
It("delete current context and the KIND cluster", func() {
err = tf.ContextCmd.DeleteContext(contextName)
_, _, err = tf.ContextCmd.DeleteContext(contextName)
Expect(err).To(BeNil(), "context should be deleted without error")
_, err := tf.KindCluster.DeleteCluster(clusterInfo.Name)
Expect(err).To(BeNil(), "kind cluster should be deleted without any error")
Expand Down Expand Up @@ -171,7 +173,7 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {
// run plugin sync, make sure the uninstalled plugin has installed again.
It("Uninstall one of the installed plugin", func() {
pluginToUninstall := pluginsInfoForCRsApplied[0]
err := tf.PluginCmd.UninstallPlugin(pluginToUninstall.Name, pluginToUninstall.Target)
err = tf.PluginCmd.UninstallPlugin(pluginToUninstall.Name, pluginToUninstall.Target)
Expect(err).To(BeNil(), "should not get any error for plugin uninstall")

latestPluginsInstalledList := pluginsInfoForCRsApplied[1:]
Expand All @@ -190,10 +192,28 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {
Expect(len(installedPluginsList)).Should(Equal(len(pluginsInfoForCRsApplied)), "number of plugins should be same as number of plugins CRs applied")
Expect(f.CheckAllPluginsExists(installedPluginsList, pluginsInfoForCRsApplied)).Should(BeTrue(), "plugins being installed and plugins info for which CRs applied should be same")
})
// Test case: h. delete current context and the KIND cluster
// Test case: h.1 Unset the context and make sure plugin are deactivated, and set the context again
It("list plugins and validate plugins being installed after context being created", func() {
installedPluginsList, err = tf.PluginCmd.ListPluginsForGivenContext(contextName, true)
Expect(err).To(BeNil(), "should not get any error for plugin list")
stdOut, _, err = tf.ContextCmd.UnsetContext(contextName)
Expect(err).To(BeNil(), "unset context should unset context without any error")
for i := range installedPluginsList {
Expect(stdOut).To(ContainSubstring(fmt.Sprintf(f.DeactivatingPlugin, installedPluginsList[i].Name, installedPluginsList[i].Version, contextName)))
}
err = tf.ContextCmd.UseContext(contextName)
Expect(err).To(BeNil(), "use context should set context without any error")
})
// Test case: h.2 delete current context and the KIND cluster
It("delete current context and the KIND cluster", func() {
err = tf.ContextCmd.DeleteContext(contextName)
installedPluginsList, err = tf.PluginCmd.ListPluginsForGivenContext(contextName, true)
Expect(err).To(BeNil(), "should not get any error for plugin list")
stdOut, _, err = tf.ContextCmd.DeleteContext(contextName)
Expect(err).To(BeNil(), "context should be deleted without error")
// delete context should deactivate all installed plugins
for i := range installedPluginsList {
Expect(stdOut).To(ContainSubstring(fmt.Sprintf(f.DeactivatingPlugin, installedPluginsList[i].Name, installedPluginsList[i].Version, contextName)))
}
_, err := tf.KindCluster.DeleteCluster(clusterInfo.Name)
Expect(err).To(BeNil(), "kind cluster should be deleted without any error")
})
Expand Down Expand Up @@ -272,7 +292,7 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {

// Test case: f. delete the KIND cluster
It("delete the KIND cluster", func() {
err = tf.ContextCmd.DeleteContext(contextName)
_, _, err = tf.ContextCmd.DeleteContext(contextName)
Expect(err).To(BeNil(), "context should be deleted without error")
_, err := tf.KindCluster.DeleteCluster(clusterInfo.Name)
Expect(err).To(BeNil(), "kind cluster should be deleted without any error")
Expand Down Expand Up @@ -325,7 +345,7 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {
})
// Test case: d. delete the context, make sure all context specific plugins are uninstalled
It("delete context, validate installed plugins list, should uninstalled all context plugins", func() {
err = tf.ContextCmd.DeleteContext(contextName)
_, _, err = tf.ContextCmd.DeleteContext(contextName)
Expect(err).To(BeNil(), "there should be no error for delete context")

pluginsList, err = tf.PluginCmd.ListPluginsForGivenContext(contextName, true)
Expand Down Expand Up @@ -429,9 +449,9 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {

// Test case: f. delete the KIND clusters
It("delete the KIND cluster", func() {
err = tf.ContextCmd.DeleteContext(contextNameClusterOne)
_, _, err = tf.ContextCmd.DeleteContext(contextNameClusterOne)
Expect(err).To(BeNil(), "context should be deleted without error")
err = tf.ContextCmd.DeleteContext(contextNameClusterTwo)
_, _, err = tf.ContextCmd.DeleteContext(contextNameClusterTwo)
Expect(err).To(BeNil(), "context should be deleted without error")
_, err = tf.KindCluster.DeleteCluster(clusterOne.Name)
Expect(err).To(BeNil(), "kind cluster should be deleted without any error")
Expand Down Expand Up @@ -504,7 +524,7 @@ var _ = f.CLICoreDescribe("[Tests:E2E][Feature:Plugin-sync-lifecycle]", func() {

// Test case: e. delete the KIND cluster
It("delete the KIND cluster", func() {
err = tf.ContextCmd.DeleteContext(contextName)
_, _, err = tf.ContextCmd.DeleteContext(contextName)
Expect(err).To(BeNil(), "context should be deleted without error")
_, err := tf.KindCluster.DeleteCluster(clusterInfo.Name)
Expect(err).To(BeNil(), "kind cluster should be deleted without any error")
Expand Down
Loading

0 comments on commit 3c96640

Please sign in to comment.