Skip to content

Commit

Permalink
Add support for JSON
Browse files Browse the repository at this point in the history
Signed-off-by: Parthvi Vala <pvala@redhat.com>
  • Loading branch information
valaparthvi committed Jun 20, 2023
1 parent 0acf1a5 commit ea2d256
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 32 deletions.
47 changes: 47 additions & 0 deletions pkg/api/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package api

/*
{
"version": "v3.11.0",
"gitCommit": "0acf1a5af",
"cluster": {
"serverURL": "https://kubernetes.docker.internal:6443",
"kubernetes": {
"version": "v1.25.9"
},
"openshift": {
"version": "4.13.0"
}
},
"podman": {
"client": {
"version": "4.5.1"
}
}
}
*/

type OdoVersion struct {
Version string `json:"version"`
GitCommit string `json:"gitCommit"`
Cluster *ClusterInfo `json:"cluster,omitempty"`
Podman *PodmanInfo `json:"podman,omitempty"`
}

type ClusterInfo struct {
ServerURL string `json:"serverURL,omitempty"`
Kubernetes ClusterClientInfo `json:"kubernetes,omitempty"`
OpenShift ClusterClientInfo `json:"openshift,omitempty"`
}

type ClusterClientInfo struct {
Version string `json:"version,omitempty"`
}

type PodmanInfo struct {
Client PodmanClientInfo `json:"client,omitempty"`
}

