Skip to content

Commit

Permalink
Merge pull request #52 from ngtuna/print-out
Browse files Browse the repository at this point in the history
display output of `kubeapps up`
  • Loading branch information
ngtuna authored Nov 28, 2017
2 parents 6be4f35 + 0f693c8 commit 77505a6
Show file tree
Hide file tree
Showing 30 changed files with 2,901 additions and 43 deletions.
5 changes: 2 additions & 3 deletions cmd/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package cmd

import (
"fmt"

"github.com/ksonnet/kubecfg/pkg/kubecfg"
"github.com/ksonnet/kubecfg/utils"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -61,10 +60,10 @@ var downCmd = &cobra.Command{
return fmt.Errorf("can't parse kubeapps manifest: %v", err)
}
if err = c.Run(objs); err != nil {
return fmt.Errorf("can't uninstall kubeapps components: %v", err)
return fmt.Errorf("can't remove kubeapps components: %v", err)
}

fmt.Println("successfully uninstalled kubeapps")
fmt.Printf("\nKubeapps has been removed successfully.\n\n")
return nil
},
}
Expand Down
163 changes: 159 additions & 4 deletions cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,29 @@ package cmd

import (
"fmt"
"io"
"os"
"strconv"
"strings"

"github.com/gosuri/uitable"
"github.com/ksonnet/kubecfg/metadata"
"github.com/ksonnet/kubecfg/pkg/kubecfg"
"github.com/kubeapps/kubeapps/pkg/gke"
"github.com/ksonnet/kubecfg/utils"
"github.com/kubeapps/kubeapps/pkg/gke"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/apps/v1beta1"
)

const (
GcTag = "bitnami/kubeapps"
GcTag = "bitnami/kubeapps"
KubeappsNS = "kubeapps"
KubelessNS = "kubeless"
SystemNS = "kube-system"
)

var upCmd = &cobra.Command{
Expand Down Expand Up @@ -118,10 +128,22 @@ List of components that kubeapps up installs:
c.SkipGc = false
}

if err = c.Run(objs, wd); err != nil {
err = c.Run(objs, wd)
if err != nil {
return fmt.Errorf("can't install kubeapps components: %v", err)
}
fmt.Println("successfully installed kubeapps")

config, err := buildOutOfClusterConfig()
if err != nil {
return err
}
clientset, err := kubernetes.NewForConfig(config)

err = printOutput(cmd.OutOrStdout(), clientset)
if err != nil {
return err
}

return nil
},
}
Expand All @@ -142,3 +164,136 @@ func isGKE(disco discovery.DiscoveryInterface) (bool, error) {

return false, nil
}

func printOutput(w io.Writer, c *kubernetes.Clientset) error {
fmt.Printf("\nKubeapps has been deployed successfully. \n" +
"It may takes few minutes for all components to be ready. \n\n")
nss := []string{KubeappsNS, KubelessNS, SystemNS}
err := printSvc(w, c, nss)
if err != nil {
return err
}
err = printDeployment(w, c, nss)
if err != nil {
return err
}
err = printStS(w, c, nss)
if err != nil {
return err
}

err = printPod(w, c, nss)
if err != nil {
return err
}

fmt.Printf("Checking `kubectl get all --all-namespaces -l created-by=kubeapps` for details. \n\n")

return nil
}

func printPod(w io.Writer, c kubernetes.Interface, nss []string) error {
table := uitable.New()
table.MaxColWidth = 50
table.Wrap = true
table.AddRow("NAMESPACE", "NAME", "STATUS")
pods := []v1.Pod{}
for _, ns := range nss {
p, err := c.CoreV1().Pods(ns).List(metav1.ListOptions{
LabelSelector: "created-by=kubeapps",
})
if err != nil {
return err
}
pods = append(pods, p.Items...)
}
for _, p := range pods {
table.AddRow(p.Namespace, fmt.Sprintf("pod/%s", p.Name), p.Status.Phase)
}
fmt.Fprintln(w, table)
fmt.Fprintln(w)
return nil
}

func printStS(w io.Writer, c kubernetes.Interface, nss []string) error {
table := uitable.New()
table.MaxColWidth = 50
table.Wrap = true
table.AddRow("NAMESPACE", "NAME", "DESIRED", "CURRENT")
sts := []v1beta1.StatefulSet{}
for _, ns := range nss {
s, err := c.AppsV1beta1().StatefulSets(ns).List(metav1.ListOptions{
LabelSelector: "created-by=kubeapps",
})
if err != nil {
return err
}
sts = append(sts, s.Items...)
}
for _, s := range sts {
table.AddRow(s.Namespace, fmt.Sprintf("statefulsets/%s", s.Name), *s.Spec.Replicas, s.Status.Replicas)
}
fmt.Fprintln(w, table)
fmt.Fprintln(w)
return nil
}

func printDeployment(w io.Writer, c kubernetes.Interface, nss []string) error {
table := uitable.New()
table.MaxColWidth = 50
table.Wrap = true
table.AddRow("NAMESPACE", "NAME", "DESIRED", "CURRENT", "UP-TO-DATE", "AVAILABLE")
deps := []v1beta1.Deployment{}
for _, ns := range nss {
dep, err := c.AppsV1beta1().Deployments(ns).List(metav1.ListOptions{
LabelSelector: "created-by=kubeapps",
})
if err != nil {
return err
}
deps = append(deps, dep.Items...)
}

for _, d := range deps {
table.AddRow(d.Namespace, fmt.Sprintf("deploy/%s", d.Name), *d.Spec.Replicas, d.Status.Replicas, d.Status.UpdatedReplicas, d.Status.AvailableReplicas)
}
fmt.Fprintln(w, table)
fmt.Fprintln(w)
return nil
}

func printSvc(w io.Writer, c kubernetes.Interface, nss []string) error {
table := uitable.New()
table.MaxColWidth = 50
table.Wrap = true
table.AddRow("NAMESPACE", "NAME", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)")
svcs := []v1.Service{}
for _, ns := range nss {
svc, err := c.CoreV1().Services(ns).List(metav1.ListOptions{
LabelSelector: "created-by=kubeapps",
})
if err != nil {
return err
}
svcs = append(svcs, svc.Items...)
}

for _, s := range svcs {
eIPs := ""
if len(s.Spec.ExternalIPs) != 0 {
for _, ip := range s.Spec.ExternalIPs {
eIPs = eIPs + ip + ", "
}
}
ports := ""
if len(s.Spec.Ports) != 0 {
for _, p := range s.Spec.Ports {
ports = ports + fmt.Sprintf("%s/%s, ", strconv.FormatInt(int64(p.Port), 10), p.Protocol)
}
}
table.AddRow(s.Namespace, fmt.Sprintf("svc/%s", s.Name), s.Spec.ClusterIP, eIPs, ports)
}
fmt.Fprintln(w, table)
fmt.Fprintln(w)
return nil
}
107 changes: 107 additions & 0 deletions cmd/up_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package cmd

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/apps/v1beta1"
restclient "k8s.io/client-go/rest"
)

Expand Down Expand Up @@ -61,3 +67,104 @@ func TestIsGKE(t *testing.T) {
t.Errorf("expect non-GKE but got GKE")
}
}

func TestPrintOutput(t *testing.T) {
om1 := metav1.ObjectMeta{
Name: "foo",
Namespace: "myns",
Labels: map[string]string{
"created-by": "kubeapps",
},
}
om2 := metav1.ObjectMeta{
Name: "bar",
Namespace: "myns",
}

po1 := &v1.Pod{
ObjectMeta: om1,
}
po2 := &v1.Pod{
ObjectMeta: om2,
}

svc1 := &v1.Service{
ObjectMeta: om1,
}
svc2 := &v1.Service{
ObjectMeta: om2,
}

replicas := int32(1)
sts1 := &v1beta1.StatefulSet{
ObjectMeta: om1,
Spec: v1beta1.StatefulSetSpec{
Replicas: &replicas,
},
}
sts2 := &v1beta1.StatefulSet{
ObjectMeta: om2,
}

dep1 := &v1beta1.Deployment{
ObjectMeta: om1,
Spec: v1beta1.DeploymentSpec{
Replicas: &replicas,
},
}
dep2 := &v1beta1.Deployment{
ObjectMeta: om2,
}

client := fake.NewSimpleClientset(po1, po2, svc1, svc2, sts1, sts2, dep1, dep2)
ns := []string{"myns"}
var buf bytes.Buffer

err := printPod(&buf, client, ns)
if err != nil {
t.Error(err)
}
output := buf.String()
if !strings.Contains(output, "foo") {
t.Errorf("pod %s isn't listed", po1.Name)
}
if strings.Contains(output, "bar") {
t.Errorf("pod %s shouldn't be listed", po2.Name)
}

err = printSvc(&buf, client, ns)
if err != nil {
t.Error(err)
}
output = buf.String()
if !strings.Contains(output, "foo") {
t.Errorf("service %s isn't listed", po1.Name)
}
if strings.Contains(output, "bar") {
t.Errorf("service %s shouldn't be listed", po2.Name)
}

err = printDeployment(&buf, client, ns)
if err != nil {
t.Error(err)
}
output = buf.String()
if !strings.Contains(output, "foo") {
t.Errorf("deployment %s isn't listed", po1.Name)
}
if strings.Contains(output, "bar") {
t.Errorf("deployment %s shouldn't be listed", po2.Name)
}

err = printStS(&buf, client, ns)
if err != nil {
t.Error(err)
}
output = buf.String()
if !strings.Contains(output, "foo") {
t.Errorf("statefulset %s isn't listed", po1.Name)
}
if strings.Contains(output, "bar") {
t.Errorf("statefulset %s shouldn't be listed", po2.Name)
}
}
Loading

0 comments on commit 77505a6

Please sign in to comment.