mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
* Attempting to delete application, now lists affected URLs Signed-off-by: Mohammed Zeeshan Ahmed <mohammed.zee1000@gmail.com> * Making component delete list affected objects before deletion. * Applying missed go gmt * Altering Application ListInProject to actually list in project. - Also includes changes to corresponding references to use List instead * Fixing imports in component that got missed * Applying go fmt * Improving messaging for application and project. - More detailed messages are now displayed about affected child components - Abortion of deletion in interactive, now logged as error * Adding more details of affected components for project deletion * Updating messaging to list linked services during component deletion * Adding missed printProjectDeleteInfo after rebasae * Updating component and project to use new format of URLs * Fixing up changes messed up during rebase. * Fixing up after rebase * Applying go fmt * Force deleting testversioncmp * Adding missing message for application deletion * Adding tests to ensure proper messaging during deletion of app and project * Deletion of application now lists affected service instances. * Fixing up application and project after rebase to use new structs * Fixing up component after rebase to use new struct and removing linked services - New struct makes it harder to list these, so will figure out a way later * Fixing up missing return of error * Fixing unnessasary message. * fixing after rebase * Fixing up after rebase to use new format of URL * Moving back to infof
This commit is contained in:
committed by
OpenShift Merge Robot
parent
f816d9f41a
commit
54ff6263e3
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
applabels "github.com/redhat-developer/odo/pkg/application/labels"
|
||||
"github.com/redhat-developer/odo/pkg/component"
|
||||
"github.com/redhat-developer/odo/pkg/occlient"
|
||||
@@ -82,14 +81,18 @@ func Create(client *occlient.Client, appName string) error {
|
||||
|
||||
// List all applications in current project
|
||||
func List(client *occlient.Client) ([]preference.ApplicationInfo, error) {
|
||||
return ListInProject(client)
|
||||
return ListInProject(client, client.Namespace)
|
||||
}
|
||||
|
||||
// ListInProject lists all applications in given project
|
||||
// Queries cluster and config file.
|
||||
// Shows also empty applications (empty applications are those that are just
|
||||
// mentioned in config file but don't have any object associated with it on cluster).
|
||||
func ListInProject(client *occlient.Client) ([]preference.ApplicationInfo, error) {
|
||||
// ListInProject lists all applications in given project
|
||||
// Queries cluster and config file.
|
||||
// Shows also empty applications (empty applications are those that are just
|
||||
// mentioned in config file but don't have any object associated with it on cluster).
|
||||
func ListInProject(client *occlient.Client, projectName string) ([]preference.ApplicationInfo, error) {
|
||||
var applications []preference.ApplicationInfo
|
||||
|
||||
cfg, err := preference.New()
|
||||
@@ -99,7 +102,7 @@ func ListInProject(client *occlient.Client) ([]preference.ApplicationInfo, error
|
||||
|
||||
// All applications of the current project from config file
|
||||
for i := range cfg.ActiveApplications {
|
||||
if cfg.ActiveApplications[i].Project == client.Namespace {
|
||||
if cfg.ActiveApplications[i].Project == projectName {
|
||||
applications = append(applications, cfg.ActiveApplications[i])
|
||||
}
|
||||
}
|
||||
@@ -114,7 +117,7 @@ func ListInProject(client *occlient.Client) ([]preference.ApplicationInfo, error
|
||||
// skip applications that are already in the list (they were mentioned in config file)
|
||||
found := false
|
||||
for _, app := range applications {
|
||||
if app.Project == client.Namespace && app.Name == name {
|
||||
if app.Project == projectName && app.Name == name {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
@@ -123,7 +126,7 @@ func ListInProject(client *occlient.Client) ([]preference.ApplicationInfo, error
|
||||
Name: name,
|
||||
// if this application is not in config file, it can't be active
|
||||
Active: false,
|
||||
Project: client.Namespace,
|
||||
Project: projectName,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -252,7 +255,7 @@ func SetCurrent(client *occlient.Client, appName string) error {
|
||||
|
||||
// Exists returns true if given application (appName) exists
|
||||
func Exists(client *occlient.Client, appName string) (bool, error) {
|
||||
apps, err := ListInProject(client)
|
||||
apps, err := List(client)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "unable to list applications")
|
||||
}
|
||||
|
||||
@@ -3,19 +3,22 @@ package application
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redhat-developer/odo/pkg/application"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/occlient"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/redhat-developer/odo/pkg/storage"
|
||||
"github.com/redhat-developer/odo/pkg/url"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/component"
|
||||
odoutil "github.com/redhat-developer/odo/pkg/odo/util"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/service"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// RecommendedCommandName is the recommended app command name
|
||||
@@ -78,21 +81,47 @@ func printDeleteAppInfo(client *occlient.Client, appName string, projectName str
|
||||
return errors.Wrap(err, "failed to get Component list")
|
||||
}
|
||||
|
||||
for _, currentComponent := range componentList.Items {
|
||||
componentDesc, err := component.GetComponent(client, currentComponent.Name, appName, projectName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get component description")
|
||||
}
|
||||
log.Info("Component", currentComponent.Name, "will be deleted.")
|
||||
if len(componentList.Items) != 0 {
|
||||
log.Info("This application has following components that will be deleted")
|
||||
for _, currentComponent := range componentList.Items {
|
||||
componentDesc, err := component.GetComponent(client, currentComponent.Name, appName, projectName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get component description")
|
||||
}
|
||||
log.Info(" component named ", currentComponent.Name)
|
||||
|
||||
if len(componentDesc.Spec.URL) != 0 {
|
||||
fmt.Println(" Externally exposed URLs will be removed")
|
||||
if len(componentDesc.Spec.URL) != 0 {
|
||||
ul, err := url.List(client, componentDesc.Name, appName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not get url list")
|
||||
}
|
||||
log.Info(" This component has following urls that will be deleted with component")
|
||||
for _, u := range ul.Items {
|
||||
log.Info(" URL named ", u.GetName(), " with host ", u.Spec.Host, " having protocol ", u.Spec.Protocol, " at port ", u.Spec.Port)
|
||||
}
|
||||
}
|
||||
|
||||
storages, err := storage.List(client, currentComponent.Name, appName)
|
||||
odoutil.LogErrorAndExit(err, "")
|
||||
if len(storages.Items) != 0 {
|
||||
log.Info(" The component has following storages which will be deleted with the component")
|
||||
for _, storageName := range componentDesc.Spec.Storage {
|
||||
store := storages.Get(storageName)
|
||||
log.Info(" Storage named ", store.GetName(), " of size ", store.Spec.Size)
|
||||
}
|
||||
}
|
||||
}
|
||||
storages, err := storage.List(client, currentComponent.Name, appName)
|
||||
odoutil.LogErrorAndExit(err, "")
|
||||
for _, storageName := range componentDesc.Spec.Storage {
|
||||
store := storages.Get(storageName)
|
||||
fmt.Println(" Storage", store.Name, "of size", store.Spec.Size, "will be removed")
|
||||
// List services that will be removed
|
||||
serviceList, err := service.List(client, appName)
|
||||
if err != nil {
|
||||
log.Info("No services / could not get services")
|
||||
glog.V(4).Info(err.Error())
|
||||
}
|
||||
if len(serviceList) != 0 {
|
||||
log.Info("This application has following service that will be deleted")
|
||||
for _, ser := range serviceList {
|
||||
log.Info(" service named ", ser.Name, " of type ", ser.Type)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package application
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/application"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/odo/cli/project"
|
||||
|
||||
@@ -49,7 +49,7 @@ func (o *ListOptions) Validate() (err error) {
|
||||
|
||||
// Run contains the logic for the odo command
|
||||
func (o *ListOptions) Run() (err error) {
|
||||
apps, err := application.ListInProject(o.Client)
|
||||
apps, err := application.List(o.Client)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get list of applications: %v", err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,13 @@ package component
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redhat-developer/odo/pkg/component"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/occlient"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
"github.com/redhat-developer/odo/pkg/storage"
|
||||
"github.com/redhat-developer/odo/pkg/url"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
odoutil "github.com/redhat-developer/odo/pkg/odo/util"
|
||||
@@ -86,3 +92,33 @@ func AddComponentFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().String(genericclioptions.ComponentFlagName, "", "Component, defaults to active component.")
|
||||
completion.RegisterCommandFlagHandler(cmd, "component", completion.ComponentNameCompletionHandler)
|
||||
}
|
||||
|
||||
// printDeleteComponentInfo will print things which will be deleted
|
||||
func printDeleteComponentInfo(client *occlient.Client, componentName string, appName string, projectName string) error {
|
||||
componentDesc, err := component.GetComponent(client, componentName, appName, projectName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get component description")
|
||||
}
|
||||
|
||||
if len(componentDesc.Spec.URL) != 0 {
|
||||
log.Info("This component has following urls that will be deleted with component")
|
||||
ul, err := url.List(client, componentDesc.Name, appName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not get url list")
|
||||
}
|
||||
for _, u := range ul.Items {
|
||||
log.Info(" URL named ", u.GetName(), " with host ", u.Spec.Host, " having protocol ", u.Spec.Protocol, " at port ", u.Spec.Port)
|
||||
}
|
||||
}
|
||||
|
||||
storages, err := storage.List(client, componentDesc.Name, appName)
|
||||
odoutil.LogErrorAndExit(err, "")
|
||||
if len(storages.Items) != 0 {
|
||||
log.Info("This component has following storages which will be deleted with the component")
|
||||
for _, storageName := range componentDesc.Spec.Storage {
|
||||
store := storages.Get(storageName)
|
||||
log.Info(" Storage", store.GetName(), "of size", store.Spec.Size)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ package component
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
appCmd "github.com/redhat-developer/odo/pkg/odo/cli/application"
|
||||
projectCmd "github.com/redhat-developer/odo/pkg/odo/cli/project"
|
||||
"github.com/redhat-developer/odo/pkg/odo/cli/ui"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
ktemplates "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
odoutil "github.com/redhat-developer/odo/pkg/odo/util"
|
||||
|
||||
"github.com/golang/glog"
|
||||
@@ -59,6 +61,11 @@ func (do *DeleteOptions) Run() (err error) {
|
||||
glog.V(4).Infof("component delete called")
|
||||
glog.V(4).Infof("args: %#v", do)
|
||||
|
||||
err = printDeleteComponentInfo(do.Client, do.componentName, do.Context.Application, do.Context.Project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if do.componentForceDeleteFlag || ui.Proceed(fmt.Sprintf("Are you sure you want to delete %v from %v?", do.componentName, do.Application)) {
|
||||
err := component.Delete(do.Client, do.componentName, do.Application)
|
||||
if err != nil {
|
||||
@@ -78,7 +85,7 @@ func (do *DeleteOptions) Run() (err error) {
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Infof("Aborting deletion of component: %v", do.componentName)
|
||||
return fmt.Errorf("Aborting deletion of component: %v", do.componentName)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -2,6 +2,7 @@ package project
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/odo/cli/ui"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
@@ -60,6 +61,10 @@ func (pdo *ProjectDeleteOptions) Validate() (err error) {
|
||||
|
||||
// Run runs the project delete command
|
||||
func (pdo *ProjectDeleteOptions) Run() (err error) {
|
||||
err = printDeleteProjectInfo(pdo.Context.Client, pdo.projectName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pdo.projectForceDeleteFlag || ui.Proceed(fmt.Sprintf("Are you sure you want to delete project %v", pdo.projectName)) {
|
||||
currentProject, err := project.Delete(pdo.Context.Client, pdo.projectName)
|
||||
if err != nil {
|
||||
|
||||
@@ -3,9 +3,18 @@ package project
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redhat-developer/odo/pkg/application"
|
||||
"github.com/redhat-developer/odo/pkg/component"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/occlient"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
odoutil "github.com/redhat-developer/odo/pkg/odo/util"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
"github.com/redhat-developer/odo/pkg/service"
|
||||
"github.com/redhat-developer/odo/pkg/storage"
|
||||
"github.com/redhat-developer/odo/pkg/url"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -66,3 +75,71 @@ func AddProjectFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().String(genericclioptions.ProjectFlagName, "", "Project, defaults to active project")
|
||||
completion.RegisterCommandFlagHandler(cmd, "project", completion.ProjectNameCompletionHandler)
|
||||
}
|
||||
|
||||
// printDeleteProjectInfo prints objects affected by project deletion
|
||||
func printDeleteProjectInfo(client *occlient.Client, projectName string) error {
|
||||
// Fetch and List the applications
|
||||
applicationList, err := application.ListInProject(client, projectName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get application list")
|
||||
}
|
||||
if len(applicationList) != 0 {
|
||||
log.Info("This project contains the following applications, which will be deleted")
|
||||
for _, app := range applicationList {
|
||||
log.Info(" Application ", app.Name)
|
||||
|
||||
// List the components
|
||||
componentList, err := component.List(client, app.Name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get Component list")
|
||||
}
|
||||
if len(componentList.Items) != 0 {
|
||||
log.Info(" This application has following components that will be deleted")
|
||||
|
||||
for _, currentComponent := range componentList.Items {
|
||||
componentDesc, err := component.GetComponent(client, currentComponent.Name, app.Name, app.Project)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get component description")
|
||||
}
|
||||
log.Info(" component named ", componentDesc.Name)
|
||||
|
||||
if len(componentDesc.Spec.URL) != 0 {
|
||||
ul, err := url.List(client, componentDesc.Name, app.Name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not get url list")
|
||||
}
|
||||
log.Info(" This component has following urls that will be deleted with component")
|
||||
for _, u := range ul.Items {
|
||||
log.Info(" URL named ", u.GetName(), " with host ", u.Spec.Host, " having protocol ", u.Spec.Protocol, " at port ", u.Spec.Port)
|
||||
}
|
||||
}
|
||||
|
||||
storages, err := storage.List(client, currentComponent.Name, app.Name)
|
||||
odoutil.LogErrorAndExit(err, "")
|
||||
if len(storages.Items) != 0 {
|
||||
log.Info(" This component has following storages which will be deleted with the component")
|
||||
for _, storageName := range componentDesc.Spec.Storage {
|
||||
store := storages.Get(storageName)
|
||||
log.Info(" Storage named ", store.GetName(), " of size ", store.Spec.Size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// List services that will be removed
|
||||
serviceList, err := service.List(client, app.Name)
|
||||
if err != nil {
|
||||
log.Info("No services / could not get services")
|
||||
glog.V(4).Info(err.Error())
|
||||
}
|
||||
|
||||
if len(serviceList) != 0 {
|
||||
log.Info(" This application has following service that will be deleted")
|
||||
for _, ser := range serviceList {
|
||||
log.Info(" service named ", ser.Name, " of type ", ser.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,16 +3,17 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
// TODO: A neater way to provide odo path. Currently we assume \
|
||||
@@ -725,7 +726,7 @@ var _ = Describe("odoe2e", func() {
|
||||
})
|
||||
|
||||
It("should delete the deployed image-specific component", func() {
|
||||
runCmdShouldPass("odo delete testversioncmp")
|
||||
runCmdShouldPass("odo delete testversioncmp -f")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1152,6 +1153,54 @@ var _ = Describe("updateE2e", func() {
|
||||
Expect(token).To(ContainSubstring(userToken))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Deleting application, with component, should list affected children", func() {
|
||||
projectName := generateTimeBasedName("project")
|
||||
appName := generateTimeBasedName("app")
|
||||
componentName := generateTimeBasedName("component")
|
||||
urlName := generateTimeBasedName("url")
|
||||
|
||||
It("Should setup for the tests ,by creating dummy projects to test against", func() {
|
||||
odoCreateProject(projectName)
|
||||
runCmdShouldPass("odo app create " + appName)
|
||||
runCmdShouldPass("odo component create nodejs " + componentName)
|
||||
runCmdShouldPass("odo url create " + urlName)
|
||||
})
|
||||
|
||||
It("Should list affected child objects", func() {
|
||||
session := runCmdShouldPass("odo app delete -f " + appName)
|
||||
Expect(session).To(ContainSubstring("This application has following components that will be deleted"))
|
||||
Expect(session).To(ContainSubstring(componentName))
|
||||
Expect(session).To(ContainSubstring(urlName))
|
||||
})
|
||||
|
||||
It("Should delete project", func() {
|
||||
odoDeleteProject(projectName)
|
||||
})
|
||||
})
|
||||
|
||||
Context("Deleting project, with application should list affected children", func() {
|
||||
projectName := generateTimeBasedName("project")
|
||||
appName := generateTimeBasedName("app")
|
||||
componentName := generateTimeBasedName("component")
|
||||
urlName := generateTimeBasedName("url")
|
||||
|
||||
It("Should setup for the tests ,by creating dummy projects to test against", func() {
|
||||
odoCreateProject(projectName)
|
||||
runCmdShouldPass("odo app create " + appName)
|
||||
runCmdShouldPass("odo component create nodejs " + componentName)
|
||||
runCmdShouldPass("odo url create " + urlName)
|
||||
})
|
||||
|
||||
It("Should list affected child objects", func() {
|
||||
session := runCmdShouldPass("odo project delete -f " + projectName)
|
||||
Expect(session).To(ContainSubstring("This project contains the following applications, which will be deleted"))
|
||||
Expect(session).To(ContainSubstring(appName))
|
||||
Expect(session).To(ContainSubstring(componentName))
|
||||
Expect(session).To(ContainSubstring(urlName))
|
||||
})
|
||||
})
|
||||
|
||||
Context("logout of the cluster", func() {
|
||||
// test for odo logout
|
||||
It("should logout the user from the cluster", func() {
|
||||
|
||||
Reference in New Issue
Block a user