Repository: zegl/kube-score
Pull request #123 (2019-04-28 12:39:16)

doc: update kube-score usage in the README
The output is generated by 'kube-score score --help'


Patch:
diff --git a/README.md b/README.md
index 67b318c..bb93c61 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ The input to `kube-score` should be all applications that you deploy to the same
 helm template my-app | kube-score score -
 ```
 
-### Example with static yamls
+### Example with static YAMLs
 
 ```bash
 kube-score score my-app/*.yaml
@@ -60,18 +60,21 @@ Usage of kube-score:
 kube-score [action] --flags
 
 Actions:
-	score 	Checks all files in the input, and gives them a score and recommendations
-	list	Prints a cvs list of all available score checks
+	score	Checks all files in the input, and gives them a score and recommendations
+	list	Prints a CSV list of all available score checks
+	version	Print the version of kube-score
+	help	Print this message
 
 Flags for score:
-      --exit-one-on-warning          Exit with code 1 in case of warnings
-      --help                         Print help
-      --ignore-container-cpu-limit   Disables the requirement of setting a container CPU limit
-      --ignore-test strings          Disable a test, can be set multiple times
-      --output-format string         Set to 'human' or 'ci'. If set to ci, kube-score will output the program in a format that is easier to parse by other programs. (default "human")
-      --threshold-ok int             The score threshold for treating an score as OK. Must be between 1 and 10 (inclusive). Scores graded below this threshold are WARNING or CRITICAL. (default 10)
-      --threshold-warning int        The score threshold for treating a score as WARNING. Grades below this threshold are CRITICAL. Must be between 1 and 10 (inclusive). (default 5)
-      --v                            Verbose output
+      --exit-one-on-warning             Exit with code 1 in case of warnings
+      --help                            Print help
+      --ignore-container-cpu-limit      Disables the requirement of setting a container CPU limit
+      --ignore-container-memory-limit   Disables the requirement of setting a container memory limit
+      --ignore-test strings             Disable a test, can be set multiple times
+      --output-format string            Set to 'human' or 'ci'. If set to ci, kube-score will output the program in a format that is easier to parse by other programs. (default "human")
+      --threshold-ok int                The score threshold for treating an score as OK. Must be between 1 and 10 (inclusive). Scores graded below this threshold are WARNING or CRITICAL. (default 10)
+      --threshold-warning int           The score threshold for treating a score as WARNING. Grades below this threshold are CRITICAL. Must be between 1 and 10 (inclusive). (default 5)
+      --v                               Verbose output
 ```
 
 ### Ignoring a test
diff --git a/cmd/kube-score/main.go b/cmd/kube-score/main.go
index 3d25e06..e0883b6 100644
--- a/cmd/kube-score/main.go
+++ b/cmd/kube-score/main.go
@@ -140,12 +140,12 @@ Use "-" as filename to read from STDIN.`)
 
 	parsedFiles, err := parser.ParseFiles(cnf)
 	if err != nil {
-		return err
+		panic(err)
 	}
 
 	scoreCard, err := score.Score(parsedFiles, cnf)
 	if err != nil {
-		return err
+		panic(err)
 	}
 
 	ignoredTests := make(map[string]struct{})
@@ -159,7 +159,7 @@ Use "-" as filename to read from STDIN.`)
 	// Detect which output format we should use
 	humanOutput := *outputFormat == "human"
 
-	for _, scoredObject := range *scoreCard {
+	for _, scoredObject := range scoreCard {
 		// Headers for each object
 		if humanOutput {
 			color.New(color.FgMagenta).Printf("%s/%s %s", scoredObject.TypeMeta.APIVersion, scoredObject.TypeMeta.Kind, scoredObject.ObjectMeta.Name)
diff --git a/score/apps/apps.go b/score/apps/apps.go
index c47ea85..11078fa 100644
--- a/score/apps/apps.go
+++ b/score/apps/apps.go
@@ -14,7 +14,7 @@ func Register(allChecks *checks.Checks) {
 	allChecks.RegisterStatefulSetCheck("StatefulSet has host PodAntiAffinity", "Makes sure that a podAntiAffinity has been set that prevents multiple pods from being scheduled on the same node. https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", statefulsetHasAntiAffinity)
 }
 
-func deploymentHasAntiAffinity(deployment appsv1.Deployment) (score scorecard.TestScore, err error) {
+func deploymentHasAntiAffinity(deployment appsv1.Deployment) (score scorecard.TestScore) {
 	// Ignore if the deployment only has a single replica
 	// If replicas is not explicitly set, we'll still warn if the anti affinity is missing
 	// as that might indicate use of a Horizontal Pod Autoscaler
@@ -46,7 +46,7 @@ func deploymentHasAntiAffinity(deployment appsv1.Deployment) (score scorecard.Te
 	return
 }
 
-func statefulsetHasAntiAffinity(statefulset appsv1.StatefulSet) (score scorecard.TestScore, err error) {
+func statefulsetHasAntiAffinity(statefulset appsv1.StatefulSet) (score scorecard.TestScore) {
 	// Ignore if the statefulset only has a single replica
 	// If replicas is not explicitly set, we'll still warn if the anti affinity is missing
 	// as that might indicate use of a Horizontal Pod Autoscaler
diff --git a/score/checks/checks.go b/score/checks/checks.go
index 1b2a05f..9d5e03f 100644
--- a/score/checks/checks.go
+++ b/score/checks/checks.go
@@ -59,12 +59,12 @@ type ServiceCheck struct {
 
 type StatefulSetCheck struct {
 	ks.Check
-	Fn func(appsv1.StatefulSet) (scorecard.TestScore, error)
+	Fn func(appsv1.StatefulSet) scorecard.TestScore
 }
 
 type DeploymentCheck struct {
 	ks.Check
-	Fn func(appsv1.Deployment) (scorecard.TestScore, error)
+	Fn func(appsv1.Deployment) scorecard.TestScore
 }
 
 type NetworkPolicyCheck struct {
@@ -124,7 +124,7 @@ func (c *Checks) CronJobs() map[string]CronJobCheck {
 	return c.cronjobs
 }
 
-func (c *Checks) RegisterStatefulSetCheck(name, comment string, fn func(appsv1.StatefulSet) (scorecard.TestScore, error)) {
+func (c *Checks) RegisterStatefulSetCheck(name, comment string, fn func(appsv1.StatefulSet) scorecard.TestScore) {
 	ch := NewCheck(name, "StatefulSet", comment)
 	c.all = append(c.all, ch)
 	c.statefulsets[machineFriendlyName(name)] = StatefulSetCheck{ch, fn}
@@ -134,7 +134,7 @@ func (c *Checks) StatefulSets() map[string]StatefulSetCheck {
 	return c.statefulsets
 }
 
-func (c *Checks) RegisterDeploymentCheck(name, comment string, fn func(appsv1.Deployment) (scorecard.TestScore, error)) {
+func (c *Checks) RegisterDeploymentCheck(name, comment string, fn func(appsv1.Deployment) scorecard.TestScore) {
 	ch := NewCheck(name, "Deployment", comment)
 	c.all = append(c.all, ch)
 	c.deployments[machineFriendlyName(name)] = DeploymentCheck{ch, fn}
diff --git a/score/disruptionbudget/disruptionbudget.go b/score/disruptionbudget/disruptionbudget.go
index 9ec1fd6..4ed68a9 100644
--- a/score/disruptionbudget/disruptionbudget.go
+++ b/score/disruptionbudget/disruptionbudget.go
@@ -1,8 +1,6 @@
 package disruptionbudget
 
 import (
-	"fmt"
-
 	ks "github.com/zegl/kube-score/domain"
 	"github.com/zegl/kube-score/score/checks"
 	"github.com/zegl/kube-score/score/internal"
@@ -18,7 +16,7 @@ func Register(allChecks *checks.Checks, budgets ks.PodDisruptionBudgets) {
 	allChecks.RegisterDeploymentCheck("Deployment has PodDisruptionBudget", `Makes sure that all Deployments are targeted by a PDB`, deploymentHas(budgets.PodDisruptionBudgets()))
 }
 
-func hasMatching(budgets []policyv1beta1.PodDisruptionBudget, namespace string, lables map[string]string) (bool, error) {
+func hasMatching(budgets []policyv1beta1.PodDisruptionBudget, namespace string, lables map[string]string) bool {
 	for _, budget := range budgets {
 		if budget.Namespace != namespace {
 			continue
@@ -26,32 +24,26 @@ func hasMatching(budgets []policyv1beta1.PodDisruptionBudget, namespace string,
 
 		selector, err := metav1.LabelSelectorAsSelector(budget.Spec.Selector)
 		if err != nil {
-			return false, fmt.Errorf("failed to create selector: %v", err)
+			panic(err)
 		}
 
 		if selector.Matches(internal.MapLables(lables)) {
-			return true, nil
+			return true
 		}
 	}
 
-	return false, nil
+	return false
 }
 
-func statefulSetHas(budgets []policyv1beta1.PodDisruptionBudget) func(appsv1.StatefulSet) (scorecard.TestScore, error) {
-	return func(statefulset appsv1.StatefulSet) (score scorecard.TestScore, err error) {
+func statefulSetHas(budgets []policyv1beta1.PodDisruptionBudget) func(appsv1.StatefulSet) scorecard.TestScore {
+	return func(statefulset appsv1.StatefulSet) (score scorecard.TestScore) {
 		if statefulset.Spec.Replicas != nil && *statefulset.Spec.Replicas < 2 {
 			score.Grade = scorecard.GradeAllOK
 			score.AddComment("", "Skipped", "Skipped because the statefulset has less than 2 replicas")
 			return
 		}
 
-		match, matchErr := hasMatching(budgets, statefulset.Namespace, statefulset.Spec.Template.Labels)
-		if matchErr != nil {
-			err = matchErr
-			return
-		}
-
-		if match {
+		if hasMatching(budgets, statefulset.Namespace, statefulset.Spec.Template.Labels) {
 			score.Grade = scorecard.GradeAllOK
 		} else {
 			score.Grade = scorecard.GradeCritical
@@ -62,21 +54,15 @@ func statefulSetHas(budgets []policyv1beta1.PodDisruptionBudget) func(appsv1.Sta
 	}
 }
 
-func deploymentHas(budgets []policyv1beta1.PodDisruptionBudget) func(appsv1.Deployment) (scorecard.TestScore, error) {
-	return func(deployment appsv1.Deployment) (score scorecard.TestScore, err error) {
+func deploymentHas(budgets []policyv1beta1.PodDisruptionBudget) func(appsv1.Deployment) scorecard.TestScore {
+	return func(deployment appsv1.Deployment) (score scorecard.TestScore) {
 		if deployment.Spec.Replicas != nil && *deployment.Spec.Replicas < 2 {
 			score.Grade = scorecard.GradeAllOK
 			score.AddComment("", "Skipped", "Skipped because the deployment has less than 2 replicas")
 			return
 		}
 
-		match, matchErr := hasMatching(budgets, deployment.Namespace, deployment.Spec.Template.Labels)
-		if matchErr != nil {
-			err = matchErr
-			return
-		}
-
-		if match {
+		if hasMatching(budgets, deployment.Namespace, deployment.Spec.Template.Labels) {
 			score.Grade = scorecard.GradeAllOK
 		} else {
 			score.Grade = scorecard.GradeCritical
diff --git a/score/score.go b/score/score.go
index a068d24..6d7b431 100644
--- a/score/score.go
+++ b/score/score.go
@@ -38,7 +38,7 @@ func RegisterAllChecks(allObjects ks.AllTypes, cnf config.Configuration) *checks
 
 // Score runs a pre-configured list of tests against the files defined in the configuration, and returns a scorecard.
 // Additional configuration and tuning parameters can be provided via the config.
-func Score(allObjects ks.AllTypes, cnf config.Configuration) (*scorecard.Scorecard, error) {
+func Score(allObjects ks.AllTypes, cnf config.Configuration) (scorecard.Scorecard, error) {
 	allChecks := RegisterAllChecks(allObjects, cnf)
 	scoreCard := scorecard.New()
 
@@ -85,22 +85,14 @@ func Score(allObjects ks.AllTypes, cnf config.Configuration) (*scorecard.Scoreca
 	for _, statefulset := range allObjects.StatefulSets() {
 		o := scoreCard.NewObject(statefulset.TypeMeta, statefulset.ObjectMeta)
 		for _, test := range allChecks.StatefulSets() {
-			res, err := test.Fn(statefulset)
-			if err != nil {
-				return nil, err
-			}
-			o.Add(res, test.Check)
+			o.Add(test.Fn(statefulset), test.Check)
 		}
 	}
 
 	for _, deployment := range allObjects.Deployments() {
 		o := scoreCard.NewObject(deployment.TypeMeta, deployment.ObjectMeta)
 		for _, test := range allChecks.Deployments() {
-			res, err := test.Fn(deployment)
-			if err != nil {
-				return nil, err
-			}
-			o.Add(res, test.Check)
+			o.Add(test.Fn(deployment), test.Check)
 		}
 	}
 
@@ -118,5 +110,5 @@ func Score(allObjects ks.AllTypes, cnf config.Configuration) (*scorecard.Scoreca
 		}
 	}
 
-	return &scoreCard, nil
+	return scoreCard, nil
 }


Test patch:
diff --git a/score/apps/apps_test.go b/score/apps/apps_test.go
index 2d5cede..f870164 100644
--- a/score/apps/apps_test.go
+++ b/score/apps/apps_test.go
@@ -113,8 +113,7 @@ func TestStatefulsetHasAntiAffinity(t *testing.T) {
 			},
 		}
 
-		score, err := statefulsetHasAntiAffinity(s)
-		assert.Nil(t, err)
+		score := statefulsetHasAntiAffinity(s)
 		assert.Equal(t, tc.expectedGrade, score.Grade, "caseID=%d", caseID)
 	}
 }
@@ -137,8 +136,7 @@ func TestDeploymentHasAntiAffinity(t *testing.T) {
 			},
 		}
 
-		score, err := deploymentHasAntiAffinity(s)
-		assert.Nil(t, err)
+		score := deploymentHasAntiAffinity(s)
 		assert.Equal(t, tc.expectedGrade, score.Grade, "caseID=%d", caseID)
 	}
 }
diff --git a/score/disruptionbudget/disruptionbudget_test.go b/score/disruptionbudget/disruptionbudget_test.go
index e033d43..7fe7bb0 100644
--- a/score/disruptionbudget/disruptionbudget_test.go
+++ b/score/disruptionbudget/disruptionbudget_test.go
@@ -17,8 +17,7 @@ func TestStatefulSetReplicas(t *testing.T) {
 	fn := statefulSetHas(nil)
 
 	for replicas, expected := range cases {
-		res, err := fn(appsv1.StatefulSet{Spec: appsv1.StatefulSetSpec{Replicas: replicas}})
-		assert.Nil(t, err)
+		res := fn(appsv1.StatefulSet{Spec: appsv1.StatefulSetSpec{Replicas: replicas}})
 
 		if replicas == nil {
 			assert.Equal(t, expected, res.Grade, "replicas=nil")
@@ -38,8 +37,7 @@ func TestDeploymentReplicas(t *testing.T) {
 	fn := deploymentHas(nil)
 
 	for replicas, expected := range cases {
-		res, err := fn(appsv1.Deployment{Spec: appsv1.DeploymentSpec{Replicas: replicas}})
-		assert.Nil(t, err)
+		res := fn(appsv1.Deployment{Spec: appsv1.DeploymentSpec{Replicas: replicas}})
 
 		if replicas == nil {
 			assert.Equal(t, expected, res.Grade, "replicas=nil")
diff --git a/score/score_test.go b/score/score_test.go
index 8609dc1..24bdd2c 100644
--- a/score/score_test.go
+++ b/score/score_test.go
@@ -45,12 +45,7 @@ func testScore(config config.Configuration) (scorecard.Scorecard, error) {
 		return nil, err
 	}
 
-	card, err := Score(parsed, config)
-	if err != nil {
-		return nil, err
-	}
-
-	return *card, err
+	return Score(parsed, config)
 }
 
 func testExpectedScore(t *testing.T, filename string, testcase string, expectedScore scorecard.Grade) []scorecard.TestScoreComment {