Added machine readable output for odo project list (#1370)

Fixes #1361

How to test ?

```
odo project list -o json
```
This commit is contained in:
Suraj Narwade
2019-04-02 16:11:51 +05:30
committed by OpenShift Merge Robot
parent 3e41ae1b35
commit fed18100f9
6 changed files with 104 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
package project
import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"
@@ -50,20 +51,28 @@ func (plo *ProjectListOptions) Run() (err error) {
if err != nil {
return err
}
if len(projects) == 0 {
return fmt.Errorf("You are not a member of any projects. You can request a project to be created using the `odo project create <project_name>` command")
}
w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent)
fmt.Fprintln(w, "ACTIVE", "\t", "NAME")
for _, project := range projects {
activeMark := " "
if project.Active {
activeMark = "*"
if plo.OutputFlag == "json" {
out, err := json.Marshal(projects)
if err != nil {
return err
}
fmt.Fprintln(w, activeMark, "\t", project.Name)
fmt.Println(string(out))
} else {
if len(projects.Items) == 0 {
return fmt.Errorf("You are not a member of any projects. You can request a project to be created using the `odo project create <project_name>` command")
}
w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent)
fmt.Fprintln(w, "ACTIVE", "\t", "NAME")
for _, project := range projects.Items {
activeMark := " "
if project.Status.Active {
activeMark = "*"
}
fmt.Fprintln(w, activeMark, "\t", project.Name)
}
w.Flush()
}
w.Flush()
return
}
@@ -80,5 +89,6 @@ func NewCmdProjectList(name, fullName string) *cobra.Command {
genericclioptions.GenericRun(o, cmd, args)
},
}
genericclioptions.AddOutputFlag(projectListCmd)
return projectListCmd
}

View File

@@ -26,7 +26,6 @@ var (
// URLListOptions encapsulates the options for the odo url list command
type URLListOptions struct {
outputFlag string
*genericclioptions.Context
}
@@ -43,7 +42,7 @@ func (o *URLListOptions) Complete(name string, cmd *cobra.Command, args []string
// Validate validates the UrlListOptions based on completed values
func (o *URLListOptions) Validate() (err error) {
return util.CheckOutputFlag(o.outputFlag)
return util.CheckOutputFlag(o.OutputFlag)
}
// Run contains the logic for the odo url list command
@@ -57,7 +56,7 @@ func (o *URLListOptions) Run() (err error) {
if len(urls.Items) == 0 {
return fmt.Errorf("no URLs found for component %v in application %v", o.Component(), o.Application)
} else {
if o.outputFlag == "json" {
if o.OutputFlag == "json" {
out, err := json.Marshal(urls)
if err != nil {
return err
@@ -96,7 +95,6 @@ func NewCmdURLList(name, fullName string) *cobra.Command {
genericclioptions.GenericRun(o, cmd, args)
},
}
urlListCmd.Flags().StringVarP(&o.outputFlag, "output", "o", "", "gives output in the form of json")
genericclioptions.AddOutputFlag(urlListCmd)
return urlListCmd
}

View File

@@ -172,7 +172,7 @@ var ProjectNameCompletionHandler = func(cmd *cobra.Command, args parsedArgs, con
return completions
}
for _, project := range projects {
for _, project := range projects.Items {
// we found the project name in the list which means
// that the project name has been already selected by the user so no need to suggest more
if args.commands[project.Name] {

View File

@@ -3,17 +3,12 @@ package project
import (
"github.com/pkg/errors"
"github.com/openshift/odo/pkg/application"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/occlient"
)
// ApplicationInfo holds information about one project
type ProjectInfo struct {
// Name of the project
Name string
// is this project active?
Active bool
}
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// GetCurrent return current project
func GetCurrent(client *occlient.Client) string {
@@ -54,24 +49,24 @@ func Delete(client *occlient.Client, projectName string) error {
return nil
}
func List(client *occlient.Client) ([]ProjectInfo, error) {
func List(client *occlient.Client) (ProjectList, error) {
currentProject := client.GetCurrentProjectName()
allProjects, err := client.GetProjectNames()
if err != nil {
return nil, errors.Wrap(err, "cannot get all the projects")
return ProjectList{}, errors.Wrap(err, "cannot get all the projects")
}
var projects []ProjectInfo
// Get apps from project
var projects []Project
for _, project := range allProjects {
isActive := false
if project == currentProject {
isActive = true
}
projects = append(projects, ProjectInfo{
Name: project,
Active: isActive,
})
apps, _ := application.ListInProject(client)
projects = append(projects, GetMachineReadableFormat(project, isActive, apps))
}
return projects, nil
return getMachineReadableFormatForList(projects), nil
}
// Checks whether a project with the given name exists or not
@@ -83,10 +78,42 @@ func Exists(client *occlient.Client, projectName string) (bool, error) {
if err != nil {
return false, errors.Wrap(err, "unable to get the project list")
}
for _, project := range projects {
for _, project := range projects.Items {
if project.Name == projectName {
return true, nil
}
}
return false, nil
}
func GetMachineReadableFormat(projectName string, isActive bool, apps []string) Project {
return Project{
TypeMeta: metav1.TypeMeta{
Kind: "Project",
APIVersion: "odo.openshift.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: projectName,
},
Spec: ProjectSpec{
Applications: apps,
},
Status: ProjectStatus{
Active: isActive,
},
}
}
// getMachineReadableFormatForList returns application list in machine readable format
func getMachineReadableFormatForList(projects []Project) ProjectList {
return ProjectList{
TypeMeta: metav1.TypeMeta{
Kind: "List",
APIVersion: "odo.openshift.io/v1alpha1",
},
ListMeta: metav1.ListMeta{},
Items: projects,
}
}

26
pkg/project/types.go Normal file
View File

@@ -0,0 +1,26 @@
package project
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type Project struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ProjectSpec `json:"spec,omitempty"`
Status ProjectStatus `json:"status,omitempty"`
}
type ProjectSpec struct {
Applications []string `json:"apps"`
}
type ProjectStatus struct {
Active bool `json:"active"`
}
type ProjectList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Project `json:"items"`
}

View File

@@ -45,6 +45,14 @@ var _ = Describe("odojsonoutput", func() {
areEqual, _ := compareJSON(desired, actual)
Expect(areEqual).To(BeTrue())
})
// odo project list -o json
It("should be able to list the projects", func() {
actual := runCmdShouldPass("odo project list -o json")
desired := `{"kind":"List","apiVersion":"odo.openshift.io/v1alpha1","metadata":{},"items":[{"kind":"Project","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"json-test","creationTimestamp":null},"spec":{"apps":["myapp"]},"status":{"active":true}},{"kind":"Project","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"myproject","creationTimestamp":null},"spec":{"apps":["myapp"]},"status":{"active":false}}]}`
areEqual, _ := compareJSON(desired, actual)
Expect(areEqual).To(BeTrue())
})
// odo app describe myapp -o json
It("should be able to describe app", func() {
desired := `{"kind":"app","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"myapp","namespace":"json-test","creationTimestamp":null},"spec":{"components":["nodejs"]},"status":{"active":false}}`