Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to get json for "minikube service list" #15831

Merged
merged 5 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 36 additions & 14 deletions cmd/minikube/cmd/service_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ limitations under the License.
package cmd

import (
"encoding/json"
"fmt"
"os"
"runtime"
"strings"

"github.com/spf13/cobra"
core "k8s.io/api/core/v1"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/reason"
Expand All @@ -32,6 +35,7 @@ import (
)

var serviceListNamespace string
var profileOutput string

// serviceListCmd represents the service list command
var serviceListCmd = &cobra.Command{
Expand All @@ -40,6 +44,7 @@ var serviceListCmd = &cobra.Command{
Long: `Lists the URLs for the services in your local cluster`,
Run: func(cmd *cobra.Command, args []string) {
co := mustload.Healthy(ClusterFlagValue())
output := strings.ToLower(profileOutput)

serviceURLs, err := service.GetServiceURLs(co.API, co.Config.Name, serviceListNamespace, serviceURLTemplate)
if err != nil {
Expand All @@ -48,28 +53,45 @@ var serviceListCmd = &cobra.Command{
os.Exit(reason.ExSvcUnavailable)
}

var data [][]string
for _, serviceURL := range serviceURLs {
if len(serviceURL.URLs) == 0 {
data = append(data, []string{serviceURL.Namespace, serviceURL.Name, "No node port"})
} else {
servicePortNames := strings.Join(serviceURL.PortNames, "\n")
serviceURLs := strings.Join(serviceURL.URLs, "\n")
switch output {
case "table":
printServicesTable(serviceURLs, co)
case "json":
printServicesJSON(serviceURLs)
default:
exit.Message(reason.Usage, fmt.Sprintf("invalid output format: %s. Valid values: 'table', 'json'", output))
}
},
}

// if we are running Docker on OSX we empty the internal service URLs
if runtime.GOOS == "darwin" && co.Config.Driver == oci.Docker {
serviceURLs = ""
}
func printServicesTable(serviceURLs service.URLs, co mustload.ClusterController) {
var data [][]string
for _, serviceURL := range serviceURLs {
if len(serviceURL.URLs) == 0 {
data = append(data, []string{serviceURL.Namespace, serviceURL.Name, "No node port"})
} else {
servicePortNames := strings.Join(serviceURL.PortNames, "\n")
serviceURLs := strings.Join(serviceURL.URLs, "\n")

data = append(data, []string{serviceURL.Namespace, serviceURL.Name, servicePortNames, serviceURLs})
// if we are running Docker on OSX we empty the internal service URLs
if runtime.GOOS == "darwin" && co.Config.Driver == oci.Docker {
serviceURLs = ""
}

data = append(data, []string{serviceURL.Namespace, serviceURL.Name, servicePortNames, serviceURLs})
}
}

service.PrintServiceList(os.Stdout, data)
},
service.PrintServiceList(os.Stdout, data)
}

func printServicesJSON(serviceURLs service.URLs) {
jsonString, _ := json.Marshal(serviceURLs)
os.Stdout.Write(jsonString)
}

func init() {
serviceListCmd.Flags().StringVarP(&profileOutput, "output", "o", "table", "The output format. One of 'json', 'table'")
serviceListCmd.Flags().StringVarP(&serviceListNamespace, "namespace", "n", core.NamespaceAll, "The services namespace")
serviceCmd.AddCommand(serviceListCmd)
}
1 change: 1 addition & 0 deletions site/content/en/docs/commands/service.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ minikube service list [flags]

```
-n, --namespace string The services namespace
-o, --output string The output format. One of 'json', 'table' (default "table")
```

### Options inherited from parent commands
Expand Down
5 changes: 5 additions & 0 deletions site/content/en/docs/contrib/tests.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ Steps:
- Run `minikube service` with `--url --format={{.IP}}` to make sure the IP address of the service is printed
- Run `minikube service` with a regular `--url` to make sure the HTTP endpoint URL of the service is printed

#### validateServiceCmdJSON

Steps:
- Run `minikube service list -o JSON` and make sure the services are correctly listed as JSON output

#### validateServiceCmdConnect

Steps:
Expand Down
38 changes: 38 additions & 0 deletions test/integration/functional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"k8s.io/minikube/pkg/minikube/detect"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/reason"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/util/retry"

"github.com/blang/semver/v4"
Expand Down Expand Up @@ -1454,6 +1455,8 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) {
t.Errorf("expected 'service list' to contain *hello-node* but got -%q-", rr.Stdout.String())
}

validateServiceCmdJSON(ctx, t, profile)

// docs: Run `minikube service` with `--https --url` to make sure the HTTPS endpoint URL of the service is printed
cmdContext := exec.CommandContext(ctx, Target(), "-p", profile, "service", "--namespace=default", "--https", "--url", "hello-node")
if NeedsPortForward() {
Expand Down Expand Up @@ -1520,6 +1523,41 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) {
}
}

func validateServiceCmdJSON(ctx context.Context, t *testing.T, profile string) {
// docs: Run `minikube service list -o JSON` and make sure the services are correctly listed as JSON output
t.Run("ServiceJSONOutput", func(t *testing.T) {
targetSvcName := "hello-node"
// helper function to run command then, return target service object from json output.
extractServiceObjFunc := func(rr *RunResult) *service.SvcURL {
var jsonObjects service.URLs
err := json.Unmarshal(rr.Stdout.Bytes(), &jsonObjects)
if err != nil {
t.Fatalf("failed to decode json from profile list: args %q: %v", rr.Command(), err)
}

for _, svc := range jsonObjects {
if svc.Name == targetSvcName {
return &svc
}
}
return nil
}

start := time.Now()
rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "service", "list", "-o", "json"))
elapsed := time.Since(start)
if err != nil {
t.Fatalf("failed to list services with json format. args %q: %v", rr.Command(), err)
}
t.Logf("Took %q to run %q", elapsed, rr.Command())

pr := extractServiceObjFunc(rr)
if pr == nil {
t.Errorf("expected the json of 'service list' to include %q but got *%q*. args: %q", targetSvcName, rr.Stdout.String(), rr.Command())
}
})
}

