Skip to content

Commit ab81c29

Browse files
authored
Merge pull request #1101 from HassanAlsamahi/remote-cmd-add-column-flag
incus/remote/list: Add column flag
2 parents a819663 + e20d2df commit ab81c29

File tree

12 files changed

+1475
-1108
lines changed

12 files changed

+1475
-1108
lines changed

cmd/incus/remote.go

+136-42
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ type cmdRemote struct {
3131
global *cmdGlobal
3232
}
3333

34+
type remoteColumn struct {
35+
Name string
36+
Data func(string, config.Remote) string
37+
}
38+
3439
// Command returns a cobra.Command for use with (*cobra.Command).AddCommand.
3540
func (c *cmdRemote) Command() *cobra.Command {
3641
cmd := &cobra.Command{}
@@ -706,7 +711,8 @@ type cmdRemoteList struct {
706711
global *cmdGlobal
707712
remote *cmdRemote
708713

709-
flagFormat string
714+
flagFormat string
715+
flagColumns string
710716
}
711717

712718
// Command returns a cobra.Command for use with (*cobra.Command).AddCommand.
@@ -716,14 +722,130 @@ func (c *cmdRemoteList) Command() *cobra.Command {
716722
cmd.Aliases = []string{"ls"}
717723
cmd.Short = i18n.G("List the available remotes")
718724
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
719-
`List the available remotes`))
725+
`List the available remotes
726+
727+
Default column layout: nupaPsg
728+
729+
== Columns ==
730+
The -c option takes a comma separated list of arguments that control
731+
which instance attributes to output when displaying in table or csv
732+
format.
733+
734+
Column arguments are either pre-defined shorthand chars (see below),
735+
or (extended) config keys.
736+
737+
Commas between consecutive shorthand chars are optional.
738+
739+
Pre-defined column shorthand chars:
740+
n - Name
741+
u - URL
742+
p - Protocol
743+
a - Auth Type
744+
P - Public
745+
s - Static
746+
g - Global`))
720747

721748
cmd.RunE = c.Run
722749
cmd.Flags().StringVarP(&c.flagFormat, "format", "f", "table", i18n.G("Format (csv|json|table|yaml|compact)")+"``")
750+
cmd.Flags().StringVarP(&c.flagColumns, "columns", "c", defaultRemoteColumns, i18n.G("Columns")+"``")
723751

724752
return cmd
725753
}
726754

