Skip to content

Commit

Permalink
odo dev/deploy should display a warning about default namespace on cl…
Browse files Browse the repository at this point in the history
…uster (#6688)

* odo dev/deploy should display a warning about default namespace on cluster

Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Move warning to after odo title

Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Add integration test for odo dev/deploy when not connected to a cluster or podman

Signed-off-by: Parthvi Vala <pvala@redhat.com>
Co-authored-by: Armel Soro <armel@rm3l.org>
Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Fix podman test failure-s

* Add a new line before warning, and use corev1.NamespaceDefault instead of default

Signed-off-by: Parthvi Vala <pvala@redhat.com>

---------

Signed-off-by: Parthvi Vala <pvala@redhat.com>
Co-authored-by: Armel Soro <armel@rm3l.org>
  • Loading branch information
valaparthvi and rm3l authored Mar 29, 2023
1 parent 61d53dc commit dfb36dd
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 50 deletions.
6 changes: 6 additions & 0 deletions pkg/odo/cli/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
dfutil "github.com/devfile/library/v2/pkg/util"
"github.com/redhat-developer/odo/pkg/kclient"

"github.com/redhat-developer/odo/pkg/component"
"github.com/redhat-developer/odo/pkg/log"
Expand Down Expand Up @@ -63,6 +64,9 @@ func (o *DeployOptions) Validate(ctx context.Context) error {
if devfileObj == nil {
return genericclioptions.NewNoDevfileError(odocontext.GetWorkingDirectory(ctx))
}
if o.clientset.KubernetesClient == nil {
return kclient.NewNoConnectionError()
}
componentName := odocontext.GetComponentName(ctx)
err := dfutil.ValidateK8sResourceName("component name", componentName)
return err
Expand All @@ -85,6 +89,8 @@ func (o *DeployOptions) Run(ctx context.Context) error {
"Namespace: "+namespace,
"odo version: "+version.VERSION)

genericclioptions.WarnIfDefaultNamespace(namespace, o.clientset.KubernetesClient)

// Run actual deploy command to be used
err := o.clientset.DeployClient.Deploy(ctx)

Expand Down
4 changes: 3 additions & 1 deletion pkg/odo/cli/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
log.Title("Developing using the \""+componentName+"\" Devfile",
dest,
"odo version: "+version.VERSION)

if platform == commonflags.PlatformCluster {
genericclioptions.WarnIfDefaultNamespace(odocontext.GetNamespace(ctx), o.clientset.KubernetesClient)
}
// check for .gitignore file and add odo-file-index.json to .gitignore.
// In case the .gitignore was created by odo, it is purposely not reported as candidate for deletion (via a call to files.ReportLocalFileGeneratedByOdo)
// because a .gitignore file is more likely to be modified by the user afterward (for another usage).
Expand Down
17 changes: 17 additions & 0 deletions pkg/odo/genericclioptions/util.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package genericclioptions

import (
"fmt"
"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/log"
pkgUtil "github.com/redhat-developer/odo/pkg/util"
v1 "k8s.io/api/core/v1"

dfutil "github.com/devfile/library/v2/pkg/util"
)
Expand Down Expand Up @@ -34,3 +38,16 @@ func ApplyIgnore(ignores *[]string, sourcePath string) (err error) {

return nil
}

// WarnIfDefaultNamespace warns when user tries to run `odo dev` or `odo deploy` in the default namespace
func WarnIfDefaultNamespace(namespace string, kubeClient kclient.ClientInterface) {
if namespace == v1.NamespaceDefault {
noun := "namespace"
if isOC, _ := kubeClient.IsProjectSupported(); isOC {
noun = "project"
}
fmt.Println()
log.Warningf("You are using \"default\" %[1]s, odo may not work as expected in the default %[1]s.", noun)
log.Warningf("You may set a new %[1]s by running `odo create %[1]s <name>`, or set an existing one by running `odo set %[1]s <name>`", noun)
}
}
10 changes: 7 additions & 3 deletions tests/helper/helper_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,22 @@ func RunDevMode(options DevSessionOpts, inside func(session *gexec.Session, outC
return nil
}

// DevModeShouldFail runs `odo dev` with an intention to fail, and checks for a given substring
// WaitForDevModeToContain runs `odo dev` until it contains a given substring in output or errOut(depending on checkErrOut arg).
// `odo dev` runs in an infinite reconciliation loop, and hence running it with Cmd will not work for a lot of failing cases,
// this function is helpful in such cases.
// TODO(pvala): Modify StartDevMode to take substring arg into account, and replace this method with it.
func DevModeShouldFail(options DevSessionOpts, substring string) (DevSession, []byte, []byte, error) {
func WaitForDevModeToContain(options DevSessionOpts, substring string, checkErrOut bool) (DevSession, []byte, []byte, error) {
args := []string{"dev", "--random-ports"}
args = append(args, options.CmdlineArgs...)
if options.RunOnPodman {
args = append(args, "--platform", "podman")
}
session := Cmd("odo", args...).AddEnv(options.EnvVars...).Runner().session
WaitForOutputToContain(substring, 360, 10, session)
if checkErrOut {
WaitForErroutToContain(substring, 360, 10, session)
} else {
WaitForOutputToContain(substring, 360, 10, session)
}
result := DevSession{
session: session,
}
Expand Down
6 changes: 5 additions & 1 deletion tests/helper/helper_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,11 @@ func RunTestSpecs(t *testing.T, description string) {
}

func IsKubernetesCluster() bool {
return os.Getenv("KUBERNETES") == "true"
k8s, err := strconv.ParseBool(os.Getenv("KUBERNETES"))
if err != nil {
return false
}
return k8s
}

type ResourceInfo struct {
Expand Down
76 changes: 31 additions & 45 deletions tests/integration/cmd_dev_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,40 @@ var _ = Describe("odo dev command tests", func() {
})
})

When("a component is bootstrapped and pushed", func() {
When("a component is bootstrapped", func() {
BeforeEach(func() {
helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context)
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass()
Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeFalse())
})

It("should fail to run odo dev when not connected to any cluster", Label(helper.LabelNoCluster), func() {
errOut := helper.Cmd("odo", "dev").ShouldFail().Err()
Expect(errOut).To(ContainSubstring("unable to access the cluster"))
})
It("should fail to run odo dev when podman is nil", Label(helper.LabelPodman), func() {
errOut := helper.Cmd("odo", "dev", "--platform", "podman").WithEnv("PODMAN_CMD=echo").ShouldFail().Err()
Expect(errOut).To(ContainSubstring("unable to access podman"))
})
When("using a default namespace", func() {
BeforeEach(func() {
commonVar.CliRunner.SetProject("default")
})
AfterEach(func() {
commonVar.CliRunner.SetProject(commonVar.Project)
})
It("should print warning about default namespace when running odo dev", func() {
namespace := "project"
if helper.IsKubernetesCluster() {
namespace = "namespace"
}
err := helper.RunDevMode(helper.DevSessionOpts{}, func(session *gexec.Session, outContents []byte, errContents []byte, ports map[string]string) {
Expect(string(errContents)).To(ContainSubstring(fmt.Sprintf("You are using \"default\" %[1]s, odo may not work as expected in the default %[1]s.", namespace)))
})
Expect(err).ToNot(HaveOccurred())
})
})

It("should add annotation to use ImageStreams", func() {
// #6376
err := helper.RunDevMode(helper.DevSessionOpts{}, func(session *gexec.Session, outContents, errContents []byte, ports map[string]string) {
Expand Down Expand Up @@ -1807,11 +1834,12 @@ CMD ["npm", "start"]
})

It("should not build images when odo dev is run", func() {
_, sessionOut, _, err := helper.DevModeShouldFail(
_, sessionOut, _, err := helper.WaitForDevModeToContain(
helper.DevSessionOpts{
EnvVars: env,
},
"failed to retrieve "+url)
"failed to retrieve "+url,
false)
Expect(err).To(BeNil())
Expect(sessionOut).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f "))
Expect(sessionOut).NotTo(ContainSubstring("push quay.io/unknown-account/myimage"))
Expand Down Expand Up @@ -2658,48 +2686,6 @@ CMD ["npm", "start"]
}))
}

Context("using Kubernetes cluster", func() {
BeforeEach(func() {
if os.Getenv("KUBERNETES") != "true" {
Skip("This is a Kubernetes specific scenario, skipping")
}
})

It("should run odo dev successfully on default namespace", func() {
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass()
helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context)

session, _, errContents, _, err := helper.StartDevMode(helper.DevSessionOpts{})
Expect(err).ToNot(HaveOccurred())
defer func() {
session.Stop()
session.WaitEnd()
}()
helper.DontMatchAllInOutput(string(errContents), []string{"odo may not work as expected in the default project"})
})
})

/* TODO(feloy) Issue #5591
Context("using OpenShift cluster", func() {
BeforeEach(func() {
if os.Getenv("KUBERNETES") == "true" {
Skip("This is a OpenShift specific scenario, skipping")
}
})
It("should run odo dev successfully on default namespace", func() {
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass()
helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context)
session, _, errContents, err := helper.StartDevMode(helper.DevSessionOpts{})
Expect(err).ToNot(HaveOccurred())
defer session.Stop()
helper.MatchAllInOutput(string(errContents), []string{"odo may not work as expected in the default project"})
})
})
*/

// Test reused and adapted from the now-removed `cmd_devfile_delete_test.go`.
// cf. https://github.com/redhat-developer/odo/blob/24fd02673d25eb4c7bb166ec3369554a8e64b59c/tests/integration/devfile/cmd_devfile_delete_test.go#L172-L238
When("a component with endpoints is bootstrapped and pushed", func() {
Expand Down
27 changes: 27 additions & 0 deletions tests/integration/cmd_devfile_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,34 @@ var _ = Describe("odo devfile deploy command tests", func() {

})
})
When("a component is bootstrapped", func() {
BeforeEach(func() {
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-deploy.yaml")).ShouldPass()
})
When("using a default namespace", func() {
BeforeEach(func() {
commonVar.CliRunner.SetProject("default")
})
AfterEach(func() {
helper.Cmd("odo", "delete", "component", "-f").ShouldPass()
commonVar.CliRunner.SetProject(commonVar.Project)
})

It("should display warning when running the deploy command", func() {
errOut := helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldRun().Err()
namespace := "project"
if helper.IsKubernetesCluster() {
namespace = "namespace"
}
Expect(errOut).To(ContainSubstring(fmt.Sprintf("You are using \"default\" %[1]s, odo may not work as expected in the default %[1]s.", namespace)))
})
})
It("should fail to run odo deploy when not connected to any cluster", Label(helper.LabelNoCluster), func() {
errOut := helper.Cmd("odo", "deploy").ShouldFail().Err()
Expect(errOut).To(ContainSubstring("unable to access the cluster"))
})
})
for _, ctx := range []struct {
title string
devfileName string
Expand Down

0 comments on commit dfb36dd

Please sign in to comment.