Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
howardjohn committed Jun 27, 2019
1 parent 8b2cad0 commit 0f3ed86
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 113 deletions.
129 changes: 22 additions & 107 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
Expand All @@ -15,40 +16,33 @@ type Args struct {
KubeConfig string
}

func createClient(kubeconfig string) (*kubernetes.Clientset, error) {
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
func Run(args *Args) error {
config, err := clientcmd.BuildConfigFromFlags("", args.KubeConfig)
if err != nil {
return nil, fmt.Errorf("failed to get kubeconfig: %v", err)
return fmt.Errorf("failed to get kubeconfig: %v", err)
}

clientset, err := kubernetes.NewForConfig(config)
metricsResponse, err := FetchMetrics(config, args.Namespace)
if err != nil {
return nil, err
return fmt.Errorf("failed to fetch metrics: %v", err)
}

return clientset, nil
}

type Resource struct {
Request int
Limit int
Usage int
}
podResponse, err := FetchPods(config, args.Namespace)
if err != nil {
return fmt.Errorf("failed to fetch pod: %v", err)
}

type ContainerResource struct {
Cpu *Resource
Memory *Resource
}
resources, err := MergePodResources(metricsResponse, podResponse)
if err != nil {
return fmt.Errorf("failed to merge responses: %v", err)
}

type PodResource struct {
Name string
Namespace string
Node string
Containers map[string]*ContainerResource
if err := Write(resources, args); err != nil {
return fmt.Errorf("faild to write: %v", err)
}
return nil
}

func FetchMetrics(cfg *rest.Config, ns string) (map[string]*PodResource, error) {

metricsclient, err := metrics.NewForConfig(cfg)
if err != nil {
return nil, fmt.Errorf("failed to create metrics client: %v", err)
Expand Down Expand Up @@ -81,11 +75,8 @@ func FetchMetrics(cfg *rest.Config, ns string) (map[string]*PodResource, error)
}
}
}
return res, nil
}

func uid(name, ns string) string {
return name + "~" + ns
return res, nil
}

func FetchPods(cfg *rest.Config, ns string) (map[string]*PodResource, error) {
Expand Down Expand Up @@ -124,86 +115,10 @@ func FetchPods(cfg *rest.Config, ns string) (map[string]*PodResource, error) {
}
}
}
return res, nil
}

func Run(args *Args) error {
config, err := clientcmd.BuildConfigFromFlags("", args.KubeConfig)
if err != nil {
return fmt.Errorf("failed to get kubeconfig: %v", err)
}
metricsResponse, err := FetchMetrics(config, args.Namespace)
if err != nil {
return fmt.Errorf("failed to fetch metrics: %v", err)
}

podResponse, err := FetchPods(config, args.Namespace)
if err != nil {
return fmt.Errorf("failed to fetch pod: %v", err)
}

resources, err := MergePodResources(metricsResponse, podResponse)
if err != nil {
return fmt.Errorf("failed to merge responses: %v", err)
}

if err := Write(resources); err != nil {
return fmt.Errorf("faild to write: %v", err)
}
return nil
return res, nil
}

