Skip to content
This repository has been archived by the owner on Sep 16, 2023. It is now read-only.

Commit

Permalink
feat: improve logging and error-handling
Browse files Browse the repository at this point in the history
close #36

Signed-off-by: Christian Kotzbauer <christian.kotzbauer@gmail.com>
  • Loading branch information
ckotzbauer committed Jun 3, 2021
1 parent 6397d45 commit df4ebc7
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 197 deletions.
9 changes: 1 addition & 8 deletions cmd/deprecation.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cmd

import (
"fmt"

"github.com/ckotzbauer/chekr/pkg/deprecation"
"github.com/ckotzbauer/chekr/pkg/kubernetes"
"github.com/ckotzbauer/chekr/pkg/printer"
Expand All @@ -28,12 +26,7 @@ var deprecationCmd = &cobra.Command{
ThrottleBurst: throttleBurst,
}

list, err := r.Execute()

if err != nil {
fmt.Printf("Error: %v", err)
return
}
list := r.Execute()

output, _ := cmd.Flags().GetString("output")
outputFile, _ := cmd.Flags().GetString("output-file")
Expand Down
9 changes: 1 addition & 8 deletions cmd/ha.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cmd

import (
"fmt"

"github.com/ckotzbauer/chekr/pkg/ha"
"github.com/ckotzbauer/chekr/pkg/kubernetes"
"github.com/ckotzbauer/chekr/pkg/printer"
Expand All @@ -25,12 +23,7 @@ var haCmd = &cobra.Command{
Namespace: namespace,
}

list, err := r.Execute()

if err != nil {
fmt.Printf("Error: %v", err)
return
}
list := r.Execute()

output, _ := cmd.Flags().GetString("output")
outputFile, _ := cmd.Flags().GetString("output-file")
Expand Down
8 changes: 1 addition & 7 deletions cmd/resources.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cmd

import (
"fmt"
"time"

"github.com/ckotzbauer/chekr/pkg/kubernetes"
Expand Down Expand Up @@ -41,12 +40,7 @@ var resourcesCmd = &cobra.Command{
Namespace: namespace,
}

list, err := r.Execute()

if err != nil {
fmt.Printf("Error: %v", err)
return
}
list := r.Execute()

output, _ := cmd.Flags().GetString("output")
outputFile, _ := cmd.Flags().GetString("output-file")
Expand Down
21 changes: 21 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ package cmd

import (
"fmt"
"io"
"os"

"github.com/ckotzbauer/chekr/pkg/kubernetes"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/client-go/tools/clientcmd"
)

var (
overrides *clientcmd.ConfigOverrides
verbosity string

rootCmd = &cobra.Command{
Use: "chekr",
Short: "A inspection utility for kubernetes-cluster maintenance.",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := setUpLogs(os.Stdout, verbosity); err != nil {
return err
}

output, _ := cmd.Flags().GetString("output")

if output != "table" && output != "json" && output != "html" {
Expand All @@ -38,6 +46,19 @@ func init() {
rootCmd.PersistentFlags().StringP("output", "o", "table", "Output-Format. Valid values are [table, json, html]")
rootCmd.PersistentFlags().StringP("output-file", "", "", "File to write to output to.")
rootCmd.PersistentFlags().StringP(clientcmd.RecommendedConfigPathFlag, "", "", "Path to the kubeconfig file to use for CLI requests.")
rootCmd.PersistentFlags().StringVarP(&verbosity, "verbosity", "v", logrus.WarnLevel.String(), "Log-level (debug, info, warn, error, fatal, panic)")

overrides = kubernetes.BindFlags(rootCmd.PersistentFlags())
}

//setUpLogs set the log output ans the log level
func setUpLogs(out io.Writer, level string) error {
logrus.SetOutput(out)
lvl, err := logrus.ParseLevel(level)
if err != nil {
return err
}

logrus.SetLevel(lvl)
return nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.10.0
github.com/prometheus/common v0.25.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
golang.org/x/text v0.3.5 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
Expand Down
76 changes: 32 additions & 44 deletions pkg/deprecation/deprecation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"

semver "github.com/Masterminds/semver/v3"
"github.com/ckotzbauer/chekr/pkg/kubernetes"
"github.com/ckotzbauer/chekr/pkg/printer"
"github.com/ckotzbauer/chekr/pkg/util"
"github.com/ddelizia/channelify"
"github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand All @@ -22,79 +22,71 @@ import (

var ignoredDeprecatedKinds = []string{"Event"}

func (d Deprecation) Execute() (printer.PrintableList, error) {
apis, err := fetchDeprecatedApis()

if err != nil {
return nil, err
}
func (d Deprecation) Execute() printer.PrintableList {
apis := fetchDeprecatedApis()

rest.SetDefaultWarningHandler(rest.NoWarnings{})
return d.findDeprecatedVersions(apis)
}

func fetchDeprecatedApis() ([]GroupVersion, error) {
func fetchDeprecatedApis() []GroupVersion {
file, err := ioutil.TempFile("", "k8s_deprecation")

if err != nil {
return nil, err
logrus.WithError(err).Fatalf("Could not create temp-file!")
}

err = util.DownloadFile(
file.Name(),
"https://raw.githubusercontent.com/ckotzbauer/chekr/master/data/k8s_deprecations_generated.json")

if err != nil {
return nil, err
logrus.WithError(err).Fatalf("Could not download deprecation-definition!")
}

buf, err := ioutil.ReadFile(file.Name())

if err != nil {
return nil, err
logrus.WithError(err).Fatalf("Could not read deprecation-definition!")
}

data := []GroupVersion{}
err = json.Unmarshal([]byte(buf), &data)

if err != nil {
return nil, err
logrus.WithError(err).Fatalf("Could not unmarshal deprecation-definition!")
}

return data, nil
return data
}

func (d Deprecation) findDeprecatedVersions(deprecatedGVs []GroupVersion) (DeprecatedResourceList, error) {
func (d Deprecation) findDeprecatedVersions(deprecatedGVs []GroupVersion) DeprecatedResourceList {
kindVersions := d.KubeClient.DiscoverResourceNameAndPreferredGV()
d.KubeClient.Config.Burst = d.ThrottleBurst
dynamicClient, err := dynamic.NewForConfig(d.KubeClient.Config)
ignoredDeprecatedKinds = append(ignoredDeprecatedKinds, d.IgnoredKinds...)

if err != nil {
return DeprecatedResourceList{}, err
logrus.WithError(err).Fatalf("Could not create Kubernetes discovery client!")
}

fn1 := func(
d Deprecation,
deprecatedGV GroupVersion,
deprecatedGVR Resource,
client dynamic.Interface,
kindVersions kubernetes.KindVersions) printer.PrintableResult {
kindVersions kubernetes.KindVersions) printer.Printable {

return d.analyzeDeprecatedResource(deprecatedGV, deprecatedGVR, dynamicClient, kindVersions)
}

ch1 := channelify.Channelify(fn1)
var channels [](chan printer.PrintableResult)
var channels [](chan printer.Printable)
deprecatedList := DeprecatedResourceList{Items: []DeprecatedResource{}}

for _, deprecatedGV := range deprecatedGVs {
for _, deprecatedGVR := range deprecatedGV.Resources {
ignored, err := d.isVersionIgnored(deprecatedGVR.Deprecated)

if err != nil {
return DeprecatedResourceList{}, err
}
ignored := d.isVersionIgnored(deprecatedGVR.Deprecated)

if ignored || util.Contains(ignoredDeprecatedKinds, deprecatedGVR.Name) {
continue
Expand All @@ -105,57 +97,53 @@ func (d Deprecation) findDeprecatedVersions(deprecatedGVs []GroupVersion) (Depre
continue
}

ch := ch1.(func(Deprecation, GroupVersion, Resource, dynamic.Interface, kubernetes.KindVersions) chan printer.PrintableResult)(d, deprecatedGV, deprecatedGVR, dynamicClient, kindVersions)
ch := ch1.(func(Deprecation, GroupVersion, Resource, dynamic.Interface, kubernetes.KindVersions) chan printer.Printable)(d, deprecatedGV, deprecatedGVR, dynamicClient, kindVersions)
channels = append(channels, ch)
}
}

for _, v := range channels {
result := <-v

if result.Error != nil {
return DeprecatedResourceList{}, result.Error
}

if result.Item == nil {
if result == nil {
continue
}

deprecatedList.Items = append(deprecatedList.Items, result.Item.([]DeprecatedResource)...)
deprecatedList.Items = append(deprecatedList.Items, result.([]DeprecatedResource)...)
}

return deprecatedList, nil
return deprecatedList
}

func (d Deprecation) analyzeDeprecatedResource(
deprecatedGV GroupVersion,
deprecatedGVR Resource,
client dynamic.Interface,
kindVersions kubernetes.KindVersions) printer.PrintableResult {
kindVersions kubernetes.KindVersions) printer.Printable {

deprecated := make([]DeprecatedResource, 0)
supportedVersions := kindVersions[deprecatedGVR.Name]
supported := findSupportedKindVersion(supportedVersions, deprecatedGV.Version)

if supported.Version == "" {
// This deprecated version does not exist anymore "Deleted"
return printer.PrintableResult{Item: deprecated}
return deprecated
}

gvr := schema.GroupVersionResource{Group: deprecatedGV.Group, Version: deprecatedGV.Version, Resource: supported.Name}
deprecatedItems, err := client.Resource(gvr).List(context.TODO(), metav1.ListOptions{})

if apierrors.IsNotFound(err) || apierrors.IsMethodNotSupported(err) {
return printer.PrintableResult{Item: deprecated}
return deprecated
}

if apierrors.IsForbidden(err) {
log.Fatalf("Failed to list objects in the cluster. Permission denied! Please check if you have the proper authorization")
return printer.PrintableResult{Item: deprecated}
logrus.WithError(err).Fatalf("Failed to list objects in the cluster. Permission denied! Please check if you have the proper authorization")
return deprecated
}

if err != nil {
log.Fatalf("Failed communicating with k8s while listing objects [%v] %v. \nError: %v", gvr.String(), apierrors.ReasonForError(err), err)
logrus.WithError(err).WithField("reason", apierrors.ReasonForError(err)).Fatalf("Failed communicating with k8s while listing objects [%v]", gvr.String())
}

if len(deprecatedItems.Items) > 0 {
Expand All @@ -166,15 +154,15 @@ func (d Deprecation) analyzeDeprecatedResource(
replacementItems, err := client.Resource(replacementGvr).List(context.TODO(), metav1.ListOptions{})

if apierrors.IsNotFound(err) {
return printer.PrintableResult{Item: deprecated}
return deprecated
}

if apierrors.IsForbidden(err) {
log.Fatalf("Failed to list objects in the cluster. Permission denied! Please check if you have the proper authorization")
logrus.WithError(err).Fatalf("Failed to list objects in the cluster. Permission denied! Please check if you have the proper authorization")
}

if err != nil {
log.Fatalf("Failed communicating with k8s while listing objects. \nError: %v", err)
logrus.WithError(err).Fatalf("Failed communicating with k8s while listing objects.")
}

for _, deprecatedItem := range deprecatedItems.Items {
Expand All @@ -189,10 +177,10 @@ func (d Deprecation) analyzeDeprecatedResource(
}
}

return printer.PrintableResult{Item: deprecated}
return deprecated
}

func (d Deprecation) isVersionIgnored(deprecation string) (bool, error) {
func (d Deprecation) isVersionIgnored(deprecation string) bool {
if d.K8sVersion == "" {
info, err := d.KubeClient.Client.ServerVersion()

Expand All @@ -204,16 +192,16 @@ func (d Deprecation) isVersionIgnored(deprecation string) (bool, error) {
c, err := semver.NewConstraint("< " + deprecation)

if err != nil {
return false, err
logrus.WithError(err).WithField("constraint", "< "+deprecation).Fatalf("Could not parse version-constraint!")
}

v, err := semver.NewVersion(d.K8sVersion)

if err != nil {
return false, err
logrus.WithError(err).WithField("version1", deprecation).WithField("version2", d.K8sVersion).Fatalf("Could not compare versions!")
}

return c.Check(v), nil
return c.Check(v)
}

func createDeprecationItem(deprecatedItem *unstructured.Unstructured, metadata Resource) DeprecatedResource {
Expand Down
8 changes: 4 additions & 4 deletions pkg/deprecation/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ type DeprecatedResourceList struct {
Items []DeprecatedResource
}

func (p DeprecatedResourceList) ToJson() (string, error) {
func (p DeprecatedResourceList) ToJson() string {
return printer.ToJson(p.Items)
}

func (p DeprecatedResourceList) ToHtml() (string, error) {
func (p DeprecatedResourceList) ToHtml() string {
return printer.ToHtml(HtmlPage, p)
}

func (p DeprecatedResourceList) ToTable() (string, error) {
func (p DeprecatedResourceList) ToTable() string {
buf := new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
table.SetRowSeparator("-")
Expand Down Expand Up @@ -94,5 +94,5 @@ func (p DeprecatedResourceList) ToTable() (string, error) {
}

table.Render()
return buf.String(), nil
return buf.String()
}
Loading

0 comments on commit df4ebc7

Please sign in to comment.