755+
const defaultRemoteColumns = "nupaPsg"
756+
757+
func (c *cmdRemoteList) parseColumns() ([]remoteColumn, error) {
758+
columnsShorthandMap := map[rune]remoteColumn{
759+
'n': {i18n.G("NAME"), c.remoteNameColumnData},
760+
'u': {i18n.G("URL"), c.addrColumnData},
761+
'p': {i18n.G("PROTOCOL"), c.protocolColumnData},
762+
'a': {i18n.G("AUTH TYPE"), c.authTypeColumnData},
763+
'P': {i18n.G("PUBLIC"), c.publicColumnData},
764+
's': {i18n.G("STATIC"), c.staticColumnData},
765+
'g': {i18n.G("GLOBAL"), c.globalColumnData},
766+
}
767+
768+
columnList := strings.Split(c.flagColumns, ",")
769+
columns := []remoteColumn{}
770+
771+
for _, columnEntry := range columnList {
772+
if columnEntry == "" {
773+
return nil, fmt.Errorf(i18n.G("Empty column entry (redundant, leading or trailing command) in '%s'"), c.flagColumns)
774+
}
775+
776+
for _, columnRune := range columnEntry {
777+
column, ok := columnsShorthandMap[columnRune]
778+
if !ok {
779+
return nil, fmt.Errorf(i18n.G("Unknown column shorthand char '%c' in '%s'"), columnRune, columnEntry)
780+
}
781+
782+
columns = append(columns, column)
783+
}
784+
}
785+
786+
return columns, nil
787+
}
788+
789+
func (c *cmdRemoteList) remoteNameColumnData(name string, rc config.Remote) string {
790+
conf := c.global.conf
791+
792+
strName := name
793+
if name == conf.DefaultRemote {
794+
strName = fmt.Sprintf("%s (%s)", name, i18n.G("current"))
795+
}
796+
797+
return strName
798+
}
799+
800+
func (c *cmdRemoteList) addrColumnData(name string, rc config.Remote) string {
801+
return rc.Addr
802+
}
803+
804+
func (c *cmdRemoteList) protocolColumnData(name string, rc config.Remote) string {
805+
return rc.Protocol
806+
}
807+
808+
func (c *cmdRemoteList) authTypeColumnData(name string, rc config.Remote) string {
809+
if rc.AuthType == "" {
810+
if strings.HasPrefix(rc.Addr, "unix:") {
811+
rc.AuthType = "file access"
812+
} else if rc.Protocol != "incus" {
813+
rc.AuthType = "none"
814+
} else {
815+
rc.AuthType = api.AuthenticationMethodTLS
816+
}
817+
}
818+
819+
return rc.AuthType
820+
}
821+
822+
func (c *cmdRemoteList) publicColumnData(name string, rc config.Remote) string {
823+
strPublic := i18n.G("NO")
824+
if rc.Public {
825+
strPublic = i18n.G("YES")
826+
}
827+
828+
return strPublic
829+
}
830+
831+
func (c *cmdRemoteList) staticColumnData(name string, rc config.Remote) string {
832+
strStatic := i18n.G("NO")
833+
if rc.Static {
834+
strStatic = i18n.G("YES")
835+
}
836+
837+
return strStatic
838+
}
839+
840+
func (c *cmdRemoteList) globalColumnData(name string, rc config.Remote) string {
841+
strGlobal := i18n.G("NO")
842+
if rc.Global {
843+
strGlobal = i18n.G("YES")
844+
}
845+
846+
return strGlobal
847+
}
848+
727849
// Run is used in the RunE field of the cobra.Command returned by Command.
728850
func (c *cmdRemoteList) Run(cmd *cobra.Command, args []string) error {
729851
conf := c.global.conf
@@ -734,56 +856,28 @@ func (c *cmdRemoteList) Run(cmd *cobra.Command, args []string) error {
734856
return err
735857
}
736858

859+
columns, err := c.parseColumns()
860+
if err != nil {
861+
return err
862+
}
863+
737864
// List the remotes
738865
data := [][]string{}
739866
for name, rc := range conf.Remotes {
740-
strPublic := i18n.G("NO")
741-
if rc.Public {
742-
strPublic = i18n.G("YES")
743-
}
744-
745-
strStatic := i18n.G("NO")
746-
if rc.Static {
747-
strStatic = i18n.G("YES")
748-
}
749-
750-
strGlobal := i18n.G("NO")
751-
if rc.Global {
752-
strGlobal = i18n.G("YES")
753-
}
754-
755-
if rc.Protocol == "" {
756-
rc.Protocol = "incus"
757-
}
758-
759-
if rc.AuthType == "" {
760-
if strings.HasPrefix(rc.Addr, "unix:") {
761-
rc.AuthType = "file access"
762-
} else if rc.Protocol != "incus" {
763-
rc.AuthType = "none"
764-
} else {
765-
rc.AuthType = api.AuthenticationMethodTLS
766-
}
767-
}
768867

769-
strName := name
770-
if name == conf.DefaultRemote {
771-
strName = fmt.Sprintf("%s (%s)", name, i18n.G("current"))
868+
line := []string{}
869+
for _, column := range columns {
870+
line = append(line, column.Data(name, rc))
772871
}
773872

774-
data = append(data, []string{strName, rc.Addr, rc.Protocol, rc.AuthType, strPublic, strStatic, strGlobal})
873+
data = append(data, line)
775874
}
776875

777876
sort.Sort(cli.SortColumnsNaturally(data))
778877

779-
header := []string{
780-
i18n.G("NAME"),
781-
i18n.G("URL"),
782-
i18n.G("PROTOCOL"),
783-
i18n.G("AUTH TYPE"),
784-
i18n.G("PUBLIC"),
785-
i18n.G("STATIC"),
786-
i18n.G("GLOBAL"),
878+
header := []string{}
879+
for _, column := range columns {
880+
header = append(header, column.Name)
787881
}
788882

789883
return cli.RenderTable(c.flagFormat, header, data, conf.Remotes)

0 commit comments

Comments
 (0)