func MergePodResources(resources ...map[string]*PodResource) (map[string]*PodResource, error) {
merged := map[string]*PodResource{}
for _, resource := range resources {
for key, pod := range resource {
if merged[key] != nil {
if merged[key].Name != pod.Name {
return nil, fmt.Errorf("attempted to merge pods with mismatched names %v %v", merged[key].Name, pod.Name)
}
if merged[key].Namespace != pod.Namespace {
return nil, fmt.Errorf("attempted to merge pods with mismatched namespace %v %v", merged[key].Namespace, pod.Namespace)
}
} else {
merged[key] = &PodResource{
Name: pod.Name,
Namespace: pod.Namespace,
Containers: make(map[string]*ContainerResource),
}
}

if pod.Node != "" {
merged[key].Node = pod.Node
}

for containerName, container := range pod.Containers {
if merged[key].Containers[containerName] == nil {
merged[key].Containers[containerName] = &ContainerResource{
Memory: &Resource{},
Cpu: &Resource{},
}
}
c := merged[key].Containers[containerName]
if container.Memory.Request != 0 {
c.Memory.Request = container.Memory.Request
}
if container.Memory.Limit != 0 {
c.Memory.Limit = container.Memory.Limit
}
if container.Memory.Usage != 0 {
c.Memory.Usage = container.Memory.Usage
}
if container.Cpu.Request != 0 {
c.Cpu.Request = container.Cpu.Request
}
if container.Cpu.Limit != 0 {
c.Cpu.Limit = container.Cpu.Limit
}
if container.Cpu.Usage != 0 {
c.Cpu.Usage = container.Cpu.Usage
}
}
}
}
return merged, nil
func uid(name, ns string) string {
return name + "~" + ns
}
76 changes: 76 additions & 0 deletions client/podresource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package client

import "fmt"

type Resource struct {
Request int
Limit int
Usage int
}

type ContainerResource struct {
Cpu *Resource
Memory *Resource
}

type PodResource struct {
Name string
Namespace string
Node string
Containers map[string]*ContainerResource
}

func MergePodResources(resources ...map[string]*PodResource) (map[string]*PodResource, error) {
merged := map[string]*PodResource{}
for _, resource := range resources {
for key, pod := range resource {
if merged[key] != nil {
if merged[key].Name != pod.Name {
return nil, fmt.Errorf("attempted to merge pods with mismatched names %v %v", merged[key].Name, pod.Name)
}
if merged[key].Namespace != pod.Namespace {
return nil, fmt.Errorf("attempted to merge pods with mismatched namespace %v %v", merged[key].Namespace, pod.Namespace)
}
} else {
merged[key] = &PodResource{
Name: pod.Name,
Namespace: pod.Namespace,
Containers: make(map[string]*ContainerResource),
}
}

if pod.Node != "" {
merged[key].Node = pod.Node
}

for containerName, container := range pod.Containers {
if merged[key].Containers[containerName] == nil {
merged[key].Containers[containerName] = &ContainerResource{
Memory: &Resource{},
Cpu: &Resource{},
}
}
c := merged[key].Containers[containerName]
if container.Memory.Request != 0 {
c.Memory.Request = container.Memory.Request
}
if container.Memory.Limit != 0 {
c.Memory.Limit = container.Memory.Limit
}
if container.Memory.Usage != 0 {
c.Memory.Usage = container.Memory.Usage
}
if container.Cpu.Request != 0 {
c.Cpu.Request = container.Cpu.Request
}
if container.Cpu.Limit != 0 {
c.Cpu.Limit = container.Cpu.Limit
}
if container.Cpu.Usage != 0 {
c.Cpu.Usage = container.Cpu.Usage
}
}
}
}
return merged, nil
}
25 changes: 19 additions & 6 deletions client/writer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"fmt"
"io"
"os"
"sort"
Expand All @@ -23,25 +24,37 @@ func sortPodResources(res []*PodResource) {
})
}

func Write(response map[string]*PodResource) error {
func Write(response map[string]*PodResource, args *Args) error {
resources := make([]*PodResource, 0, len(response))
for _, res := range response {
resources = append(resources, res)
}
sortPodResources(resources)

w := getNewTabWriter(os.Stdout)
if _, err := w.Write([]byte("NAME\tNAMESPACE\tNODE\n")); err != nil {
return err
if _, err := w.Write([]byte(formatHeader(args))); err != nil {
return fmt.Errorf("write failed: %v", err)
}
for _, pod := range resources {
if _, err := w.Write([]byte(pod.Name + "\t" + pod.Namespace + "\t" + pod.Node + "\n")); err != nil {
return err
for _, res := range resources {
row := formatRow(res, args)
if _, err := w.Write([]byte(row)); err != nil {
return fmt.Errorf("write failed: %v", err)
}
}

return w.Flush()
}

func formatHeader(args *Args) string {
// TODO
return "NAME"
}

func formatRow(resource *PodResource, args *Args) string {
// TODO
return resource.Name + "\n"
}

// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text.
func getNewTabWriter(output io.Writer) *tabwriter.Writer {
return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, 0)
Expand Down

0 comments on commit 0f3ed86

Please sign in to comment.