-
-
Save nrmitchi/b303dc2bf4cdaf947892cbeeb8de6a92 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"os/user" | |
"path/filepath" | |
"sort" | |
"time" | |
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | |
"k8s.io/client-go/kubernetes" | |
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" // Import is necessary in order to support GKE | |
"k8s.io/client-go/tools/clientcmd" | |
) | |
func main() { | |
var kubeconfig *string | |
u, err := user.Current() | |
if err != nil { | |
panic(err.Error()) | |
} | |
if home := u.HomeDir; home != "" { | |
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") | |
} else { | |
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") | |
} | |
filter := flag.String("l", "", "label selector, as in kubectl -l") | |
namespace := flag.String("n", "default", "namespace selector, as in kubectl -n") | |
allNamespaces := flag.Bool("A", false, "use all namespaces") | |
flag.Parse() | |
// If allNamespaces flag was provided, overwrite "namespace" flag as empty string | |
if *allNamespaces { | |
*namespace = "" | |
} | |
// use the current context in kubeconfig | |
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// create the clientset | |
clientset, err := kubernetes.NewForConfig(config) | |
if err != nil { | |
panic(err.Error()) | |
} | |
type record struct { | |
name string | |
reason string | |
finishedAt time.Time | |
} | |
var records []record | |
// Make our Kubernetes API call based on the current context | |
pods, err := clientset.CoreV1().Pods(*namespace).List(metav1.ListOptions{LabelSelector: *filter}) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// Extract the last terminated reason and time | |
for _, pod := range pods.Items { | |
for _, stat := range pod.Status.ContainerStatuses { | |
terminated := stat.LastTerminationState.Terminated | |
if terminated == nil { | |
continue | |
} | |
records = append(records, record{ | |
name: pod.Name, | |
reason: terminated.Reason, | |
finishedAt: terminated.FinishedAt.Time, | |
}) | |
} | |
} | |
// Sort and output our exist reasons | |
sort.Slice(records, func(i, j int) bool { | |
return records[i].finishedAt.Before(records[j].finishedAt) | |
}) | |
for _, rec := range records { | |
fmt.Printf("%-40s %-12s %s (%s ago)\n", rec.name, rec.reason, rec.finishedAt.Format(time.RFC3339), time.Since(rec.finishedAt)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment