From 1be52fb3045ae473e9ea48c3f0c38fd1b2c584f1 Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 23 Jun 2017 09:40:53 +0100 Subject: [PATCH 1/5] Add missing error output if JSON output can't be emitted --- cmd/common.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/common.go b/cmd/common.go index 1e35449..33ded89 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -112,6 +112,8 @@ func runChecks(t check.NodeType) { if jsonFmt { out, err := controls.JSON() if err != nil { + fmt.Fprintf(os.Stderr, "failed to output in JSON format: %v\n", err) + os.Exit(1) } fmt.Println(string(out)) From b36832e40c0b6ac068039ab02869ef67a0a20fc0 Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 23 Jun 2017 09:58:46 +0100 Subject: [PATCH 2/5] Correct block-copy error in flanneld config directory --- cmd/common.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/common.go b/cmd/common.go index 33ded89..c96893b 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -86,7 +86,7 @@ func runChecks(t check.NodeType) { // Variable substitutions. Replace all occurrences of variables in controls file. s := strings.Replace(string(in), "$kubeConfDir", viper.Get("kubeConfDir").(string), -1) s = strings.Replace(s, "$etcdConfDir", viper.Get("etcdConfDir").(string), -1) - s = strings.Replace(s, "$flanneldConfDir", viper.Get("etcdConfDir").(string), -1) + s = strings.Replace(s, "$flanneldConfDir", viper.Get("flanneldConfDir").(string), -1) controls := check.NewControls(t, []byte(s)) From f6509b804e5606e711033ccfc3b87fa24c66db81 Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 23 Jun 2017 10:28:58 +0100 Subject: [PATCH 3/5] Typo --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index da8ab94..2506c54 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -99,7 +99,7 @@ func initConfig() { if err := viper.ReadInConfig(); err == nil { colorPrint(check.INFO, fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed())) } else { - colorPrint(check.FAIL, fmt.Sprintf("Faied to read config file: %v\n", err)) + colorPrint(check.FAIL, fmt.Sprintf("Failed to read config file: %v\n", err)) os.Exit(1) } } From 6340ee44c5393c59008fdf7b00f78b9b750622e7 Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 23 Jun 2017 10:41:40 +0100 Subject: [PATCH 4/5] =?UTF-8?q?Don=E2=80=99t=20output=20warnings=20as=20te?= =?UTF-8?q?xt=20if=20we=E2=80=99re=20generating=20JSON=20output.=20Add=20e?= =?UTF-8?q?rror=20handling=20in=20a=20few=20missing=20cases.=20Some=20comm?= =?UTF-8?q?ent=20tidying.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/common.go | 82 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index c96893b..a296999 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -54,6 +54,7 @@ var ( func runChecks(t check.NodeType) { var summary check.Summary + var warnings []string var file string // Set up for config file check. @@ -66,7 +67,15 @@ func runChecks(t check.NodeType) { kubeNodeConf = append(kubeNodeConf, viper.Get("kubeConfDir").(string)+"/kubelet") kubeNodeConf = append(kubeNodeConf, viper.Get("kubeConfDir").(string)+"/proxy") - verifyNodeType(t) + warnings, err := verifyNodeType(t, warnings) + if err != nil { + for _, w := range warnings { + colorPrint(check.WARN, w) + } + + fmt.Fprintf(os.Stderr, "failed to verify node type: %v\n", err) + os.Exit(1) + } switch t { case check.MASTER: @@ -91,17 +100,14 @@ func runChecks(t check.NodeType) { controls := check.NewControls(t, []byte(s)) if groupList != "" && checkList == "" { - // log.Println("group: set, checks: not set") ids := cleanIDs(groupList) summary = controls.RunGroup(ids...) } else if checkList != "" && groupList == "" { - // log.Println("group: not set, checks: set") ids := cleanIDs(checkList) summary = controls.RunChecks(ids...) } else if checkList != "" && groupList != "" { - // log.Println("group: set, checks: set") fmt.Fprintf(os.Stderr, "group option and check option can't be used together\n") os.Exit(1) @@ -109,7 +115,8 @@ func runChecks(t check.NodeType) { summary = controls.RunGroup() } - if jsonFmt { + // if we successfully ran some tests and it's json format, ignore the warnings + if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0) && jsonFmt { out, err := controls.JSON() if err != nil { fmt.Fprintf(os.Stderr, "failed to output in JSON format: %v\n", err) @@ -118,7 +125,7 @@ func runChecks(t check.NodeType) { fmt.Println(string(out)) } else { - prettyPrint(controls, summary) + prettyPrint(warnings, controls, summary) } } @@ -133,7 +140,8 @@ func cleanIDs(list string) []string { return ids } -func verifyNodeType(t check.NodeType) { +// verifyNodeType checks the executables and config files are as expected for the specified tests (master, node or federated) +func verifyNodeType(t check.NodeType, w []string) ([]string, error) { var binPath []string var confPath []string var out []byte @@ -155,40 +163,58 @@ func verifyNodeType(t check.NodeType) { for _, b := range binPath { _, err := exec.LookPath(b) if err != nil { - colorPrint(check.WARN, fmt.Sprintf("%s: command not found on path - version check skipped\n", b)) + w = append(w, fmt.Sprintf("%s: command not found on path - version check skipped\n", b)) continue } // Check version cmd := exec.Command(b, "--version") - out, _ = cmd.Output() - if matched, _ := regexp.MatchString(kubeVersion, string(out)); !matched { - colorPrint(check.FAIL, - fmt.Sprintf( - "%s unsupported version, expected %s, got %s\n", - b, - kubeVersion, - string(out), - )) - os.Exit(1) + out, err = cmd.Output() + if err != nil { + return w, fmt.Errorf("failed executing %s --version: %v", b, err) + } + + matched, err := regexp.MatchString(kubeVersion, string(out)) + if err != nil { + return w, fmt.Errorf("regexp match for version failed: %v", err) + } + + if !matched { + return w, fmt.Errorf( + "%s unsupported version, expected %s, got %s", + b, + kubeVersion, + string(out), + ) } } + // Check if the executables for this type of node are running. for _, b := range binPath { - // Check if running. cmd := exec.Command("ps", "-ef") - out, _ = cmd.Output() - if matched, _ := regexp.MatchString(".*"+b, string(out)); !matched { - colorPrint(check.FAIL, fmt.Sprintf("%s is not running\n", b)) - os.Exit(1) + out, err := cmd.Output() + if err != nil { + return w, fmt.Errorf("failed executing ps -ef: %v", err) + } + + matched, err := regexp.MatchString(".*"+b, string(out)) + if err != nil { + return w, fmt.Errorf("regexp match for ps output failed: %v", err) + } + + if !matched { + return w, fmt.Errorf("%s is not running", b) } } + // Check whether the config files for this type of node are in the expected location for _, c := range confPath { if _, err := os.Stat(c); os.IsNotExist(err) { - colorPrint(check.WARN, fmt.Sprintf("config file %s does not exist\n", c)) + w = append(w, fmt.Sprintf("config file %s does not exist\n", c)) } } + + return w, nil } // colorPrint outputs the state in a specific colour, along with a message string @@ -197,8 +223,12 @@ func colorPrint(state check.State, s string) { fmt.Printf("%s", s) } -func prettyPrint(r *check.Controls, summary check.Summary) { - // Print checks and results. +// prettyPrint outputs the results to stdout in human-readable format +func prettyPrint(warnings []string, r *check.Controls, summary check.Summary) { + for _, w := range warnings { + colorPrint(check.WARN, w) + } + colorPrint(check.INFO, fmt.Sprintf("%s %s\n", r.ID, r.Text)) for _, g := range r.Groups { colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text)) From 07750ea43a89ab9e71ae82cf8ba6f854e600646e Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 23 Jun 2017 10:48:49 +0100 Subject: [PATCH 5/5] Don't output message about config file if output format is JSON --- cmd/common.go | 2 ++ cmd/root.go | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index a296999..63940d4 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -225,6 +225,8 @@ func colorPrint(state check.State, s string) { // prettyPrint outputs the results to stdout in human-readable format func prettyPrint(warnings []string, r *check.Controls, summary check.Summary) { + colorPrint(check.INFO, fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed())) + for _, w := range warnings { colorPrint(check.WARN, w) } diff --git a/cmd/root.go b/cmd/root.go index 2506c54..b1c5bc4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -96,9 +96,7 @@ func initConfig() { viper.SetDefault("federatedFile", cfgDir+"/federated.yaml") // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - colorPrint(check.INFO, fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed())) - } else { + if err := viper.ReadInConfig(); err != nil { colorPrint(check.FAIL, fmt.Sprintf("Failed to read config file: %v\n", err)) os.Exit(1) }