Skip to content

Commit dd266c7

Browse files
authored
Merge pull request #5554 from woodcockjosh/json-output-for-profile-lists
Add json output for profile list
2 parents ce2b0a3 + d758672 commit dd266c7

File tree

2 files changed

+119
-28
lines changed

2 files changed

+119
-28
lines changed

Diff for: cmd/minikube/cmd/config/profile_list.go

+82-27
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ limitations under the License.
1717
package config
1818

1919
import (
20+
"encoding/json"
2021
"fmt"
2122
"os"
2223
"strconv"
24+
"strings"
2325

2426
"k8s.io/minikube/pkg/minikube/config"
2527
"k8s.io/minikube/pkg/minikube/exit"
@@ -29,48 +31,101 @@ import (
2931
"github.com/spf13/cobra"
3032
)
3133

34+
var (
35+
output string
36+
)
37+
3238
var profileListCmd = &cobra.Command{
3339
Use: "list",
3440
Short: "Lists all minikube profiles.",
3541
Long: "Lists all valid minikube profiles and detects all possible invalid profiles.",
3642
Run: func(cmd *cobra.Command, args []string) {
3743

38-
var validData [][]string
44+
switch strings.ToLower(output) {
45+
case "json":
46+
printProfilesJSON()
47+
case "table":
48+
printProfilesTable()
49+
default:
50+
exit.WithCodeT(exit.BadUsage, fmt.Sprintf("invalid output format: %s. Valid values: 'table', 'json'", output))
51+
}
52+
53+
},
54+
}
55+
56+
var printProfilesTable = func() {
3957

40-
table := tablewriter.NewWriter(os.Stdout)
41-
table.SetHeader([]string{"Profile", "VM Driver", "NodeIP", "Node Port", "Kubernetes Version"})
42-
table.SetAutoFormatHeaders(false)
43-
table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
44-
table.SetCenterSeparator("|")
45-
validProfiles, invalidProfiles, err := config.ListProfiles()
58+
var validData [][]string
4659

47-
if len(validProfiles) == 0 || err != nil {
48-
exit.UsageT("No minikube profile was found. You can create one using `minikube start`.")
49-
}
50-
for _, p := range validProfiles {
51-
validData = append(validData, []string{p.Name, p.Config.MachineConfig.VMDriver, p.Config.KubernetesConfig.NodeIP, strconv.Itoa(p.Config.KubernetesConfig.NodePort), p.Config.KubernetesConfig.KubernetesVersion})
52-
}
60+
table := tablewriter.NewWriter(os.Stdout)
61+
table.SetHeader([]string{"Profile", "VM Driver", "NodeIP", "Node Port", "Kubernetes Version"})
62+
table.SetAutoFormatHeaders(false)
63+
table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
64+
table.SetCenterSeparator("|")
65+
validProfiles, invalidProfiles, err := config.ListProfiles()
5366

54-
table.AppendBulk(validData)
55-
table.Render()
67+
if len(validProfiles) == 0 || err != nil {
68+
exit.UsageT("No minikube profile was found. You can create one using `minikube start`.")
69+
}
70+
for _, p := range validProfiles {
71+
validData = append(validData, []string{p.Name, p.Config.MachineConfig.VMDriver, p.Config.KubernetesConfig.NodeIP, strconv.Itoa(p.Config.KubernetesConfig.NodePort), p.Config.KubernetesConfig.KubernetesVersion})
72+
}
5673

57-
if invalidProfiles != nil {
58-
out.T(out.WarningType, "Found {{.number}} invalid profile(s) ! ", out.V{"number": len(invalidProfiles)})
59-
for _, p := range invalidProfiles {
60-
out.T(out.Empty, "\t "+p.Name)
61-
}
62-
out.T(out.Tip, "You can delete them using the following command(s): ")
63-
for _, p := range invalidProfiles {
64-
out.String(fmt.Sprintf("\t $ minikube delete -p %s \n", p.Name))
65-
}
74+
table.AppendBulk(validData)
75+
table.Render()
6676

77+
if invalidProfiles != nil {
78+
out.T(out.WarningType, "Found {{.number}} invalid profile(s) ! ", out.V{"number": len(invalidProfiles)})
79+
for _, p := range invalidProfiles {
80+
out.T(out.Empty, "\t "+p.Name)
6781
}
68-
if err != nil {
69-
exit.WithCodeT(exit.Config, fmt.Sprintf("error loading profiles: %v", err))
82+
out.T(out.Tip, "You can delete them using the following command(s): ")
83+
for _, p := range invalidProfiles {
84+
out.String(fmt.Sprintf("\t $ minikube delete -p %s \n", p.Name))
7085
}
71-
},
86+
87+
}
88+
89+
if err != nil {
90+
exit.WithCodeT(exit.Config, fmt.Sprintf("error loading profiles: %v", err))
91+
}
92+
93+
}
94+
95+
var printProfilesJSON = func() {
96+
validProfiles, invalidProfiles, err := config.ListProfiles()
97+
98+
var valid []*config.Profile
99+
var invalid []*config.Profile
100+
101+
if validProfiles != nil {
102+
valid = validProfiles
103+
} else {
104+
valid = []*config.Profile{}
105+
}
106+
107+
if invalidProfiles != nil {
108+
invalid = invalidProfiles
109+
} else {
110+
invalid = []*config.Profile{}
111+
}
112+
113+
var body = map[string]interface{}{}
114+
115+
if err == nil {
116+
body["valid"] = valid
117+
body["invalid"] = invalid
118+
jsonString, _ := json.Marshal(body)
119+
out.String(string(jsonString))
120+
} else {
121+
body["error"] = err
122+
jsonString, _ := json.Marshal(body)
123+
out.String(string(jsonString))
124+
os.Exit(exit.Failure)
125+
}
72126
}
73127

74128
func init() {
129+
profileListCmd.Flags().StringVarP(&output, "output", "o", "table", "The output format. One of 'json', 'table'")
75130
ProfileCmd.AddCommand(profileListCmd)
76131
}

Diff for: test/integration/functional_test.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,48 @@ func validateLogsCmd(ctx context.Context, t *testing.T, profile string) {
297297
}
298298
}
299299

300-
// validateProfileCmd asserts basic "profile" command functionality
300+
// validateProfileCmd asserts "profile" command functionality
301301
func validateProfileCmd(ctx context.Context, t *testing.T, profile string) {
302302
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list"))
303303
if err != nil {
304304
t.Errorf("%s failed: %v", rr.Args, err)
305305
}
306+
307+
// Table output
308+
listLines := strings.Split(strings.TrimSpace(rr.Stdout.String()), "\n")
309+
profileExists := false
310+
for i := 3; i < (len(listLines) - 1); i++ {
311+
profileLine := listLines[i]
312+
if strings.Contains(profileLine, profile) {
313+
profileExists = true
314+
break
315+
}
316+
}
317+
if !profileExists {
318+
t.Errorf("%s failed: Missing profile '%s'. Got '\n%s\n'", rr.Args, profile, rr.Stdout.String())
319+
}
320+
321+
// Json output
322+
rr, err = Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "--output", "json"))
323+
if err != nil {
324+
t.Errorf("%s failed: %v", rr.Args, err)
325+
}
326+
var jsonObject map[string][]map[string]interface{}
327+
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonObject)
328+
if err != nil {
329+
t.Errorf("%s failed: %v", rr.Args, err)
330+
}
331+
validProfiles := jsonObject["valid"]
332+
profileExists = false
333+
for _, profileObject := range validProfiles {
334+
if profileObject["Name"] == profile {
335+
profileExists = true
336+
break
337+
}
338+
}
339+
if !profileExists {
340+
t.Errorf("%s failed: Missing profile '%s'. Got '\n%s\n'", rr.Args, profile, rr.Stdout.String())
341+
}
306342
}
307343

308344
// validateServiceCmd asserts basic "service" command functionality

0 commit comments

Comments
 (0)