type PodmanClientInfo struct {
Version string `json:"version,omitempty"`
}
61 changes: 50 additions & 11 deletions pkg/odo/cli/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package version
import (
"context"
"fmt"
"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/odo/commonflags"
"github.com/redhat-developer/odo/pkg/podman"
"os"
"strings"
Expand Down Expand Up @@ -45,6 +47,7 @@ type VersionOptions struct {
}

var _ genericclioptions.Runnable = (*VersionOptions)(nil)
var _ genericclioptions.JsonOutputter = (*VersionOptions)(nil)

// NewVersionOptions creates a new VersionOptions instance
func NewVersionOptions() *VersionOptions {
Expand All @@ -69,7 +72,7 @@ func (o *VersionOptions) Complete(ctx context.Context, cmdline cmdline.Cmdline,
if o.clientset.PodmanClient != nil {
o.podmanInfo, err = o.clientset.PodmanClient.Version(ctx)
if err != nil {
klog.V(4).Info("unable to fetch the podman version: ", err)
klog.V(4).Info("unable to fetch the podman client version: ", err)
}
}

Expand All @@ -82,35 +85,70 @@ func (o *VersionOptions) Validate(ctx context.Context) (err error) {
return nil
}

func (o *VersionOptions) RunForJsonOutput(ctx context.Context) (out interface{}, err error) {
return o.run(), nil
}

func (o *VersionOptions) run() api.OdoVersion {
result := api.OdoVersion{
Version: odoversion.VERSION,
GitCommit: odoversion.GITCOMMIT,
}

if o.clientFlag {
return result
}

if o.serverInfo != nil {
clusterInfo := &api.ClusterInfo{
ServerURL: o.serverInfo.Address,
Kubernetes: api.ClusterClientInfo{Version: o.serverInfo.KubernetesVersion},
OpenShift: api.ClusterClientInfo{Version: o.serverInfo.OpenShiftVersion},
}
result.Cluster = clusterInfo
}

if o.podmanInfo.Client != nil {
podmanInfo := &api.PodmanInfo{Client: api.PodmanClientInfo{Version: o.podmanInfo.Client.Version}}
result.Podman = podmanInfo
}

return result
}

// Run contains the logic for the odo service create command
func (o *VersionOptions) Run(ctx context.Context) (err error) {
// If verbose mode is enabled, dump all KUBECLT_* env variables
// this is usefull for debuging oc plugin integration
// If verbose mode is enabled, dump all KUBECTL_* env variables
// this is useful for debugging oc plugin integration
for _, v := range os.Environ() {
if strings.HasPrefix(v, "KUBECTL_") {
klog.V(4).Info(v)
}
}

fmt.Println("odo " + odoversion.VERSION + " (" + odoversion.GITCOMMIT + ")")
odoVersion := o.run()
fmt.Println("odo " + odoVersion.Version + " (" + odoVersion.GitCommit + ")")

if o.clientFlag {
return nil
}

message := "\n"
if o.serverInfo != nil {
message = fmt.Sprintf("Server: %v\n", o.serverInfo.Address)
if odoVersion.Cluster != nil {
cluster := odoVersion.Cluster
message = fmt.Sprintf("Server: %v\n", cluster.ServerURL)

// make sure we only include OpenShift info if we actually have it
if len(o.serverInfo.OpenShiftVersion) > 0 {
message += fmt.Sprintf("OpenShift: %v\n", o.serverInfo.OpenShiftVersion)
if cluster.OpenShift.Version != "" {
message += fmt.Sprintf("OpenShift: %v\n", cluster.OpenShift.Version)
}
message += fmt.Sprintf("Kubernetes: %v\n", o.serverInfo.KubernetesVersion)

message += fmt.Sprintf("Kubernetes: %v\n", cluster.Kubernetes.Version)

}

if o.podmanInfo.Client != nil {
message += fmt.Sprintf("Podman (Client): %v\n", o.podmanInfo.Client.Version)
if odoVersion.Podman != nil {
message += fmt.Sprintf("Podman Client: %v\n", odoVersion.Podman.Client.Version)
}

fmt.Print(message)
Expand All @@ -131,6 +169,7 @@ func NewCmdVersion(name, fullName string, testClientset clientset.Clientset) *co
return genericclioptions.GenericRun(o, testClientset, cmd, args)
},
}
commonflags.UseOutputFlag(versionCmd)
clientset.Add(versionCmd, clientset.PREFERENCE, clientset.KUBERNETES_NULLABLE, clientset.PODMAN_NULLABLE)
util.SetCommandGroup(versionCmd, util.UtilityGroup)

Expand Down
7 changes: 7 additions & 0 deletions tests/helper/helper_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/onsi/gomega/types"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -324,6 +325,12 @@ func JsonPathContentContain(json string, path string, value string) {
Expect(result.String()).To(ContainSubstring(value), fmt.Sprintf("content of path %q should contain %q but is %q", path, value, result.String()))
}

// JsonPathSatisfies expects content of the path to satisfy all the matchers passed to it
func JsonPathSatisfies(json string, path string, matchers ...types.GomegaMatcher) {
result := gjson.Get(json, path)
Expect(result.String()).Should(SatisfyAll(matchers...))
}

// JsonPathDoesNotExist expects that the content of the path does not exist in the JSON string
func JsonPathDoesNotExist(json string, path string) {
result := gjson.Get(json, path)
Expand Down
71 changes: 50 additions & 21 deletions tests/integration/generic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ var _ = Describe("odo generic", func() {
Context("executing odo version command", func() {
const (
reOdoVersion = `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)`
rekubernetesVersion = `Kubernetes:\s*v[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
rePodmanVersion = `Podman \(Client\):\s*[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
reKubernetesVersion = `Kubernetes:\s*v[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
rePodmanVersion = `Podman Client:\s*[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
reJSONVersion = `^v{0,1}[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
)
When("executing the complete command with server info", func() {
var odoVersion string
Expand All @@ -125,20 +126,37 @@ var _ = Describe("odo generic", func() {
for _, podman := range []bool{true, false} {
podman := podman
It("should show the version of odo major components including server login URL", helper.LabelPodmanIf(podman, func() {
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))

// odo tests setup (CommonBeforeEach) is designed in a way that if a test is labelled with 'podman', it will not have cluster configuration
// so we only test podman info on podman labelled test, and clsuter info otherwise
// TODO (pvala): Change this behavior when we write tests that should be tested on both podman and cluster simultaneously
// Ref: https://github.com/redhat-developer/odo/issues/6719
if podman {
Expect(odoVersion).Should(MatchRegexp(rePodmanVersion))
Expect(odoVersion).To(ContainSubstring(helper.GetPodmanVersion()))
} else {
Expect(odoVersion).Should(MatchRegexp(rekubernetesVersion))
serverURL := oc.GetCurrentServerURL()
Expect(odoVersion).Should(ContainSubstring("Server: " + serverURL))
}
By("checking the human readable output", func() {
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))

// odo tests setup (CommonBeforeEach) is designed in a way that if a test is labelled with 'podman', it will not have cluster configuration
// so we only test podman info on podman labelled test, and clsuter info otherwise
// TODO (pvala): Change this behavior when we write tests that should be tested on both podman and cluster simultaneously
// Ref: https://github.com/redhat-developer/odo/issues/6719
if podman {
Expect(odoVersion).Should(MatchRegexp(rePodmanVersion))
Expect(odoVersion).To(ContainSubstring(helper.GetPodmanVersion()))
} else {
Expect(odoVersion).Should(MatchRegexp(reKubernetesVersion))
serverURL := oc.GetCurrentServerURL()
Expect(odoVersion).Should(ContainSubstring("Server: " + serverURL))
}
})

By("checking the JSON output", func() {
odoVersion = helper.Cmd("odo", "version", "-o", "json").ShouldPass().Out()
Expect(helper.IsJSON(odoVersion)).To(BeTrue())
helper.JsonPathSatisfies(odoVersion, "version", MatchRegexp(reJSONVersion))
helper.JsonPathExist(odoVersion, "gitCommit")
if podman {
helper.JsonPathSatisfies(odoVersion, "podman.client.version", MatchRegexp(reJSONVersion), Equal(helper.GetPodmanVersion()))
} else {
helper.JsonPathSatisfies(odoVersion, "cluster.kubernetes.version", MatchRegexp(reJSONVersion))
serverURL := oc.GetCurrentServerURL()
helper.JsonPathContentIs(odoVersion, "cluster.serverURL", serverURL)
helper.JsonPathExist(odoVersion, "cluster.openshift")
}
})
}))
}

Expand All @@ -158,13 +176,24 @@ var _ = Describe("odo generic", func() {
})
It("should not print podman version if podman cmd timeout has been reached", func() {
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
Expect(odoVersion).ToNot(ContainSubstring("Podman (Client):"))
Expect(odoVersion).ToNot(ContainSubstring("Podman Client:"))
})
})
It("should only print client info when asked for it", func() {
odoVersion := helper.Cmd("odo", "version", "--client").ShouldPass().Out()
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
Expect(odoVersion).ToNot(SatisfyAll(ContainSubstring("Server"), ContainSubstring("Kubernetes"), ContainSubstring("Podman (Client)")))
It("should only print client info when using --client flag", func() {
By("checking human readable output", func() {
odoVersion := helper.Cmd("odo", "version", "--client").ShouldPass().Out()
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
Expect(odoVersion).ToNot(SatisfyAll(ContainSubstring("Server"), ContainSubstring("Kubernetes"), ContainSubstring("Podman Client")))
})

By("checking JSON output", func() {
odoVersion := helper.Cmd("odo", "version", "--client", "-o", "json").ShouldPass().Out()
Expect(helper.IsJSON(odoVersion)).To(BeTrue())
helper.JsonPathSatisfies(odoVersion, "version", MatchRegexp(reJSONVersion))
helper.JsonPathExist(odoVersion, "gitCommit")
helper.JsonPathSatisfies(odoVersion, "cluster", BeEmpty())
helper.JsonPathSatisfies(odoVersion, "podman", BeEmpty())
})
})
})

Expand Down

0 comments on commit ea2d256

Please sign in to comment.