Skip to content

Commit dfb36dd

Browse files
valaparthvirm3l
andauthored
odo dev/deploy should display a warning about default namespace on cluster (#6688)
* odo dev/deploy should display a warning about default namespace on cluster Signed-off-by: Parthvi Vala <[email protected]> * Move warning to after odo title Signed-off-by: Parthvi Vala <[email protected]> * Add integration test for odo dev/deploy when not connected to a cluster or podman Signed-off-by: Parthvi Vala <[email protected]> Co-authored-by: Armel Soro <[email protected]> Signed-off-by: Parthvi Vala <[email protected]> * Fix podman test failure-s * Add a new line before warning, and use corev1.NamespaceDefault instead of default Signed-off-by: Parthvi Vala <[email protected]> --------- Signed-off-by: Parthvi Vala <[email protected]> Co-authored-by: Armel Soro <[email protected]>
1 parent 61d53dc commit dfb36dd

File tree

7 files changed

+96
-50
lines changed

7 files changed

+96
-50
lines changed

pkg/odo/cli/deploy/deploy.go

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
dfutil "github.com/devfile/library/v2/pkg/util"
7+
"github.com/redhat-developer/odo/pkg/kclient"
78

89
"github.com/redhat-developer/odo/pkg/component"
910
"github.com/redhat-developer/odo/pkg/log"
@@ -63,6 +64,9 @@ func (o *DeployOptions) Validate(ctx context.Context) error {
6364
if devfileObj == nil {
6465
return genericclioptions.NewNoDevfileError(odocontext.GetWorkingDirectory(ctx))
6566
}
67+
if o.clientset.KubernetesClient == nil {
68+
return kclient.NewNoConnectionError()
69+
}
6670
componentName := odocontext.GetComponentName(ctx)
6771
err := dfutil.ValidateK8sResourceName("component name", componentName)
6872
return err
@@ -85,6 +89,8 @@ func (o *DeployOptions) Run(ctx context.Context) error {
8589
"Namespace: "+namespace,
8690
"odo version: "+version.VERSION)
8791

92+
genericclioptions.WarnIfDefaultNamespace(namespace, o.clientset.KubernetesClient)
93+
8894
// Run actual deploy command to be used
8995
err := o.clientset.DeployClient.Deploy(ctx)
9096

pkg/odo/cli/dev/dev.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
157157
log.Title("Developing using the \""+componentName+"\" Devfile",
158158
dest,
159159
"odo version: "+version.VERSION)
160-
160+
if platform == commonflags.PlatformCluster {
161+
genericclioptions.WarnIfDefaultNamespace(odocontext.GetNamespace(ctx), o.clientset.KubernetesClient)
162+
}
161163
// check for .gitignore file and add odo-file-index.json to .gitignore.
162164
// In case the .gitignore was created by odo, it is purposely not reported as candidate for deletion (via a call to files.ReportLocalFileGeneratedByOdo)
163165
// because a .gitignore file is more likely to be modified by the user afterward (for another usage).

pkg/odo/genericclioptions/util.go

+17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package genericclioptions
22

33
import (
4+
"fmt"
5+
"github.com/redhat-developer/odo/pkg/kclient"
6+
"github.com/redhat-developer/odo/pkg/log"
47
pkgUtil "github.com/redhat-developer/odo/pkg/util"
8+
v1 "k8s.io/api/core/v1"
59

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

3539
return nil
3640
}
41+
42+
// WarnIfDefaultNamespace warns when user tries to run `odo dev` or `odo deploy` in the default namespace
43+
func WarnIfDefaultNamespace(namespace string, kubeClient kclient.ClientInterface) {
44+
if namespace == v1.NamespaceDefault {
45+
noun := "namespace"
46+
if isOC, _ := kubeClient.IsProjectSupported(); isOC {
47+
noun = "project"
48+
}
49+
fmt.Println()
50+
log.Warningf("You are using \"default\" %[1]s, odo may not work as expected in the default %[1]s.", noun)
51+
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)
52+
}
53+
}

tests/helper/helper_dev.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -255,18 +255,22 @@ func RunDevMode(options DevSessionOpts, inside func(session *gexec.Session, outC
255255
return nil
256256
}
257257

258-
// DevModeShouldFail runs `odo dev` with an intention to fail, and checks for a given substring
258+
// WaitForDevModeToContain runs `odo dev` until it contains a given substring in output or errOut(depending on checkErrOut arg).
259259
// `odo dev` runs in an infinite reconciliation loop, and hence running it with Cmd will not work for a lot of failing cases,
260260
// this function is helpful in such cases.
261261
// TODO(pvala): Modify StartDevMode to take substring arg into account, and replace this method with it.
262-
func DevModeShouldFail(options DevSessionOpts, substring string) (DevSession, []byte, []byte, error) {
262+
func WaitForDevModeToContain(options DevSessionOpts, substring string, checkErrOut bool) (DevSession, []byte, []byte, error) {
263263
args := []string{"dev", "--random-ports"}
264264
args = append(args, options.CmdlineArgs...)
265265
if options.RunOnPodman {
266266
args = append(args, "--platform", "podman")
267267
}
268268
session := Cmd("odo", args...).AddEnv(options.EnvVars...).Runner().session
269-
WaitForOutputToContain(substring, 360, 10, session)
269+
if checkErrOut {
270+
WaitForErroutToContain(substring, 360, 10, session)
271+
} else {
272+
WaitForOutputToContain(substring, 360, 10, session)
273+
}
270274
result := DevSession{
271275
session: session,
272276
}

tests/helper/helper_generic.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,11 @@ func RunTestSpecs(t *testing.T, description string) {
353353
}
354354

355355
func IsKubernetesCluster() bool {
356-
return os.Getenv("KUBERNETES") == "true"
356+
k8s, err := strconv.ParseBool(os.Getenv("KUBERNETES"))
357+
if err != nil {
358+
return false
359+
}
360+
return k8s
357361
}
358362

359363
type ResourceInfo struct {

tests/integration/cmd_dev_test.go

+31-45
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,40 @@ var _ = Describe("odo dev command tests", func() {
6161
})
6262
})
6363

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

71+
It("should fail to run odo dev when not connected to any cluster", Label(helper.LabelNoCluster), func() {
72+
errOut := helper.Cmd("odo", "dev").ShouldFail().Err()
73+
Expect(errOut).To(ContainSubstring("unable to access the cluster"))
74+
})
75+
It("should fail to run odo dev when podman is nil", Label(helper.LabelPodman), func() {
76+
errOut := helper.Cmd("odo", "dev", "--platform", "podman").WithEnv("PODMAN_CMD=echo").ShouldFail().Err()
77+
Expect(errOut).To(ContainSubstring("unable to access podman"))
78+
})
79+
When("using a default namespace", func() {
80+
BeforeEach(func() {
81+
commonVar.CliRunner.SetProject("default")
82+
})
83+
AfterEach(func() {
84+
commonVar.CliRunner.SetProject(commonVar.Project)
85+
})
86+
It("should print warning about default namespace when running odo dev", func() {
87+
namespace := "project"
88+
if helper.IsKubernetesCluster() {
89+
namespace = "namespace"
90+
}
91+
err := helper.RunDevMode(helper.DevSessionOpts{}, func(session *gexec.Session, outContents []byte, errContents []byte, ports map[string]string) {
92+
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)))
93+
})
94+
Expect(err).ToNot(HaveOccurred())
95+
})
96+
})
97+
7198
It("should add annotation to use ImageStreams", func() {
7299
// #6376
73100
err := helper.RunDevMode(helper.DevSessionOpts{}, func(session *gexec.Session, outContents, errContents []byte, ports map[string]string) {
@@ -1807,11 +1834,12 @@ CMD ["npm", "start"]
18071834
})
18081835

18091836
It("should not build images when odo dev is run", func() {
1810-
_, sessionOut, _, err := helper.DevModeShouldFail(
1837+
_, sessionOut, _, err := helper.WaitForDevModeToContain(
18111838
helper.DevSessionOpts{
18121839
EnvVars: env,
18131840
},
1814-
"failed to retrieve "+url)
1841+
"failed to retrieve "+url,
1842+
false)
18151843
Expect(err).To(BeNil())
18161844
Expect(sessionOut).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f "))
18171845
Expect(sessionOut).NotTo(ContainSubstring("push quay.io/unknown-account/myimage"))
@@ -2658,48 +2686,6 @@ CMD ["npm", "start"]
26582686
}))
26592687
}
26602688

