From 763761159e8d895a439ebe20a04f0de6b4cfca18 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 10 May 2022 10:50:42 +0200 Subject: [PATCH 1/9] odo describe component --- pkg/api/component.go | 15 +- pkg/odo/cli/describe/component.go | 98 +++++++++-- .../integration/devfile/cmd_describe_test.go | 162 +++++++++++++----- 3 files changed, 214 insertions(+), 61 deletions(-) diff --git a/pkg/api/component.go b/pkg/api/component.go index 914a33a9120..b834ed19bb2 100644 --- a/pkg/api/component.go +++ b/pkg/api/component.go @@ -1,5 +1,7 @@ package api +import "strings" + type RunningMode string type RunningModeList []RunningMode @@ -9,6 +11,17 @@ const ( RunningModeUnknown RunningMode = "Unknown" ) +func (o RunningModeList) String() string { + if len(o) == 0 { + return "None" + } + strs := make([]string, 0, len(o)) + for _, s := range o { + strs = append(strs, string(s)) + } + return strings.Join(strs, ", ") +} + func (u RunningModeList) Len() int { return len(u) } @@ -25,7 +38,7 @@ type Component struct { DevfilePath string `json:"devfilePath,omitempty"` DevfileData *DevfileData `json:"devfileData,omitempty"` DevForwardedPorts []ForwardedPort `json:"devForwardedPorts,omitempty"` - RunningIn []RunningMode `json:"runningIn"` + RunningIn RunningModeList `json:"runningIn"` ManagedBy string `json:"managedBy"` } diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index 05ff92b4029..679ea851af9 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -5,7 +5,11 @@ import ( "errors" "fmt" "path/filepath" + "strings" + "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/spf13/cobra" ktemplates "k8s.io/kubectl/pkg/util/templates" @@ -81,22 +85,23 @@ func (o *ComponentOptions) Validate() (err error) { } func (o *ComponentOptions) Run(ctx context.Context) error { - result, err := o.run(ctx) + result, devfileObj, err := o.run(ctx) if err != nil { return err } - printHumanReadableOutput(result) - return nil + return printHumanReadableOutput(result, devfileObj) } // Run contains the logic for the odo command func (o *ComponentOptions) RunForJsonOutput(ctx context.Context) (out interface{}, err error) { - return o.run(ctx) + result, _, err := o.run(ctx) + return result, err } -func (o *ComponentOptions) run(ctx context.Context) (result api.Component, err error) { +func (o *ComponentOptions) run(ctx context.Context) (result api.Component, devfileObj *parser.DevfileObj, err error) { if o.nameFlag != "" { - return o.describeNamedComponent(o.nameFlag) + result, err := o.describeNamedComponent(o.nameFlag) + return result, nil, err } return o.describeDevfileComponent() } @@ -114,23 +119,23 @@ func (o *ComponentOptions) describeNamedComponent(name string) (result api.Compo } // describeDevfileComponent describes the component defined by the devfile in the current directory -func (o *ComponentOptions) describeDevfileComponent() (result api.Component, err error) { +func (o *ComponentOptions) describeDevfileComponent() (result api.Component, devfile *parser.DevfileObj, err error) { devfileObj := o.EnvSpecificInfo.GetDevfileObj() path, err := filepath.Abs(".") if err != nil { - return api.Component{}, err + return api.Component{}, nil, err } forwardedPorts, err := o.clientset.StateClient.GetForwardedPorts() if err != nil { - return api.Component{}, err + return api.Component{}, nil, err } runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, devfileObj.GetMetadataName(), o.clientset.KubernetesClient.GetCurrentNamespace()) if err != nil { if !errors.As(err, &component.NoComponentFoundError{}) { - return api.Component{}, err + return api.Component{}, nil, err } else { // it is ok if the component is not deployed - forwardedPorts = nil + runningIn = nil } } return api.Component{ @@ -139,11 +144,76 @@ func (o *ComponentOptions) describeDevfileComponent() (result api.Component, err DevForwardedPorts: forwardedPorts, RunningIn: runningIn, ManagedBy: "odo", - }, nil + }, &devfileObj, nil +} + +func printHumanReadableOutput(component api.Component, devfileObj *parser.DevfileObj) error { + if component.DevfileData != nil { + fmt.Printf("Name: %s\n", component.DevfileData.Devfile.GetMetadata().Name) + fmt.Printf("Display Name: %s\n", component.DevfileData.Devfile.GetMetadata().DisplayName) + fmt.Printf("Project Type: %s\n", component.DevfileData.Devfile.GetMetadata().ProjectType) + fmt.Printf("Language: %s\n", component.DevfileData.Devfile.GetMetadata().Language) + fmt.Printf("Version: %s\n", component.DevfileData.Devfile.GetMetadata().Version) + fmt.Printf("Description: %s\n", component.DevfileData.Devfile.GetMetadata().Description) + fmt.Printf("Tags: %s\n", strings.Join(component.DevfileData.Devfile.GetMetadata().Tags, ", ")) + fmt.Println() + } + + fmt.Printf("Running in: %s\n", component.RunningIn.String()) + fmt.Println() + + if len(component.DevForwardedPorts) > 0 { + fmt.Println("Forwarded ports:") + for _, port := range component.DevForwardedPorts { + fmt.Printf(" - %s:%d -> %s:%d\n", port.LocalAddress, port.LocalPort, port.ContainerName, port.ContainerPort) + } + fmt.Println() + } + + fmt.Println("Supported odo features:") + if component.DevfileData != nil { + fmt.Printf(" - Dev: %v\n", component.DevfileData.SupportedOdoFeatures.Dev) + fmt.Printf(" - Deploy: %v\n", component.DevfileData.SupportedOdoFeatures.Deploy) + fmt.Printf(" - Debug: %v\n", component.DevfileData.SupportedOdoFeatures.Debug) + } else { + fmt.Printf(" - Dev: Unknown\n") + fmt.Printf(" - Deploy: Unknown\n") + fmt.Printf(" - Debug: Unknown\n") + } + fmt.Println() + + err := listComponentsNames("Container components:", devfileObj, v1alpha2.ContainerComponentType) + if err != nil { + return err + } + + err = listComponentsNames("Kubernetes components:", devfileObj, v1alpha2.KubernetesComponentType) + if err != nil { + return err + } + return nil } -func printHumanReadableOutput(component api.Component) { - // TODO(feloy) #5661 +func listComponentsNames(title string, devfileObj *parser.DevfileObj, typ v1alpha2.ComponentType) error { + if devfileObj == nil { + fmt.Printf("%s Unknown\n\n", title) + return nil + } + containers, err := devfileObj.Data.GetComponents(common.DevfileOptions{ + ComponentOptions: common.ComponentOptions{ComponentType: typ}, + }) + if err != nil { + return err + } + if len(containers) == 0 { + return nil + } + fmt.Println(title) + for _, container := range containers { + fmt.Printf(" - %s\n", container.Name) + } + fmt.Println() + return nil } // NewCmdComponent implements the component odo sub-command diff --git a/tests/integration/devfile/cmd_describe_test.go b/tests/integration/devfile/cmd_describe_test.go index 5290f29d10c..305f0bb1146 100644 --- a/tests/integration/devfile/cmd_describe_test.go +++ b/tests/integration/devfile/cmd_describe_test.go @@ -27,7 +27,7 @@ var _ = Describe("odo describe command tests", func() { }) It("should fail", func() { - By("running odo describe component with namespace flag without name flag", func() { + By("running odo describe component -o json with namespace flag without name flag", func() { res := helper.Cmd("odo", "describe", "component", "--namespace", "default", "-o", "json").ShouldFail() stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stderr)).To(BeTrue()) @@ -35,7 +35,7 @@ var _ = Describe("odo describe command tests", func() { helper.JsonPathContentContain(stderr, "message", "--namespace can be used only with --name") }) - By("running odo describe component without name and without devfile in the current directory", func() { + By("running odo describe component -o json without name and without devfile in the current directory", func() { res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldFail() stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stderr)).To(BeTrue()) @@ -43,13 +43,34 @@ var _ = Describe("odo describe command tests", func() { helper.JsonPathContentContain(stderr, "message", "no devfile found") }) - By("running odo describe component with an unknown name", func() { + By("running odo describe component -o json with an unknown name", func() { res := helper.Cmd("odo", "describe", "component", "--name", "unknown-name", "-o", "json").ShouldFail() stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stderr)).To(BeTrue()) Expect(stdout).To(BeEmpty()) helper.JsonPathContentContain(stderr, "message", "no component found with name \"unknown-name\" in the namespace \""+commonVar.Project+"\"") }) + + By("running odo describe component with namespace flag without name flag", func() { + res := helper.Cmd("odo", "describe", "component", "--namespace", "default").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("--namespace can be used only with --name")) + }) + + By("running odo describe component without name and without devfile in the current directory", func() { + res := helper.Cmd("odo", "describe", "component").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("no devfile found")) + }) + + By("running odo describe component with an unknown name", func() { + res := helper.Cmd("odo", "describe", "component", "--name", "unknown-name").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("no component found with name \"unknown-name\" in the namespace \"" + commonVar.Project + "\"")) + }) }) When("creating a component", func() { @@ -67,23 +88,43 @@ var _ = Describe("odo describe command tests", func() { } It("should describe the component in the current directory", func() { - res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stdout)).To(BeTrue()) - Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, "devfile.yaml") - helper.JsonPathContentIs(stdout, "runningIn", "") - helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + By("running with json output", func() { + res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stdout)).To(BeTrue()) + Expect(stderr).To(BeEmpty()) + checkDevfileDescription(stdout, "devfile.yaml") + helper.JsonPathContentIs(stdout, "runningIn", "") + helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + }) + + By("running with default output", func() { + res := helper.Cmd("odo", "describe", "component").ShouldPass() + stdout := res.Out() + Expect(stdout).To(ContainSubstring("Running in: None")) + Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) + }) }) It("should not describe the component from another directory", func() { - err := os.Chdir("/") - Expect(err).NotTo(HaveOccurred()) - res := helper.Cmd("odo", "describe", "component", "--name", cmpName, "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stderr)).To(BeTrue()) - Expect(stdout).To(BeEmpty()) - helper.JsonPathContentContain(stderr, "message", "no component found with name \""+cmpName+"\" in the namespace \""+commonVar.Project+"\"") + By("running with json output", func() { + err := os.Chdir("/") + Expect(err).NotTo(HaveOccurred()) + res := helper.Cmd("odo", "describe", "component", "--name", cmpName, "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stderr)).To(BeTrue()) + Expect(stdout).To(BeEmpty()) + helper.JsonPathContentContain(stderr, "message", "no component found with name \""+cmpName+"\" in the namespace \""+commonVar.Project+"\"") + }) + + By("running with default output", func() { + err := os.Chdir("/") + Expect(err).NotTo(HaveOccurred()) + res := helper.Cmd("odo", "describe", "component", "--name", cmpName).ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("no component found with name \"" + cmpName + "\" in the namespace \"" + commonVar.Project + "\"")) + }) }) When("renaming to hide devfile.yaml file", func() { @@ -93,13 +134,22 @@ var _ = Describe("odo describe command tests", func() { }) It("should describe the component in the current directory using the hidden devfile", func() { - res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stdout)).To(BeTrue()) - Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, ".devfile.yaml") - helper.JsonPathContentIs(stdout, "runningIn", "") - helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + By("running with json output", func() { + res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stdout)).To(BeTrue()) + Expect(stderr).To(BeEmpty()) + checkDevfileDescription(stdout, ".devfile.yaml") + helper.JsonPathContentIs(stdout, "runningIn", "") + helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + }) + + By("running with default output", func() { + res := helper.Cmd("odo", "describe", "component").ShouldPass() + stdout := res.Out() + Expect(stdout).To(ContainSubstring("Running in: None")) + Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) + }) }) }) @@ -119,31 +169,51 @@ var _ = Describe("odo describe command tests", func() { }) It("should describe the component in dev mode", func() { - res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stdout)).To(BeTrue()) - Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, "devfile.yaml") - helper.JsonPathContentIs(stdout, "devForwardedPorts.#", "1") - helper.JsonPathContentIs(stdout, "devForwardedPorts.0.containerName", "runtime") - helper.JsonPathContentIs(stdout, "devForwardedPorts.0.localAddress", "127.0.0.1") - helper.JsonPathContentIs(stdout, "devForwardedPorts.0.localPort", ports["3000"][len("127.0.0.1:"):]) - helper.JsonPathContentIs(stdout, "devForwardedPorts.0.containerPort", "3000") + By("running with json output", func() { + res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stdout)).To(BeTrue()) + Expect(stderr).To(BeEmpty()) + checkDevfileDescription(stdout, "devfile.yaml") + helper.JsonPathContentIs(stdout, "devForwardedPorts.#", "1") + helper.JsonPathContentIs(stdout, "devForwardedPorts.0.containerName", "runtime") + helper.JsonPathContentIs(stdout, "devForwardedPorts.0.localAddress", "127.0.0.1") + helper.JsonPathContentIs(stdout, "devForwardedPorts.0.localPort", ports["3000"][len("127.0.0.1:"):]) + helper.JsonPathContentIs(stdout, "devForwardedPorts.0.containerPort", "3000") + }) + + By("running with default output", func() { + res := helper.Cmd("odo", "describe", "component").ShouldPass() + stdout := res.Out() + Expect(stdout).To(ContainSubstring("Forwarded ports")) + Expect(stdout).To(ContainSubstring("127.0.0.1:" + ports["3000"][len("127.0.0.1:"):] + " -> runtime:3000")) + }) }) It("should describe the component from another directory", func() { - err := os.Chdir("/") - Expect(err).NotTo(HaveOccurred()) - res := helper.Cmd("odo", "describe", "component", "--name", cmpName, "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stdout)).To(BeTrue()) - Expect(stderr).To(BeEmpty()) - helper.JsonPathContentIs(stdout, "devfilePath", "") - helper.JsonPathContentIs(stdout, "devfileData", "") - helper.JsonPathContentIs(stdout, "devForwardedPorts", "") - helper.JsonPathContentIs(stdout, "runningIn.#", "1") - helper.JsonPathContentIs(stdout, "runningIn.0", "Dev") - helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + By("running with json output", func() { + err := os.Chdir("/") + Expect(err).NotTo(HaveOccurred()) + res := helper.Cmd("odo", "describe", "component", "--name", cmpName, "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stdout)).To(BeTrue()) + Expect(stderr).To(BeEmpty()) + helper.JsonPathContentIs(stdout, "devfilePath", "") + helper.JsonPathContentIs(stdout, "devfileData", "") + helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + helper.JsonPathContentIs(stdout, "runningIn.#", "1") + helper.JsonPathContentIs(stdout, "runningIn.0", "Dev") + helper.JsonPathContentIs(stdout, "devForwardedPorts", "") + }) + + By("running with default output", func() { + err := os.Chdir("/") + Expect(err).NotTo(HaveOccurred()) + res := helper.Cmd("odo", "describe", "component", "--name", cmpName).ShouldPass() + stdout := res.Out() + Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) + Expect(stdout).To(ContainSubstring("Running in: Dev")) + }) }) }) From 7e3a39460b322b1b7b5ba457e5fb7f14d39e8fc7 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 10 May 2022 17:48:48 +0200 Subject: [PATCH 2/9] More fields on named describe --- pkg/api/devfile-data.go | 4 +- pkg/api/utils.go | 4 +- pkg/component/component.go | 72 ++++++++++++++++--- pkg/odo/cli/describe/component.go | 48 +++++++------ .../integration/devfile/cmd_describe_test.go | 31 ++++++-- 5 files changed, 121 insertions(+), 38 deletions(-) diff --git a/pkg/api/devfile-data.go b/pkg/api/devfile-data.go index f08b6352a91..0c7b3dff141 100644 --- a/pkg/api/devfile-data.go +++ b/pkg/api/devfile-data.go @@ -4,8 +4,8 @@ import "github.com/devfile/library/pkg/devfile/parser/data" // DevfileData describes a devfile content type DevfileData struct { - Devfile data.DevfileData `json:"devfile"` - SupportedOdoFeatures SupportedOdoFeatures `json:"supportedOdoFeatures"` + Devfile data.DevfileData `json:"devfile"` + SupportedOdoFeatures *SupportedOdoFeatures `json:"supportedOdoFeatures,omitempty"` } // SupportedOdoFeatures indicates the support of high-level (odo) features by a devfile component diff --git a/pkg/api/utils.go b/pkg/api/utils.go index 8964125af66..a6bb228fdf3 100644 --- a/pkg/api/utils.go +++ b/pkg/api/utils.go @@ -13,8 +13,8 @@ func GetDevfileData(devfileObj parser.DevfileObj) *DevfileData { } } -func getSupportedOdoFeatures(devfileData data.DevfileData) SupportedOdoFeatures { - return SupportedOdoFeatures{ +func getSupportedOdoFeatures(devfileData data.DevfileData) *SupportedOdoFeatures { + return &SupportedOdoFeatures{ Dev: libdevfile.HasRunCommand(devfileData), Deploy: libdevfile.HasDeployCommand(devfileData), Debug: libdevfile.HasDebugCommand(devfileData), diff --git a/pkg/component/component.go b/pkg/component/component.go index 66cb51be6f7..18707d25440 100644 --- a/pkg/component/component.go +++ b/pkg/component/component.go @@ -10,6 +10,7 @@ import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/api/v2/pkg/devfile" "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data" dfutil "github.com/devfile/library/pkg/util" "github.com/redhat-developer/odo/pkg/api" @@ -22,7 +23,10 @@ import ( "k8s.io/klog" ) -const NotAvailable = "Not available" +const ( + NotAvailable = "Not available" + UnknownValue = "Unknown" +) // GetComponentTypeFromDevfileMetadata returns component type from the devfile metadata; // it could either be projectType or language, if neither of them are set, return 'Not available' @@ -211,14 +215,11 @@ func ListAllClusterComponents(client kclient.ClientInterface, namespace string) return components, nil } -// GetRunningModes returns the list of modes on which a "name" component is deployed, by looking into namespace -// the resources deployed with matching labels, based on the "odo.dev/mode" label -func GetRunningModes(client kclient.ClientInterface, name string, namespace string) ([]api.RunningMode, error) { - mapResult := map[string]bool{} +func getResourcesForComponent(client kclient.ClientInterface, name string, namespace string) ([]unstructured.Unstructured, error) { selector := labels.GetSelector(name, "app", labels.ComponentAnyMode) resourceList, err := client.GetAllResourcesFromSelector(selector, namespace) if err != nil { - return []api.RunningMode{api.RunningModeUnknown}, nil + return nil, err } filteredList := []unstructured.Unstructured{} for _, resource := range resourceList { @@ -228,12 +229,23 @@ func GetRunningModes(client kclient.ClientInterface, name string, namespace stri } filteredList = append(filteredList, resource) } + return filteredList, nil +} - if len(filteredList) == 0 { +// GetRunningModes returns the list of modes on which a "name" component is deployed, by looking into namespace +// the resources deployed with matching labels, based on the "odo.dev/mode" label +func GetRunningModes(client kclient.ClientInterface, name string, namespace string) ([]api.RunningMode, error) { + list, err := getResourcesForComponent(client, name, namespace) + if err != nil { + return []api.RunningMode{api.RunningModeUnknown}, nil + } + + if len(list) == 0 { return nil, NewNoComponentFoundError(name, namespace) } - for _, resource := range filteredList { + mapResult := map[string]bool{} + for _, resource := range list { resourceLabels := resource.GetLabels() mode := labels.GetMode(resourceLabels) if mode != "" { @@ -258,3 +270,47 @@ func Contains(component OdoComponent, components []OdoComponent) bool { } return false } + +// GetDevfileInfoFromCluster extracts information from the labels and annotations of resources to rebuild a Devfile +func GetDevfileInfoFromCluster(client kclient.ClientInterface, name string, namespace string) (parser.DevfileObj, error) { + list, err := getResourcesForComponent(client, name, namespace) + if err != nil { + return parser.DevfileObj{}, nil + } + + if len(list) == 0 { + return parser.DevfileObj{}, nil + } + + devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200)) + if err != nil { + return parser.DevfileObj{}, err + } + metadata := devfileData.GetMetadata() + metadata.Name = UnknownValue + metadata.DisplayName = UnknownValue + metadata.ProjectType = UnknownValue + metadata.Language = UnknownValue + metadata.Version = UnknownValue + metadata.Description = UnknownValue + + for _, resource := range list { + labels := resource.GetLabels() + annotations := resource.GetAnnotations() + name := odolabels.GetComponentName(labels) + if len(name) > 0 && metadata.Name == UnknownValue { + metadata.Name = name + } + typ, err := odolabels.GetProjectType(labels, annotations) + if err != nil { + continue + } + if len(typ) > 0 && metadata.ProjectType == UnknownValue { + metadata.ProjectType = typ + } + } + devfileData.SetMetadata(metadata) + return parser.DevfileObj{ + Data: devfileData, + }, nil +} diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index 679ea851af9..b4f19400a0e 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -100,22 +100,28 @@ func (o *ComponentOptions) RunForJsonOutput(ctx context.Context) (out interface{ func (o *ComponentOptions) run(ctx context.Context) (result api.Component, devfileObj *parser.DevfileObj, err error) { if o.nameFlag != "" { - result, err := o.describeNamedComponent(o.nameFlag) - return result, nil, err + return o.describeNamedComponent(o.nameFlag) } return o.describeDevfileComponent() } // describeNamedComponent describes a component given its name -func (o *ComponentOptions) describeNamedComponent(name string) (result api.Component, err error) { +func (o *ComponentOptions) describeNamedComponent(name string) (result api.Component, devfileObj *parser.DevfileObj, err error) { runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, name, o.clientset.KubernetesClient.GetCurrentNamespace()) if err != nil { - return api.Component{}, err + return api.Component{}, nil, err + } + devfile, err := component.GetDevfileInfoFromCluster(o.clientset.KubernetesClient, name, o.clientset.KubernetesClient.GetCurrentNamespace()) + if err != nil { + return api.Component{}, nil, err } return api.Component{ + DevfileData: &api.DevfileData{ + Devfile: devfile.Data, + }, RunningIn: runningIn, ManagedBy: "odo", - }, nil + }, &devfile, nil } // describeDevfileComponent describes the component defined by the devfile in the current directory @@ -147,34 +153,34 @@ func (o *ComponentOptions) describeDevfileComponent() (result api.Component, dev }, &devfileObj, nil } -func printHumanReadableOutput(component api.Component, devfileObj *parser.DevfileObj) error { - if component.DevfileData != nil { - fmt.Printf("Name: %s\n", component.DevfileData.Devfile.GetMetadata().Name) - fmt.Printf("Display Name: %s\n", component.DevfileData.Devfile.GetMetadata().DisplayName) - fmt.Printf("Project Type: %s\n", component.DevfileData.Devfile.GetMetadata().ProjectType) - fmt.Printf("Language: %s\n", component.DevfileData.Devfile.GetMetadata().Language) - fmt.Printf("Version: %s\n", component.DevfileData.Devfile.GetMetadata().Version) - fmt.Printf("Description: %s\n", component.DevfileData.Devfile.GetMetadata().Description) - fmt.Printf("Tags: %s\n", strings.Join(component.DevfileData.Devfile.GetMetadata().Tags, ", ")) +func printHumanReadableOutput(cmp api.Component, devfileObj *parser.DevfileObj) error { + if cmp.DevfileData != nil { + fmt.Printf("Name: %s\n", cmp.DevfileData.Devfile.GetMetadata().Name) + fmt.Printf("Display Name: %s\n", cmp.DevfileData.Devfile.GetMetadata().DisplayName) + fmt.Printf("Project Type: %s\n", cmp.DevfileData.Devfile.GetMetadata().ProjectType) + fmt.Printf("Language: %s\n", cmp.DevfileData.Devfile.GetMetadata().Language) + fmt.Printf("Version: %s\n", cmp.DevfileData.Devfile.GetMetadata().Version) + fmt.Printf("Description: %s\n", cmp.DevfileData.Devfile.GetMetadata().Description) + fmt.Printf("Tags: %s\n", strings.Join(cmp.DevfileData.Devfile.GetMetadata().Tags, ", ")) fmt.Println() } - fmt.Printf("Running in: %s\n", component.RunningIn.String()) + fmt.Printf("Running in: %s\n", cmp.RunningIn.String()) fmt.Println() - if len(component.DevForwardedPorts) > 0 { + if len(cmp.DevForwardedPorts) > 0 { fmt.Println("Forwarded ports:") - for _, port := range component.DevForwardedPorts { + for _, port := range cmp.DevForwardedPorts { fmt.Printf(" - %s:%d -> %s:%d\n", port.LocalAddress, port.LocalPort, port.ContainerName, port.ContainerPort) } fmt.Println() } fmt.Println("Supported odo features:") - if component.DevfileData != nil { - fmt.Printf(" - Dev: %v\n", component.DevfileData.SupportedOdoFeatures.Dev) - fmt.Printf(" - Deploy: %v\n", component.DevfileData.SupportedOdoFeatures.Deploy) - fmt.Printf(" - Debug: %v\n", component.DevfileData.SupportedOdoFeatures.Debug) + if cmp.DevfileData != nil && cmp.DevfileData.SupportedOdoFeatures != nil { + fmt.Printf(" - Dev: %v\n", cmp.DevfileData.SupportedOdoFeatures.Dev) + fmt.Printf(" - Deploy: %v\n", cmp.DevfileData.SupportedOdoFeatures.Deploy) + fmt.Printf(" - Debug: %v\n", cmp.DevfileData.SupportedOdoFeatures.Debug) } else { fmt.Printf(" - Dev: Unknown\n") fmt.Printf(" - Deploy: Unknown\n") diff --git a/tests/integration/devfile/cmd_describe_test.go b/tests/integration/devfile/cmd_describe_test.go index 305f0bb1146..46ecb3fddba 100644 --- a/tests/integration/devfile/cmd_describe_test.go +++ b/tests/integration/devfile/cmd_describe_test.go @@ -78,7 +78,7 @@ var _ = Describe("odo describe command tests", func() { helper.Cmd("odo", "init", "--name", cmpName, "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-registry.yaml")).ShouldPass() }) - checkDevfileDescription := func(jsonContent string, devfileName string) { + checkDevfileJSONDescription := func(jsonContent string, devfileName string) { helper.JsonPathContentIs(jsonContent, "devfilePath", filepath.Join(commonVar.Context, devfileName)) helper.JsonPathContentIs(jsonContent, "devfileData.devfile.metadata.name", cmpName) helper.JsonPathContentIs(jsonContent, "devfileData.supportedOdoFeatures.dev", "true") @@ -87,13 +87,23 @@ var _ = Describe("odo describe command tests", func() { helper.JsonPathContentIs(jsonContent, "managedBy", "odo") } + checkDevfileDescription := func(content string, withUnknown bool) { + Expect(content).To(ContainSubstring("Name: " + cmpName)) + Expect(content).To(ContainSubstring("Project Type: nodejs")) + if withUnknown { + for _, v := range []string{"Version", "Display Name", "Description", "Language"} { + Expect(content).To(ContainSubstring(v + ": Unknown")) + } + } + } + It("should describe the component in the current directory", func() { By("running with json output", func() { res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stdout)).To(BeTrue()) Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, "devfile.yaml") + checkDevfileJSONDescription(stdout, "devfile.yaml") helper.JsonPathContentIs(stdout, "runningIn", "") helper.JsonPathContentIs(stdout, "devForwardedPorts", "") }) @@ -101,6 +111,7 @@ var _ = Describe("odo describe command tests", func() { By("running with default output", func() { res := helper.Cmd("odo", "describe", "component").ShouldPass() stdout := res.Out() + checkDevfileDescription(stdout, false) Expect(stdout).To(ContainSubstring("Running in: None")) Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) }) @@ -139,7 +150,7 @@ var _ = Describe("odo describe command tests", func() { stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stdout)).To(BeTrue()) Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, ".devfile.yaml") + checkDevfileJSONDescription(stdout, ".devfile.yaml") helper.JsonPathContentIs(stdout, "runningIn", "") helper.JsonPathContentIs(stdout, "devForwardedPorts", "") }) @@ -147,6 +158,7 @@ var _ = Describe("odo describe command tests", func() { By("running with default output", func() { res := helper.Cmd("odo", "describe", "component").ShouldPass() stdout := res.Out() + checkDevfileDescription(stdout, false) Expect(stdout).To(ContainSubstring("Running in: None")) Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) }) @@ -174,7 +186,7 @@ var _ = Describe("odo describe command tests", func() { stdout, stderr := res.Out(), res.Err() Expect(helper.IsJSON(stdout)).To(BeTrue()) Expect(stderr).To(BeEmpty()) - checkDevfileDescription(stdout, "devfile.yaml") + checkDevfileJSONDescription(stdout, "devfile.yaml") helper.JsonPathContentIs(stdout, "devForwardedPorts.#", "1") helper.JsonPathContentIs(stdout, "devForwardedPorts.0.containerName", "runtime") helper.JsonPathContentIs(stdout, "devForwardedPorts.0.localAddress", "127.0.0.1") @@ -185,6 +197,7 @@ var _ = Describe("odo describe command tests", func() { By("running with default output", func() { res := helper.Cmd("odo", "describe", "component").ShouldPass() stdout := res.Out() + checkDevfileDescription(stdout, false) Expect(stdout).To(ContainSubstring("Forwarded ports")) Expect(stdout).To(ContainSubstring("127.0.0.1:" + ports["3000"][len("127.0.0.1:"):] + " -> runtime:3000")) }) @@ -199,7 +212,11 @@ var _ = Describe("odo describe command tests", func() { Expect(helper.IsJSON(stdout)).To(BeTrue()) Expect(stderr).To(BeEmpty()) helper.JsonPathContentIs(stdout, "devfilePath", "") - helper.JsonPathContentIs(stdout, "devfileData", "") + helper.JsonPathContentIs(stdout, "devfileData.devfile.metadata.name", cmpName) + helper.JsonPathContentIs(stdout, "devfileData.devfile.metadata.projectType", "nodejs") + for _, v := range []string{"version", "displayName", "description", "language"} { + helper.JsonPathContentIs(stdout, "devfileData.devfile.metadata."+v, "Unknown") + } helper.JsonPathContentIs(stdout, "devForwardedPorts", "") helper.JsonPathContentIs(stdout, "runningIn.#", "1") helper.JsonPathContentIs(stdout, "runningIn.0", "Dev") @@ -211,8 +228,12 @@ var _ = Describe("odo describe command tests", func() { Expect(err).NotTo(HaveOccurred()) res := helper.Cmd("odo", "describe", "component", "--name", cmpName).ShouldPass() stdout := res.Out() + checkDevfileDescription(stdout, true) Expect(stdout).ToNot(ContainSubstring("Forwarded ports")) Expect(stdout).To(ContainSubstring("Running in: Dev")) + Expect(stdout).To(ContainSubstring("Dev: Unknown")) + Expect(stdout).To(ContainSubstring("Deploy: Unknown")) + Expect(stdout).To(ContainSubstring("Debug: Unknown")) }) }) From b800356b797212ef619c52c61aefc4f2cf5c4be1 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 10 May 2022 18:11:46 +0200 Subject: [PATCH 3/9] Doc --- .../version-3.0.0/command-reference/describe.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/website/versioned_docs/version-3.0.0/command-reference/describe.md b/docs/website/versioned_docs/version-3.0.0/command-reference/describe.md index a545cbbcb2a..d84e563cdac 100644 --- a/docs/website/versioned_docs/version-3.0.0/command-reference/describe.md +++ b/docs/website/versioned_docs/version-3.0.0/command-reference/describe.md @@ -8,15 +8,25 @@ sidebar_position: 3 There are 2 ways to describe a component: - [Describe with access to Devfile](#describe-with-access-to-devfile) - [Describe without access to Devfile](#describe-without-access-to-devfile) -- [Available Flags](#available-flags) ## Describe with access to Devfile ```shell odo describe component ``` +This command returns information extracted from the Devfile: +- metadata (name, display name, project type, language, version, description and tags) +- supported odo features, indicating if the Devfile defines necessary information to run `odo dev`, `odo dev --debug` and `odo deploy` +- the list of container components, +- the list of Kubernetes components. + +The command also displays if the component is currently running in the cluster on Dev and/or Deploy mode. + ## Describe without access to Devfile ```shell odo describe component --name [--namespace ] ``` +The command extracts information from the labels and annotations attached to the deployed component to display the known metadata of the Devfile used to deploy the component. + +The command also displays if the component is currently running in the cluster on Dev and/or Deploy mode. From 88be65596feea0ea232d392f713a3ef2624b92e6 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 11 May 2022 08:11:57 +0200 Subject: [PATCH 4/9] Update pkg/odo/cli/describe/component.go Co-authored-by: Parthvi Vala --- pkg/odo/cli/describe/component.go | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index b4f19400a0e..ea02d53be18 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -155,36 +155,36 @@ func (o *ComponentOptions) describeDevfileComponent() (result api.Component, dev func printHumanReadableOutput(cmp api.Component, devfileObj *parser.DevfileObj) error { if cmp.DevfileData != nil { - fmt.Printf("Name: %s\n", cmp.DevfileData.Devfile.GetMetadata().Name) - fmt.Printf("Display Name: %s\n", cmp.DevfileData.Devfile.GetMetadata().DisplayName) - fmt.Printf("Project Type: %s\n", cmp.DevfileData.Devfile.GetMetadata().ProjectType) - fmt.Printf("Language: %s\n", cmp.DevfileData.Devfile.GetMetadata().Language) - fmt.Printf("Version: %s\n", cmp.DevfileData.Devfile.GetMetadata().Version) - fmt.Printf("Description: %s\n", cmp.DevfileData.Devfile.GetMetadata().Description) - fmt.Printf("Tags: %s\n", strings.Join(cmp.DevfileData.Devfile.GetMetadata().Tags, ", ")) + log.Describef("Name: ", cmp.DevfileData.Devfile.GetMetadata().Name) + log.Describef("Display Name: ", cmp.DevfileData.Devfile.GetMetadata().DisplayName) + log.Describef("Project Type: ", cmp.DevfileData.Devfile.GetMetadata().ProjectType) + log.Describef("Language: ", cmp.DevfileData.Devfile.GetMetadata().Language) + log.Describef("Version: ", cmp.DevfileData.Devfile.GetMetadata().Version) + log.Describef("Description: ", cmp.DevfileData.Devfile.GetMetadata().Description) + log.Describef("Tags: ", strings.Join(cmp.DevfileData.Devfile.GetMetadata().Tags, ", ")) fmt.Println() } - fmt.Printf("Running in: %s\n", cmp.RunningIn.String()) + log.Describef("Running in: ", cmp.RunningIn.String()) fmt.Println() if len(cmp.DevForwardedPorts) > 0 { - fmt.Println("Forwarded ports:") + log.Info("Forwarded ports:") for _, port := range cmp.DevForwardedPorts { - fmt.Printf(" - %s:%d -> %s:%d\n", port.LocalAddress, port.LocalPort, port.ContainerName, port.ContainerPort) + log.Printf("%s:%d -> %s:%d", port.LocalAddress, port.LocalPort, port.ContainerName, port.ContainerPort) } fmt.Println() } - fmt.Println("Supported odo features:") + log.Info("Supported odo features:") if cmp.DevfileData != nil && cmp.DevfileData.SupportedOdoFeatures != nil { - fmt.Printf(" - Dev: %v\n", cmp.DevfileData.SupportedOdoFeatures.Dev) - fmt.Printf(" - Deploy: %v\n", cmp.DevfileData.SupportedOdoFeatures.Deploy) - fmt.Printf(" - Debug: %v\n", cmp.DevfileData.SupportedOdoFeatures.Debug) + log.Printf("Dev: %v", cmp.DevfileData.SupportedOdoFeatures.Dev) + log.Printf("Deploy: %v", cmp.DevfileData.SupportedOdoFeatures.Deploy) + log.Printf("Debug: %v", cmp.DevfileData.SupportedOdoFeatures.Debug) } else { - fmt.Printf(" - Dev: Unknown\n") - fmt.Printf(" - Deploy: Unknown\n") - fmt.Printf(" - Debug: Unknown\n") + log.Printf("Dev: Unknown") + log.Printf("Deploy: Unknown") + log.Printf("Debug: Unknown") } fmt.Println() From 755626c169a173599e1e67fe1e2804a3b7d6939b Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 11 May 2022 08:12:16 +0200 Subject: [PATCH 5/9] Update pkg/odo/cli/describe/component.go Co-authored-by: Parthvi Vala --- pkg/odo/cli/describe/component.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index ea02d53be18..ba2442cc83b 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -202,7 +202,7 @@ func printHumanReadableOutput(cmp api.Component, devfileObj *parser.DevfileObj) func listComponentsNames(title string, devfileObj *parser.DevfileObj, typ v1alpha2.ComponentType) error { if devfileObj == nil { - fmt.Printf("%s Unknown\n\n", title) + log.Describef(title, " Unknown") return nil } containers, err := devfileObj.Data.GetComponents(common.DevfileOptions{ From 978b365feda013342443b43d21a6fc95e526a521 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 11 May 2022 08:12:23 +0200 Subject: [PATCH 6/9] Update pkg/odo/cli/describe/component.go Co-authored-by: Parthvi Vala --- pkg/odo/cli/describe/component.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index ba2442cc83b..96594060eae 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -214,9 +214,9 @@ func listComponentsNames(title string, devfileObj *parser.DevfileObj, typ v1alph if len(containers) == 0 { return nil } - fmt.Println(title) + log.Info(title) for _, container := range containers { - fmt.Printf(" - %s\n", container.Name) + log.Printf("%s", container.Name) } fmt.Println() return nil From 9e71f8c2ab7574c6a0486de67bd69c2d84624156 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 11 May 2022 08:17:28 +0200 Subject: [PATCH 7/9] Add Describef --- pkg/log/status.go | 10 ++++++++++ pkg/odo/cli/describe/component.go | 1 + 2 files changed, 11 insertions(+) diff --git a/pkg/log/status.go b/pkg/log/status.go index a36f707b970..a72de3613f2 100644 --- a/pkg/log/status.go +++ b/pkg/log/status.go @@ -386,6 +386,16 @@ func Sbold(s string) string { return bold(fmt.Sprint(s)) } +// Describef will print out the first variable as BOLD and then the second not.. +// this is intended to be used with `odo describe` and other outputs that list +// a lot of information +func Describef(title string, format string, a ...interface{}) { + if !IsJSON() { + bold := color.New(color.Bold).SprintFunc() + fmt.Fprintf(GetStdout(), "%s%s\n", bold(title), fmt.Sprintf(format, a...)) + } +} + // Spinner creates a spinner, sets the prefix then returns it. // Remember to use .End(bool) to stop the spin / when you're done. // For example: defer s.End(false) diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index 96594060eae..dc9de49f144 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -15,6 +15,7 @@ import ( "github.com/redhat-developer/odo/pkg/api" "github.com/redhat-developer/odo/pkg/component" + "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/machineoutput" "github.com/redhat-developer/odo/pkg/odo/cmdline" "github.com/redhat-developer/odo/pkg/odo/genericclioptions" From edf6332c1b40c07600ffd57337a13e211bd3136b Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 11 May 2022 09:47:17 +0200 Subject: [PATCH 8/9] Parthvi review --- pkg/component/component.go | 10 ++++----- pkg/component/component_test.go | 35 +++++++++++++++---------------- pkg/odo/cli/describe/component.go | 6 +++--- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/pkg/component/component.go b/pkg/component/component.go index 18707d25440..aea5b74141d 100644 --- a/pkg/component/component.go +++ b/pkg/component/component.go @@ -234,14 +234,14 @@ func getResourcesForComponent(client kclient.ClientInterface, name string, names // GetRunningModes returns the list of modes on which a "name" component is deployed, by looking into namespace // the resources deployed with matching labels, based on the "odo.dev/mode" label -func GetRunningModes(client kclient.ClientInterface, name string, namespace string) ([]api.RunningMode, error) { - list, err := getResourcesForComponent(client, name, namespace) +func GetRunningModes(client kclient.ClientInterface, name string) ([]api.RunningMode, error) { + list, err := getResourcesForComponent(client, name, client.GetCurrentNamespace()) if err != nil { return []api.RunningMode{api.RunningModeUnknown}, nil } if len(list) == 0 { - return nil, NewNoComponentFoundError(name, namespace) + return nil, NewNoComponentFoundError(name, client.GetCurrentNamespace()) } mapResult := map[string]bool{} @@ -272,8 +272,8 @@ func Contains(component OdoComponent, components []OdoComponent) bool { } // GetDevfileInfoFromCluster extracts information from the labels and annotations of resources to rebuild a Devfile -func GetDevfileInfoFromCluster(client kclient.ClientInterface, name string, namespace string) (parser.DevfileObj, error) { - list, err := getResourcesForComponent(client, name, namespace) +func GetDevfileInfoFromCluster(client kclient.ClientInterface, name string) (parser.DevfileObj, error) { + list, err := getResourcesForComponent(client, name, client.GetCurrentNamespace()) if err != nil { return parser.DevfileObj{}, nil } diff --git a/pkg/component/component_test.go b/pkg/component/component_test.go index 7539889821f..eec15ee504d 100644 --- a/pkg/component/component_test.go +++ b/pkg/component/component_test.go @@ -171,9 +171,8 @@ func TestGetRunningModes(t *testing.T) { packageManifestResource.SetLabels(labels.Builder().WithMode(labels.ComponentDevMode).Labels()) type args struct { - client func(ctrl *gomock.Controller) kclient.ClientInterface - name string - namespace string + client func(ctrl *gomock.Controller) kclient.ClientInterface + name string } tests := []struct { name string @@ -186,11 +185,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: nil, wantErr: true, @@ -200,11 +199,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{packageManifestResource}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: nil, wantErr: true, @@ -214,11 +213,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{packageManifestResource, otherResource}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: []api.RunningMode{}, }, @@ -227,11 +226,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{packageManifestResource, otherResource, resourceDev1, resourceDev2}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: []api.RunningMode{api.RunningModeDev}, }, @@ -240,11 +239,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{packageManifestResource, otherResource, resourceDeploy1, resourceDeploy2}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: []api.RunningMode{api.RunningModeDeploy}, }, @@ -253,11 +252,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return([]unstructured.Unstructured{packageManifestResource, otherResource, resourceDev1, resourceDev2, resourceDeploy1, resourceDeploy2}, nil) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: []api.RunningMode{api.RunningModeDev, api.RunningModeDeploy}, }, @@ -266,11 +265,11 @@ func TestGetRunningModes(t *testing.T) { args: args{ client: func(ctrl *gomock.Controller) kclient.ClientInterface { c := kclient.NewMockClientInterface(ctrl) + c.EXPECT().GetCurrentNamespace().Return("a-namespace").AnyTimes() c.EXPECT().GetAllResourcesFromSelector(gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) return c }, - name: "aname", - namespace: "anamespace", + name: "aname", }, want: []api.RunningMode{api.RunningModeUnknown}, }, @@ -278,7 +277,7 @@ func TestGetRunningModes(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) - got, err := GetRunningModes(tt.args.client(ctrl), tt.args.name, tt.args.namespace) + got, err := GetRunningModes(tt.args.client(ctrl), tt.args.name) if (err != nil) != tt.wantErr { t.Errorf("error = %v, wantErr %v", err, tt.wantErr) return diff --git a/pkg/odo/cli/describe/component.go b/pkg/odo/cli/describe/component.go index dc9de49f144..e7918ac1a4d 100644 --- a/pkg/odo/cli/describe/component.go +++ b/pkg/odo/cli/describe/component.go @@ -108,11 +108,11 @@ func (o *ComponentOptions) run(ctx context.Context) (result api.Component, devfi // describeNamedComponent describes a component given its name func (o *ComponentOptions) describeNamedComponent(name string) (result api.Component, devfileObj *parser.DevfileObj, err error) { - runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, name, o.clientset.KubernetesClient.GetCurrentNamespace()) + runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, name) if err != nil { return api.Component{}, nil, err } - devfile, err := component.GetDevfileInfoFromCluster(o.clientset.KubernetesClient, name, o.clientset.KubernetesClient.GetCurrentNamespace()) + devfile, err := component.GetDevfileInfoFromCluster(o.clientset.KubernetesClient, name) if err != nil { return api.Component{}, nil, err } @@ -136,7 +136,7 @@ func (o *ComponentOptions) describeDevfileComponent() (result api.Component, dev if err != nil { return api.Component{}, nil, err } - runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, devfileObj.GetMetadataName(), o.clientset.KubernetesClient.GetCurrentNamespace()) + runningIn, err := component.GetRunningModes(o.clientset.KubernetesClient, devfileObj.GetMetadataName()) if err != nil { if !errors.As(err, &component.NoComponentFoundError{}) { return api.Component{}, nil, err From cfdff496ec3954afca975be035208b3133c9d3a2 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Thu, 12 May 2022 09:07:34 +0200 Subject: [PATCH 9/9] Fix rebase --- pkg/registry/registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index dca67fe313d..25ec070cae6 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -165,7 +165,7 @@ func (o RegistryClient) ListDevfileStacks(registryName, devfileFlag, filterFlag if err != nil { return *catalogDevfileList, err } - devfile.SupportedOdoFeatures = devfileData.SupportedOdoFeatures + devfile.SupportedOdoFeatures = *devfileData.SupportedOdoFeatures } devfiles = append(devfiles, devfile)