func validateServiceCmdConnect(ctx context.Context, t *testing.T, profile string) {
defer PostMortemLogs(t, profile)

Expand Down
8 changes: 4 additions & 4 deletions translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"--kvm-numa-count range is 1-8": "Der Wertebereich für --kvm-numa-count ist 1-8",
"--network flag is only valid with the docker/podman and KVM drivers, it will be ignored": "Der Parameter --network kann nur mit dem docker/podman und den KVM Treibern verwendet werden, er wird ignoriert werden",
"--network flag is only valid with the docker/podman, KVM and Qemu drivers, it will be ignored": "",
"--network with QEMU must be 'user' or 'socket_vmnet'": "",
"--network with QEMU must be 'builtin' or 'socket_vmnet'": "",
"--static-ip is only implemented on Docker and Podman drivers, flag will be ignored": "",
"--static-ip overrides --subnet, --subnet will be ignored": "",
"1) Recreate the cluster with Kubernetes {{.new}}, by running:\n\t \n\t\t minikube delete{{.profile}}\n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t2) Create a second cluster with Kubernetes {{.new}}, by running:\n\t \n\t\t minikube start -p {{.suggestedName}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t3) Use the existing cluster at version Kubernetes {{.old}}, by running:\n\t \n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.old}}\n\t\t": "1) Erstellen Sie den Cluster mit Kubernetes {{.new}} neu, indem Sie folgende Befehle ausführen:\n\t \n\t\t minikube delete{{.profile}}\n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t2) Erstellen Sie einen zweiten Cluster mit Kubernetes {{.new}}, indem Sie folgende Befehle ausführen:\n\t \n\t\t minikube start -p {{.suggestedName}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t3) Verwenden Sie den existierenden Cluster mit Version {{.old}} von Kubernetes, indem Sie folgende Befehle ausführen:\n\t \n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.old}}\n\t\t",
Expand Down Expand Up @@ -988,14 +988,14 @@
"minikube is not meant for production use. You are opening non-local traffic": "Minikube ist nicht für die Verwendung in Produktion gedacht. Nicht lokaler Traffik wird zugelassen",
"minikube is unable to access the Google Container Registry. You may need to configure it to use a HTTP proxy.": "Minikube ist nicht in der Lage auf die Google Container Registry zuzugreifen. Eventuell müssen Sie einen HTTP Proxy konfigurieren.",
"minikube is unable to connect to the VM: {{.error}}\n\n\tThis is likely due to one of two reasons:\n\n\t- VPN or firewall interference\n\t- {{.hypervisor}} network configuration issue\n\n\tSuggested workarounds:\n\n\t- Disable your local VPN or firewall software\n\t- Configure your local VPN or firewall to allow access to {{.ip}}\n\t- Restart or reinstall {{.hypervisor}}\n\t- Use an alternative --vm-driver\n\t- Use --force to override this connectivity check\n\t": "Minikube kann nicht zur VM verbinden: {{.error}}\n\n\tDies ist wahrscheinlich aufgrund einem von zwei Gründen:\n\n\t- VPN oder Firewall Probleme\n\t- {{.hypervisor}} Netzwerk Konfiguration Issue\n\n\tVorgeschlagene Workarounds:\n\n\t- Deaktiviere die lokale VPN oder Firewall Software\n\t- Konfigure das lokale VPN oder die Firewall so, dass Zugriff auf die IP {{.ip}} erlaubt ist\n\t- Restarte oder Reinstalliere {{.hypervisor}}\n\t- Verwende einen alternativen --vm-dirver\n\t- Verwende --force um die Konnektivitäts-Prüfung zu überspringen\n\t",
"minikube mount is not currently implemented with the user network on QEMU": "",
"minikube mount is not currently implemented with the builtin network on QEMU": "",
"minikube profile was successfully set to {{.profile_name}}": "Minikube Profil wurde erfolgreich gesetzt auf {{.profile_name}}",
"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "Minikube provisioniert und managed lokale Kubernetes Cluster optimiert für Entwicklungs-Workflows.",
"minikube quickly sets up a local Kubernetes cluster": "Minikube installiert schnell einen lokalen Kubernetes Cluster",
"minikube service is not currently implemented with the user network on QEMU": "",
"minikube service is not currently implemented with the builtin network on QEMU": "",
"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "Minikube überspringt diverse Validierungen wenn --force angegeben ist; das könnte zu unerwartetem Verhalten führen",
"minikube status --output OUTPUT. json, text": "",
"minikube tunnel is not currently implemented with the user network on QEMU": "",
"minikube tunnel is not currently implemented with the builtin network on QEMU": "",
"minikube {{.version}} is available! Download it: {{.url}}": "Minikube {{.version}} ist verfügbar. Lade es herunter: {{.url}}",
"mkcmp is used to compare performance of two minikube binaries": "mkcmp wird verwendet um die Performance von zwei Minikube Binaries zu vergleichen",
"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "Das Argument \"{{.value}}\" für Mount muss in der Form \u003cQuell Verzeichnis\u003e:\u003cZiel Verzeichnis\u003e",
Expand Down
8 changes: 4 additions & 4 deletions translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"--kvm-numa-count range is 1-8": "--kvm-numa-count el rango es 1-8",
"--network flag is only valid with the docker/podman and KVM drivers, it will be ignored": "el flag --network es válido solamente con docker/podman y KVM, será ignorado",
"--network flag is only valid with the docker/podman, KVM and Qemu drivers, it will be ignored": "",
"--network with QEMU must be 'user' or 'socket_vmnet'": "",
"--network with QEMU must be 'builtin' or 'socket_vmnet'": "",
"--static-ip is only implemented on Docker and Podman drivers, flag will be ignored": "",
"--static-ip overrides --subnet, --subnet will be ignored": "",
"1) Recreate the cluster with Kubernetes {{.new}}, by running:\n\t \n\t\t minikube delete{{.profile}}\n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t2) Create a second cluster with Kubernetes {{.new}}, by running:\n\t \n\t\t minikube start -p {{.suggestedName}} --kubernetes-version={{.prefix}}{{.new}}\n\t \n\t\t3) Use the existing cluster at version Kubernetes {{.old}}, by running:\n\t \n\t\t minikube start{{.profile}} --kubernetes-version={{.prefix}}{{.old}}\n\t\t": "",
Expand Down Expand Up @@ -983,14 +983,14 @@
"minikube is not meant for production use. You are opening non-local traffic": "",
"minikube is unable to access the Google Container Registry. You may need to configure it to use a HTTP proxy.": "",
"minikube is unable to connect to the VM: {{.error}}\n\n\tThis is likely due to one of two reasons:\n\n\t- VPN or firewall interference\n\t- {{.hypervisor}} network configuration issue\n\n\tSuggested workarounds:\n\n\t- Disable your local VPN or firewall software\n\t- Configure your local VPN or firewall to allow access to {{.ip}}\n\t- Restart or reinstall {{.hypervisor}}\n\t- Use an alternative --vm-driver\n\t- Use --force to override this connectivity check\n\t": "",
"minikube mount is not currently implemented with the user network on QEMU": "",
"minikube mount is not currently implemented with the builtin network on QEMU": "",
"minikube profile was successfully set to {{.profile_name}}": "",
"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "",
"minikube quickly sets up a local Kubernetes cluster": "",
"minikube service is not currently implemented with the user network on QEMU": "",
"minikube service is not currently implemented with the builtin network on QEMU": "",
"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
"minikube status --output OUTPUT. json, text": "",
"minikube tunnel is not currently implemented with the user network on QEMU": "",
"minikube tunnel is not currently implemented with the builtin network on QEMU": "",
"minikube {{.version}} is available! Download it: {{.url}}": "",
"mkcmp is used to compare performance of two minikube binaries": "",
"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
Expand Down
4 changes: 4 additions & 0 deletions translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"--kvm-numa-count range is 1-8": "la tranche de --kvm-numa-count est 1 à 8",
"--network flag is only valid with the docker/podman and KVM drivers, it will be ignored": "l'indicateur --network est valide uniquement avec les pilotes docker/podman et KVM, il va être ignoré",
"--network flag is only valid with the docker/podman, KVM and Qemu drivers, it will be ignored": "L'indicateur --network n'est valide qu'avec les pilotes docker/podman, KVM et Qemu, il sera ignoré",
"--network with QEMU must be 'builtin' or 'socket_vmnet'": "",
"--network with QEMU must be 'user' or 'socket_vmnet'": "--network avec QEMU doit être 'user' ou 'socket_vmnet'",
"--static-ip is only implemented on Docker and Podman drivers, flag will be ignored": "--static-ip n'est implémenté que sur les pilotes Docker et Podman, l'indicateur sera ignoré",
"--static-ip overrides --subnet, --subnet will be ignored": "--static-ip remplace --subnet, --subnet sera ignoré",
Expand Down Expand Up @@ -965,14 +966,17 @@
"minikube is not meant for production use. You are opening non-local traffic": "minikube n'est pas destiné à une utilisation en production. Vous ouvrez du trafic non local",
"minikube is unable to access the Google Container Registry. You may need to configure it to use a HTTP proxy.": "minikube ne peut pas accéder à Google Container Registry. Vous devrez peut-être le configurer pour utiliser un proxy HTTP.",
"minikube is unable to connect to the VM: {{.error}}\n\n\tThis is likely due to one of two reasons:\n\n\t- VPN or firewall interference\n\t- {{.hypervisor}} network configuration issue\n\n\tSuggested workarounds:\n\n\t- Disable your local VPN or firewall software\n\t- Configure your local VPN or firewall to allow access to {{.ip}}\n\t- Restart or reinstall {{.hypervisor}}\n\t- Use an alternative --vm-driver\n\t- Use --force to override this connectivity check\n\t": "minikube ne parvient pas à se connecter à la VM : {{.error}}\n\n\tCela est probablement dû à l'une des deux raisons suivantes :\n\n\t- Interférence VPN ou pare-feu\n\t- {{.hypervisor}} problème de configuration réseau\n\n\tSolutions suggérées :\n\n\t- Désactivez votre logiciel VPN ou pare-feu local\n\t- Configurez votre VPN ou pare-feu local pour autoriser l'accès à {{.ip}}\n \t- Redémarrez ou réinstallez {{.hypervisor}}\n\t- Utilisez un autre --vm-driver\n\t- Utilisez --force pour annuler cette vérification de connectivité\n\t",
"minikube mount is not currently implemented with the builtin network on QEMU": "",
"minikube mount is not currently implemented with the user network on QEMU": "Le montage minikube n'est pas actuellement implémenté avec le réseau utilisateur sur QEMU",
"minikube profile was successfully set to {{.profile_name}}": "Le profil de minikube a été défini avec succès sur {{.profile_name}}",
"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube provisionne et gère des clusters Kubernetes locaux optimisés pour les workflows de développement.",
"minikube quickly sets up a local Kubernetes cluster": "minikube configure rapidement un cluster Kubernetes local",
"minikube service is not currently implemented with the builtin network on QEMU": "",
"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le service minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.",
"minikube service is not currently implemented with the user network on QEMU": "Le service minikube n'est pas actuellement implémenté avec le réseau utilisateur sur QEMU",
"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "minikube ignore diverses validations lorsque --force est fourni ; cela peut conduire à un comportement inattendu",
"minikube status --output OUTPUT. json, text": "état minikube --sortie SORTIE. json, texte",
"minikube tunnel is not currently implemented with the builtin network on QEMU": "",
"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le tunnel minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.",
"minikube tunnel is not currently implemented with the user network on QEMU": "Le tunnel minikube n'est pas actuellement implémenté avec le réseau utilisateur sur QEMU",
"minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} est disponible ! Téléchargez-le ici : {{.url}}",
Expand Down