2661-
Context("using Kubernetes cluster", func() {
2662-
BeforeEach(func() {
2663-
if os.Getenv("KUBERNETES") != "true" {
2664-
Skip("This is a Kubernetes specific scenario, skipping")
2665-
}
2666-
})
2667-
2668-
It("should run odo dev successfully on default namespace", func() {
2669-
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
2670-
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass()
2671-
helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context)
2672-
2673-
session, _, errContents, _, err := helper.StartDevMode(helper.DevSessionOpts{})
2674-
Expect(err).ToNot(HaveOccurred())
2675-
defer func() {
2676-
session.Stop()
2677-
session.WaitEnd()
2678-
}()
2679-
helper.DontMatchAllInOutput(string(errContents), []string{"odo may not work as expected in the default project"})
2680-
})
2681-
})
2682-
2683-
/* TODO(feloy) Issue #5591
2684-
Context("using OpenShift cluster", func() {
2685-
BeforeEach(func() {
2686-
if os.Getenv("KUBERNETES") == "true" {
2687-
Skip("This is a OpenShift specific scenario, skipping")
2688-
}
2689-
})
2690-
It("should run odo dev successfully on default namespace", func() {
2691-
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
2692-
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass()
2693-
helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context)
2694-
2695-
session, _, errContents, err := helper.StartDevMode(helper.DevSessionOpts{})
2696-
Expect(err).ToNot(HaveOccurred())
2697-
defer session.Stop()
2698-
helper.MatchAllInOutput(string(errContents), []string{"odo may not work as expected in the default project"})
2699-
})
2700-
})
2701-
*/
2702-
27032689
// Test reused and adapted from the now-removed `cmd_devfile_delete_test.go`.
27042690
// cf. https://github.com/redhat-developer/odo/blob/24fd02673d25eb4c7bb166ec3369554a8e64b59c/tests/integration/devfile/cmd_devfile_delete_test.go#L172-L238
27052691
When("a component with endpoints is bootstrapped and pushed", func() {

tests/integration/cmd_devfile_deploy_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,34 @@ var _ = Describe("odo devfile deploy command tests", func() {
4545

4646
})
4747
})
48+
When("a component is bootstrapped", func() {
49+
BeforeEach(func() {
50+
helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context)
51+
helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-deploy.yaml")).ShouldPass()
52+
})
53+
When("using a default namespace", func() {
54+
BeforeEach(func() {
55+
commonVar.CliRunner.SetProject("default")
56+
})
57+
AfterEach(func() {
58+
helper.Cmd("odo", "delete", "component", "-f").ShouldPass()
59+
commonVar.CliRunner.SetProject(commonVar.Project)
60+
})
4861

62+
It("should display warning when running the deploy command", func() {
63+
errOut := helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldRun().Err()
64+
namespace := "project"
65+
if helper.IsKubernetesCluster() {
66+
namespace = "namespace"
67+
}
68+
Expect(errOut).To(ContainSubstring(fmt.Sprintf("You are using \"default\" %[1]s, odo may not work as expected in the default %[1]s.", namespace)))
69+
})
70+
})
71+
It("should fail to run odo deploy when not connected to any cluster", Label(helper.LabelNoCluster), func() {
72+
errOut := helper.Cmd("odo", "deploy").ShouldFail().Err()
73+
Expect(errOut).To(ContainSubstring("unable to access the cluster"))
74+
})
75+
})
4976
for _, ctx := range []struct {
5077
title string
5178
devfileName string

0 commit comments

Comments
 (0)