From c4e55cb672e68055d3da6bda3cf5d2aa8daebc75 Mon Sep 17 00:00:00 2001 From: zhaojizhuang <571130360@qq.com> Date: Thu, 12 Aug 2021 20:19:29 +0800 Subject: [PATCH] add support display running version Signed-off-by: zhaojizhuang <571130360@qq.com> --- internal/cli/cmd/cmd.go | 2 +- internal/cli/cmd/version.go | 78 ++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/internal/cli/cmd/cmd.go b/internal/cli/cmd/cmd.go index 6b7e5bb73f..50edec2c9b 100644 --- a/internal/cli/cmd/cmd.go +++ b/internal/cli/cmd/cmd.go @@ -36,7 +36,7 @@ func NewDefaultCiliumCommand() *cobra.Command { return nil } switch cmd.Name() { - case "completion", "help", "version": + case "completion", "help": return nil } diff --git a/internal/cli/cmd/version.go b/internal/cli/cmd/version.go index 643cdb946f..6870aeae37 100644 --- a/internal/cli/cmd/version.go +++ b/internal/cli/cmd/version.go @@ -15,15 +15,20 @@ package cmd import ( + "context" + "errors" "fmt" "io" "net/http" "runtime" "strings" - "github.com/cilium/cilium-cli/defaults" - "github.com/spf13/cobra" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/cilium/cilium-cli/defaults" + "github.com/cilium/cilium-cli/internal/k8s" ) // The following variables are set at compile time via LDFLAGS. @@ -32,6 +37,58 @@ var ( Version string ) +type CiliumVersion struct { + client *k8s.Client +} + +func NewCiliumVersion() *CiliumVersion { + return &CiliumVersion{client: k8sClient} +} + +func (c *CiliumVersion) GetRunningCiliumVersionForCluster(ctx context.Context) (string, error) { + nss, err := c.client.ListNamespaces(ctx, metav1.ListOptions{}) + if err != nil { + return "", fmt.Errorf("unable to list k8s namespace: %w", err) + } + + // First look for ns kube-system + //version, err := c.getCiliumVersionOfNamespace(ctx, "kube-system") + //if version != "" { + // return version, nil + //} + + if len(nss.Items) > 0 { + for _, namespace := range nss.Items { + version, _ := c.client.GetRunningCiliumVersion(ctx, namespace.Name) + if version != "" { + return version, nil + } + } + } + + return "", errors.New("unable to obtain cilium version: no cilium pods found") +} + +func (c *CiliumVersion) getCiliumVersionOfNamespace(ctx context.Context, namespace string) (string, error) { + pods, err := c.client.ListPods(ctx, namespace, metav1.ListOptions{LabelSelector: "k8s-app=cilium"}) + if err != nil { + return "", fmt.Errorf("unable to list cilium pods: %w", err) + } + if len(pods.Items) > 0 && len(pods.Items[0].Spec.Containers) > 0 { + image := pods.Items[0].Spec.Containers[0].Image + version := strings.SplitN(image, ":", 2) + if len(version) != 2 { + return "", errors.New("unable to extract cilium version from container image") + } + v := version[1] + if digest := strings.Index(v, "@"); digest > 0 { + v = v[:digest] + } + return v, nil + } + return "", nil +} + func getLatestStableVersion() string { resp, err := http.Get("https://raw.githubusercontent.com/cilium/cilium/master/stable.txt") if err != nil { @@ -48,16 +105,25 @@ func getLatestStableVersion() string { } func newCmdVersion() *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "version", Short: "Display detailed version information", Long: `Displays information about the version of this software.`, - Run: func(cmd *cobra.Command, _ []string) { - // TODO: add support for reporting the Cilium version running in - // the cluster, if any. See https://github.com/cilium/cilium-cli/issues/131 + RunE: func(cmd *cobra.Command, args []string) error { fmt.Printf("cilium-cli: %s compiled with %v on %v/%v\n", Version, runtime.Version(), runtime.GOOS, runtime.GOARCH) fmt.Printf("cilium image (default): %s\n", defaults.Version) fmt.Printf("cilium image (stable): %s\n", getLatestStableVersion()) + ciliumVersion := NewCiliumVersion() + version, err := ciliumVersion.GetRunningCiliumVersionForCluster(context.Background()) + if err != nil { + fmt.Printf("cilium image (running): unknown. Error: %s \n", err.Error()) + } else { + fmt.Printf("cilium image (running): %s\n", version) + } + return nil }, } + + cmd.Flags().StringVar(&contextName, "context", "", "Kubernetes configuration context") + return cmd }