diff --git a/README.md b/README.md index 8ade2d9..9083866 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,11 @@ You can setup MFA also using the configuration sub command, only TOTP is support # Server Verification To enable Server Verification you need to run `passbolt verify` once, after that the server will always be verified if the same config is used +# Scripting +For Scripting we have a -j or --json flag to convert the Output for the create, get and list commands to JSON for easier Parsing in Scripts. + +Note: The JSON Output does not cover Error Messages, you can detect Errors by checking if the Exitcode is not 0 + # Documentation Usage for all Subcommands is [here](https://github.com/passbolt/go-passbolt-cli/wiki/go-passbolt-cli). And is also available via `man passbolt` diff --git a/cmd/create.go b/cmd/create.go index c758b86..967824a 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -18,6 +18,7 @@ var createCmd = &cobra.Command{ func init() { rootCmd.AddCommand(createCmd) + createCmd.PersistentFlags().BoolP("json", "j", false, "Output JSON") createCmd.AddCommand(resource.ResourceCreateCmd) createCmd.AddCommand(folder.FolderCreateCmd) createCmd.AddCommand(group.GroupCreateCmd) diff --git a/cmd/get.go b/cmd/get.go index 24fbc33..ac8bdce 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -18,6 +18,7 @@ var getCmd = &cobra.Command{ func init() { rootCmd.AddCommand(getCmd) + getCmd.PersistentFlags().BoolP("json", "j", false, "Output JSON") getCmd.AddCommand(resource.ResourceGetCmd) getCmd.AddCommand(folder.FolderGetCmd) getCmd.AddCommand(group.GroupGetCmd) diff --git a/cmd/list.go b/cmd/list.go index f4672aa..90124b2 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -18,6 +18,7 @@ var listCmd = &cobra.Command{ func init() { rootCmd.AddCommand(listCmd) + listCmd.PersistentFlags().BoolP("json", "j", false, "Output JSON") listCmd.AddCommand(resource.ResourceListCmd) listCmd.AddCommand(folder.FolderListCmd) listCmd.AddCommand(group.GroupListCmd) diff --git a/folder/create.go b/folder/create.go index 5b18b0c..8e9c464 100644 --- a/folder/create.go +++ b/folder/create.go @@ -2,6 +2,7 @@ package folder import ( "context" + "encoding/json" "fmt" "github.com/passbolt/go-passbolt-cli/util" @@ -33,6 +34,10 @@ func FolderCreate(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -53,6 +58,18 @@ func FolderCreate(cmd *cobra.Command, args []string) error { return fmt.Errorf("Creating Folder: %w", err) } - fmt.Printf("FolderID: %v\n", id) + if jsonOutput { + jsonId, err := json.MarshalIndent( + map[string]string{"id": id}, + "", + " ", + ) + if err != nil { + return fmt.Errorf("Marshalling Json: %w", err) + } + fmt.Println(string(jsonId)) + } else { + fmt.Printf("FolderID: %v\n", id) + } return nil } diff --git a/folder/get.go b/folder/get.go index edf5e72..d6350c7 100644 --- a/folder/get.go +++ b/folder/get.go @@ -2,11 +2,11 @@ package folder import ( "context" + "encoding/json" "fmt" "github.com/alessio/shellescape" "github.com/passbolt/go-passbolt-cli/util" - "github.com/passbolt/go-passbolt/helper" "github.com/spf13/cobra" ) @@ -29,6 +29,10 @@ func FolderGet(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -39,15 +43,22 @@ func FolderGet(cmd *cobra.Command, args []string) error { defer client.Logout(context.TODO()) cmd.SilenceUsage = true - folderParentID, name, err := helper.GetFolder( - ctx, - client, - id, - ) + folder, err := client.GetFolder(ctx, id, nil) if err != nil { return fmt.Errorf("Getting Folder: %w", err) } - fmt.Printf("FolderParentID: %v\n", folderParentID) - fmt.Printf("Name: %v\n", shellescape.StripUnsafe(name)) + if jsonOutput { + jsonGroup, err := json.MarshalIndent(FolderJsonOutput{ + FolderParentID: &folder.FolderParentID, + Name: &folder.Name, + }, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonGroup)) + } else { + fmt.Printf("FolderParentID: %v\n", folder.FolderParentID) + fmt.Printf("Name: %v\n", shellescape.StripUnsafe(folder.Name)) + } return nil } diff --git a/folder/json.go b/folder/json.go new file mode 100644 index 0000000..c74b9d5 --- /dev/null +++ b/folder/json.go @@ -0,0 +1,11 @@ +package folder + +import "time" + +type FolderJsonOutput struct { + ID *string `json:"id,omitempty"` + FolderParentID *string `json:"folder_parent_id,omitempty"` + Name *string `json:"name,omitempty"` + CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"` + ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"` +} diff --git a/folder/list.go b/folder/list.go index 796c3cf..be92a52 100644 --- a/folder/list.go +++ b/folder/list.go @@ -2,6 +2,7 @@ package folder import ( "context" + "encoding/json" "fmt" "strings" "time" @@ -46,6 +47,10 @@ func FolderList(cmd *cobra.Command, args []string) error { if len(columns) == 0 { return fmt.Errorf("You need to Specify atleast one column to return") } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() cmd.SilenceUsage = true @@ -64,30 +69,48 @@ func FolderList(cmd *cobra.Command, args []string) error { return fmt.Errorf("Listing Folder: %w", err) } - data := pterm.TableData{columns} - - for _, folder := range folders { - entry := make([]string, len(columns)) - for i := range columns { - switch strings.ToLower(columns[i]) { - case "id": - entry[i] = folder.ID - case "folderparentid": - entry[i] = folder.FolderParentID - case "name": - entry[i] = shellescape.StripUnsafe(folder.Name) - case "createdtimestamp": - entry[i] = folder.Created.Format(time.RFC3339) - case "modifiedtimestamp": - entry[i] = folder.Modified.Format(time.RFC3339) - default: - cmd.SilenceUsage = false - return fmt.Errorf("Unknown Column: %v", columns[i]) - } + if jsonOutput { + outputFolders := []FolderJsonOutput{} + for i := range folders { + outputFolders = append(outputFolders, FolderJsonOutput{ + ID: &folders[i].ID, + FolderParentID: &folders[i].FolderParentID, + Name: &folders[i].Name, + CreatedTimestamp: &folders[i].Created.Time, + ModifiedTimestamp: &folders[i].Modified.Time, + }) } - data = append(data, entry) - } + jsonFolders, err := json.MarshalIndent(outputFolders, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonFolders)) + } else { + data := pterm.TableData{columns} - pterm.DefaultTable.WithHasHeader().WithData(data).Render() + for _, folder := range folders { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "id": + entry[i] = folder.ID + case "folderparentid": + entry[i] = folder.FolderParentID + case "name": + entry[i] = shellescape.StripUnsafe(folder.Name) + case "createdtimestamp": + entry[i] = folder.Created.Format(time.RFC3339) + case "modifiedtimestamp": + entry[i] = folder.Modified.Format(time.RFC3339) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } return nil } diff --git a/group/create.go b/group/create.go index 4c1b8ae..6e8caa2 100644 --- a/group/create.go +++ b/group/create.go @@ -2,6 +2,7 @@ package group import ( "context" + "encoding/json" "fmt" "github.com/passbolt/go-passbolt-cli/util" @@ -40,6 +41,10 @@ func GroupCreate(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ops := []helper.GroupMembershipOperation{} for _, user := range users { @@ -74,6 +79,18 @@ func GroupCreate(cmd *cobra.Command, args []string) error { return fmt.Errorf("Creating Group: %w", err) } - fmt.Printf("GroupID: %v\n", id) + if jsonOutput { + jsonId, err := json.MarshalIndent( + map[string]string{"id": id}, + "", + " ", + ) + if err != nil { + return fmt.Errorf("Marshalling Json: %w", err) + } + fmt.Println(string(jsonId)) + } else { + fmt.Printf("GroupID: %v\n", id) + } return nil } diff --git a/group/get.go b/group/get.go index f7dcdeb..db2d9b0 100644 --- a/group/get.go +++ b/group/get.go @@ -2,6 +2,7 @@ package group import ( "context" + "encoding/json" "fmt" "strings" @@ -37,6 +38,10 @@ func GroupGet(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -55,34 +60,58 @@ func GroupGet(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("Getting Group: %w", err) } - fmt.Printf("Name: %v\n", name) - // Print Memberships - if len(columns) != 0 { - data := pterm.TableData{columns} - for _, membership := range memberships { - entry := make([]string, len(columns)) - for i := range columns { - switch strings.ToLower(columns[i]) { - case "userid": - entry[i] = membership.UserID - case "isgroupmanager": - entry[i] = fmt.Sprint(membership.IsGroupManager) - case "username": - entry[i] = shellescape.StripUnsafe(membership.Username) - case "userfirstname": - entry[i] = shellescape.StripUnsafe(membership.UserFirstName) - case "userlastname": - entry[i] = shellescape.StripUnsafe(membership.UserLastName) - default: - cmd.SilenceUsage = false - return fmt.Errorf("Unknown Column: %v", columns[i]) - } - } - data = append(data, entry) + if jsonOutput { + groupUserMemberships := []GroupUserMembershipJsonOutput{} + for i := range memberships { + groupUserMemberships = append(groupUserMemberships, GroupUserMembershipJsonOutput{ + ID: &memberships[i].UserID, + Username: &memberships[i].Username, + FirstName: &memberships[i].UserFirstName, + LastName: &memberships[i].UserLastName, + IsGroupManager: &memberships[i].IsGroupManager, + }) } - pterm.DefaultTable.WithHasHeader().WithData(data).Render() + jsonGroup, err := json.MarshalIndent(GroupJsonOutput{ + Name: &name, + Users: groupUserMemberships, + }, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonGroup)) + + } else { + fmt.Printf("Name: %v\n", name) + // Print Memberships + if len(columns) != 0 { + data := pterm.TableData{columns} + + for _, membership := range memberships { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "userid": + entry[i] = membership.UserID + case "isgroupmanager": + entry[i] = fmt.Sprint(membership.IsGroupManager) + case "username": + entry[i] = shellescape.StripUnsafe(membership.Username) + case "userfirstname": + entry[i] = shellescape.StripUnsafe(membership.UserFirstName) + case "userlastname": + entry[i] = shellescape.StripUnsafe(membership.UserLastName) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } } return nil } diff --git a/group/json.go b/group/json.go new file mode 100644 index 0000000..84d6b11 --- /dev/null +++ b/group/json.go @@ -0,0 +1,19 @@ +package group + +import "time" + +type GroupJsonOutput struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Users []GroupUserMembershipJsonOutput `json:"users,omitempty"` + CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"` + ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"` +} + +type GroupUserMembershipJsonOutput struct { + ID *string `json:"id,omitempty"` + Username *string `json:"username,omitempty"` + FirstName *string `json:"first_name,omitempty"` + LastName *string `json:"last_name,omitempty"` + IsGroupManager *bool `json:"is_group_manager,omitempty"` +} diff --git a/group/list.go b/group/list.go index 74cddfc..6faa9c5 100644 --- a/group/list.go +++ b/group/list.go @@ -2,6 +2,7 @@ package group import ( "context" + "encoding/json" "fmt" "strings" "time" @@ -46,6 +47,10 @@ func GroupList(cmd *cobra.Command, args []string) error { if len(columns) == 0 { return fmt.Errorf("You need to specify atleast one column to return") } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -64,28 +69,45 @@ func GroupList(cmd *cobra.Command, args []string) error { return fmt.Errorf("Listing Group: %w", err) } - data := pterm.TableData{columns} - - for _, group := range groups { - entry := make([]string, len(columns)) - for i := range columns { - switch strings.ToLower(columns[i]) { - case "id": - entry[i] = group.ID - case "name": - entry[i] = shellescape.StripUnsafe(group.Name) - case "createdtimestamp": - entry[i] = group.Created.Format(time.RFC3339) - case "modifiedtimestamp": - entry[i] = group.Modified.Format(time.RFC3339) - default: - cmd.SilenceUsage = false - return fmt.Errorf("Unknown Column: %v", columns[i]) - } + if jsonOutput { + outputGroups := []GroupJsonOutput{} + for i := range groups { + outputGroups = append(outputGroups, GroupJsonOutput{ + ID: &groups[i].ID, + Name: &groups[i].Name, + CreatedTimestamp: &groups[i].Created.Time, + ModifiedTimestamp: &groups[i].Modified.Time, + }) } - data = append(data, entry) - } + jsonGroups, err := json.MarshalIndent(outputGroups, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonGroups)) + } else { + data := pterm.TableData{columns} - pterm.DefaultTable.WithHasHeader().WithData(data).Render() + for _, group := range groups { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "id": + entry[i] = group.ID + case "name": + entry[i] = shellescape.StripUnsafe(group.Name) + case "createdtimestamp": + entry[i] = group.Created.Format(time.RFC3339) + case "modifiedtimestamp": + entry[i] = group.Modified.Format(time.RFC3339) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } return nil } diff --git a/resource/create.go b/resource/create.go index 799c0d5..a0866ca 100644 --- a/resource/create.go +++ b/resource/create.go @@ -2,6 +2,7 @@ package resource import ( "context" + "encoding/json" "fmt" "github.com/passbolt/go-passbolt-cli/util" @@ -54,6 +55,10 @@ func ResourceCreate(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -78,6 +83,18 @@ func ResourceCreate(cmd *cobra.Command, args []string) error { return fmt.Errorf("Creating Resource: %w", err) } - fmt.Printf("ResourceID: %v\n", id) + if jsonOutput { + jsonId, err := json.MarshalIndent( + map[string]string{"id": id}, + "", + " ", + ) + if err != nil { + return fmt.Errorf("Marshalling Json: %w", err) + } + fmt.Println(string(jsonId)) + } else { + fmt.Printf("ResourceID: %v\n", id) + } return nil } diff --git a/resource/get.go b/resource/get.go index 699c944..9147280 100644 --- a/resource/get.go +++ b/resource/get.go @@ -2,6 +2,7 @@ package resource import ( "context" + "encoding/json" "fmt" "github.com/alessio/shellescape" @@ -29,6 +30,10 @@ func ResourceGet(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -47,11 +52,27 @@ func ResourceGet(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("Getting Resource: %w", err) } - fmt.Printf("FolderParentID: %v\n", folderParentID) - fmt.Printf("Name: %v\n", shellescape.StripUnsafe(name)) - fmt.Printf("Username: %v\n", shellescape.StripUnsafe(username)) - fmt.Printf("URI: %v\n", shellescape.StripUnsafe(uri)) - fmt.Printf("Password: %v\n", shellescape.StripUnsafe(password)) - fmt.Printf("Description: %v\n", shellescape.StripUnsafe(description)) + + if jsonOutput { + jsonResource, err := json.MarshalIndent(ResourceJsonOutput{ + FolderParentID: &folderParentID, + Name: &name, + Username: &username, + URI: &uri, + Password: &password, + Description: &description, + }, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonResource)) + } else { + fmt.Printf("FolderParentID: %v\n", folderParentID) + fmt.Printf("Name: %v\n", shellescape.StripUnsafe(name)) + fmt.Printf("Username: %v\n", shellescape.StripUnsafe(username)) + fmt.Printf("URI: %v\n", shellescape.StripUnsafe(uri)) + fmt.Printf("Password: %v\n", shellescape.StripUnsafe(password)) + fmt.Printf("Description: %v\n", shellescape.StripUnsafe(description)) + } return nil } diff --git a/resource/json.go b/resource/json.go new file mode 100644 index 0000000..950a109 --- /dev/null +++ b/resource/json.go @@ -0,0 +1,15 @@ +package resource + +import "time" + +type ResourceJsonOutput struct { + ID *string `json:"id,omitempty"` + FolderParentID *string `json:"folder_parent_id,omitempty"` + Name *string `json:"name,omitempty"` + Username *string `json:"username,omitempty"` + URI *string `json:"uri,omitempty"` + Password *string `json:"password,omitempty"` + Description *string `json:"description,omitempty"` + CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"` + ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"` +} diff --git a/resource/list.go b/resource/list.go index 2cd2626..ad1d9ac 100644 --- a/resource/list.go +++ b/resource/list.go @@ -2,6 +2,7 @@ package resource import ( "context" + "encoding/json" "fmt" "strings" "time" @@ -58,6 +59,10 @@ func ResourceList(cmd *cobra.Command, args []string) error { if len(columns) == 0 { return fmt.Errorf("You need to specify atleast one column to return") } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -78,46 +83,72 @@ func ResourceList(cmd *cobra.Command, args []string) error { return fmt.Errorf("Listing Resource: %w", err) } - data := pterm.TableData{columns} - - for _, resource := range resources { - entry := make([]string, len(columns)) - for i := range columns { - switch strings.ToLower(columns[i]) { - case "id": - entry[i] = resource.ID - case "folderparentid": - entry[i] = resource.FolderParentID - case "name": - entry[i] = shellescape.StripUnsafe(resource.Name) - case "username": - entry[i] = shellescape.StripUnsafe(resource.Username) - case "uri": - entry[i] = shellescape.StripUnsafe(resource.URI) - case "password": - _, _, _, _, pass, _, err := helper.GetResource(ctx, client, resource.ID) - if err != nil { - return fmt.Errorf("Get Resource %w", err) - } - entry[i] = shellescape.StripUnsafe(pass) - case "description": - _, _, _, _, _, desc, err := helper.GetResource(ctx, client, resource.ID) - if err != nil { - return fmt.Errorf("Get Resource %w", err) - } - entry[i] = shellescape.StripUnsafe(desc) - case "createdtimestamp": - entry[i] = resource.Created.Format(time.RFC3339) - case "modifiedtimestamp": - entry[i] = resource.Modified.Format(time.RFC3339) - default: - cmd.SilenceUsage = false - return fmt.Errorf("Unknown Column: %v", columns[i]) + if jsonOutput { + outputResources := []ResourceJsonOutput{} + for i := range resources { + _, _, _, _, pass, desc, err := helper.GetResource(ctx, client, resources[i].ID) + if err != nil { + return fmt.Errorf("Get Resource %w", err) } + outputResources = append(outputResources, ResourceJsonOutput{ + ID: &resources[i].ID, + FolderParentID: &resources[i].FolderParentID, + Name: &resources[i].Name, + Username: &resources[i].Username, + URI: &resources[i].URI, + Password: &pass, + Description: &desc, + CreatedTimestamp: &resources[i].Created.Time, + ModifiedTimestamp: &resources[i].Modified.Time, + }) } - data = append(data, entry) - } + jsonResources, err := json.MarshalIndent(outputResources, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonResources)) + } else { + data := pterm.TableData{columns} - pterm.DefaultTable.WithHasHeader().WithData(data).Render() + for _, resource := range resources { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "id": + entry[i] = resource.ID + case "folderparentid": + entry[i] = resource.FolderParentID + case "name": + entry[i] = shellescape.StripUnsafe(resource.Name) + case "username": + entry[i] = shellescape.StripUnsafe(resource.Username) + case "uri": + entry[i] = shellescape.StripUnsafe(resource.URI) + case "password": + _, _, _, _, pass, _, err := helper.GetResource(ctx, client, resource.ID) + if err != nil { + return fmt.Errorf("Get Resource %w", err) + } + entry[i] = shellescape.StripUnsafe(pass) + case "description": + _, _, _, _, _, desc, err := helper.GetResource(ctx, client, resource.ID) + if err != nil { + return fmt.Errorf("Get Resource %w", err) + } + entry[i] = shellescape.StripUnsafe(desc) + case "createdtimestamp": + entry[i] = resource.Created.Format(time.RFC3339) + case "modifiedtimestamp": + entry[i] = resource.Modified.Format(time.RFC3339) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } return nil } diff --git a/user/create.go b/user/create.go index 4c1b937..34465f6 100644 --- a/user/create.go +++ b/user/create.go @@ -2,6 +2,7 @@ package user import ( "context" + "encoding/json" "fmt" "github.com/passbolt/go-passbolt-cli/util" @@ -45,6 +46,11 @@ func UserCreate(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } + ctx := util.GetContext() client, err := util.GetClient(ctx) @@ -66,6 +72,18 @@ func UserCreate(cmd *cobra.Command, args []string) error { return fmt.Errorf("Creating User: %w", err) } - fmt.Printf("UserID: %v\n", id) + if jsonOutput { + jsonId, err := json.MarshalIndent( + map[string]string{"id": id}, + "", + " ", + ) + if err != nil { + return fmt.Errorf("Marshalling Json: %w", err) + } + fmt.Println(string(jsonId)) + } else { + fmt.Printf("UserID: %v\n", id) + } return nil } diff --git a/user/get.go b/user/get.go index 62029c8..d75522b 100644 --- a/user/get.go +++ b/user/get.go @@ -2,6 +2,7 @@ package user import ( "context" + "encoding/json" "fmt" "github.com/alessio/shellescape" @@ -29,6 +30,10 @@ func UserGet(cmd *cobra.Command, args []string) error { if err != nil { return err } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -47,10 +52,22 @@ func UserGet(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("Getting User: %w", err) } - fmt.Printf("Username: %v\n", shellescape.StripUnsafe(username)) - fmt.Printf("FirstName: %v\n", shellescape.StripUnsafe(firstname)) - fmt.Printf("LastName: %v\n", shellescape.StripUnsafe(lastname)) - fmt.Printf("Role: %v\n", shellescape.StripUnsafe(role)) - + if jsonOutput { + jsonUser, err := json.MarshalIndent(UserJsonOutput{ + Username: &username, + FirstName: &firstname, + LastName: &lastname, + Role: &role, + }, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonUser)) + } else { + fmt.Printf("Username: %v\n", shellescape.StripUnsafe(username)) + fmt.Printf("FirstName: %v\n", shellescape.StripUnsafe(firstname)) + fmt.Printf("LastName: %v\n", shellescape.StripUnsafe(lastname)) + fmt.Printf("Role: %v\n", shellescape.StripUnsafe(role)) + } return nil } diff --git a/user/json.go b/user/json.go new file mode 100644 index 0000000..9b04988 --- /dev/null +++ b/user/json.go @@ -0,0 +1,13 @@ +package user + +import "time" + +type UserJsonOutput struct { + ID *string `json:"id,omitempty"` + Username *string `json:"username,omitempty"` + FirstName *string `json:"first_name,omitempty"` + LastName *string `json:"last_name,omitempty"` + Role *string `json:"role,omitempty"` + CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"` + ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"` +} diff --git a/user/list.go b/user/list.go index aa55d28..32ff273 100644 --- a/user/list.go +++ b/user/list.go @@ -2,6 +2,7 @@ package user import ( "context" + "encoding/json" "fmt" "strings" "time" @@ -57,6 +58,10 @@ func UserList(cmd *cobra.Command, args []string) error { if len(columns) == 0 { return fmt.Errorf("You need to specify atleast one column to return") } + jsonOutput, err := cmd.Flags().GetBool("json") + if err != nil { + return err + } ctx := util.GetContext() @@ -77,34 +82,54 @@ func UserList(cmd *cobra.Command, args []string) error { return fmt.Errorf("Listing User: %w", err) } - data := pterm.TableData{columns} - - for _, user := range users { - entry := make([]string, len(columns)) - for i := range columns { - switch strings.ToLower(columns[i]) { - case "id": - entry[i] = user.ID - case "username": - entry[i] = shellescape.StripUnsafe(user.Username) - case "firstname": - entry[i] = shellescape.StripUnsafe(user.Profile.FirstName) - case "lastname": - entry[i] = shellescape.StripUnsafe(user.Profile.LastName) - case "role": - entry[i] = shellescape.StripUnsafe(user.Role.Name) - case "createdtimestamp": - entry[i] = user.Created.Format(time.RFC3339) - case "modifiedtimestamp": - entry[i] = user.Modified.Format(time.RFC3339) - default: - cmd.SilenceUsage = false - return fmt.Errorf("Unknown Column: %v", columns[i]) - } + if jsonOutput { + outputUsers := []UserJsonOutput{} + for i := range users { + outputUsers = append(outputUsers, UserJsonOutput{ + ID: &users[i].ID, + Username: &users[i].Username, + FirstName: &users[i].Profile.FirstName, + LastName: &users[i].Profile.LastName, + Role: &users[i].Role.Name, + CreatedTimestamp: &users[i].Created.Time, + ModifiedTimestamp: &users[i].Modified.Time, + }) } - data = append(data, entry) - } + jsonUsers, err := json.MarshalIndent(outputUsers, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonUsers)) + } else { + data := pterm.TableData{columns} - pterm.DefaultTable.WithHasHeader().WithData(data).Render() + for _, user := range users { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "id": + entry[i] = user.ID + case "username": + entry[i] = shellescape.StripUnsafe(user.Username) + case "firstname": + entry[i] = shellescape.StripUnsafe(user.Profile.FirstName) + case "lastname": + entry[i] = shellescape.StripUnsafe(user.Profile.LastName) + case "role": + entry[i] = shellescape.StripUnsafe(user.Role.Name) + case "createdtimestamp": + entry[i] = user.Created.Format(time.RFC3339) + case "modifiedtimestamp": + entry[i] = user.Modified.Format(time.RFC3339) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } return nil }