From 626d44ac7cb90bf978eeb289289961e182d4d0b3 Mon Sep 17 00:00:00 2001 From: Mario Constanti Date: Mon, 22 Jul 2024 14:45:10 +0200 Subject: [PATCH] feat: list all known profiles with additional info (#11) Signed-off-by: Mario Constanti --- cmd/kubectl-dpm.go | 3 ++ go.mod | 7 +++++ go.sum | 15 +++++++-- pkg/command/config.go | 1 + pkg/command/list.go | 70 +++++++++++++++++++++++++++++++++++++++++ pkg/profile/util.go | 16 ++++++++++ pkg/profile/validate.go | 5 +-- 7 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 pkg/command/list.go create mode 100644 pkg/profile/util.go diff --git a/cmd/kubectl-dpm.go b/cmd/kubectl-dpm.go index 4a9e3d7..c15c486 100644 --- a/cmd/kubectl-dpm.go +++ b/cmd/kubectl-dpm.go @@ -34,6 +34,9 @@ func main() { ) // validation sub command root.AddCommand(command.ValidateDebugProfileFile()) + // list sub command + root.AddCommand(command.List()) + // version sub command root.AddCommand(command.Version()) if err := root.Execute(); err != nil { diff --git a/go.mod b/go.mod index 531dac8..039445f 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,11 @@ require ( k8s.io/kubectl v0.30.2 ) +require ( + github.com/fatih/color v1.9.0 + github.com/rodaine/table v1.2.0 +) + require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect @@ -46,6 +51,8 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index f1250e7..d63151f 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -225,12 +226,16 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -309,6 +314,10 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA= +github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -330,8 +339,9 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -340,8 +350,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/pkg/command/config.go b/pkg/command/config.go index d89b9a3..1e4bcff 100644 --- a/pkg/command/config.go +++ b/pkg/command/config.go @@ -6,4 +6,5 @@ var ( flagProfileName string flagImage string flagDebug bool + flagVerboseList bool ) diff --git a/pkg/command/list.go b/pkg/command/list.go new file mode 100644 index 0000000..100a71a --- /dev/null +++ b/pkg/command/list.go @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT + +package command + +import ( + "fmt" + + "github.com/fatih/color" + "github.com/rodaine/table" + "github.com/spf13/cobra" + + "github.com/bavarianbidi/kubectl-dpm/pkg/config" + "github.com/bavarianbidi/kubectl-dpm/pkg/profile" +) + +func List() *cobra.Command { + listCmd := &cobra.Command{ + Use: "list", + Short: "list all profiles", + + RunE: func(c *cobra.Command, args []string) error { + if err := config.GenerateConfig(); err != nil { + return err + } + + if err := generateListOutput(); err != nil { + return err + } + + return nil + }, + } + + listCmd.Flags().BoolVarP(&flagVerboseList, "wide", "w", false, "show more information about profiles") + + return listCmd +} + +func generateListOutput() error { + headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc() + columnFmt := color.New(color.FgYellow).SprintfFunc() + + var tbl table.Table + tbl = table.New("Name", "Profile") + + if flagVerboseList { + tbl = table.New("Name", "Profile", "Image", "Namespace", "MatchLabels") + } + tbl. + WithHeaderFormatter(headerFmt). + WithFirstColumnFormatter(columnFmt) + + for _, p := range profile.Config.Profiles { + var matchLabels string + for label, value := range p.MatchLabels { + matchLabels += fmt.Sprintf("%s=%s, ", label, value) + } + tbl.AddRow( + p.ProfileName, // Name + p.CustomProfileFile, // Profile + p.Image, // Image + p.Namespace, // Namespace + matchLabels, // MatchLabels + ) + } + + tbl.Print() + + return nil +} diff --git a/pkg/profile/util.go b/pkg/profile/util.go new file mode 100644 index 0000000..de57b38 --- /dev/null +++ b/pkg/profile/util.go @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT + +package profile + +import ( + "cmp" + "slices" + "strings" +) + +func SortProfiles() { + // sort profiles by name + slices.SortFunc(Config.Profiles, func(a, b Profile) int { + return cmp.Compare(strings.ToLower(a.ProfileName), strings.ToLower(b.ProfileName)) + }) +} diff --git a/pkg/profile/validate.go b/pkg/profile/validate.go index be20c65..0831f42 100644 --- a/pkg/profile/validate.go +++ b/pkg/profile/validate.go @@ -3,7 +3,6 @@ package profile import ( - "cmp" "encoding/json" "fmt" "log" @@ -54,9 +53,7 @@ func ValidateKubectlPath() error { func ValidateAllProfiles() error { // sort profiles by name - slices.SortFunc(Config.Profiles, func(a, b Profile) int { - return cmp.Compare(strings.ToLower(a.ProfileName), strings.ToLower(b.ProfileName)) - }) + SortProfiles() compactProfiles := slices.CompactFunc(Config.Profiles, func(a, b Profile) bool { if strings.EqualFold(a.ProfileName, b.ProfileName) {