Repository: zegl/kube-score
Pull request #111 (2019-04-25 14:58:30)

allow for ignoring memory limits
#107

codecov[bot]: # [Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=h1) Report
> Merging [#111](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=desc) into [master](https://codecov.io/gh/zegl/kube-score/commit/4a634587eb05d68ca0ff842299cc3382d19294be?src=pr&el=desc) will **decrease** coverage by `0.16%`.
> The diff coverage is `37.5%`.

[![Impacted file tree graph](https://codecov.io/gh/zegl/kube-score/pull/111/graphs/tree.svg?width=650&token=6cR05TgI8D&height=150&src=pr)](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #111      +/-   ##
==========================================
- Coverage   79.45%   79.29%   -0.17%     
==========================================
  Files          20       20              
  Lines         959      961       +2     
==========================================
  Hits          762      762              
- Misses        183      185       +2     
  Partials       14       14
```


| [Impacted Files](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/kube-score/main.go](https://codecov.io/gh/zegl/kube-score/pull/111/diff?src=pr&el=tree#diff-Y21kL2t1YmUtc2NvcmUvbWFpbi5nbw==) | `0% <0%> (ø)` | :arrow_up: |
| [score/container/container.go](https://codecov.io/gh/zegl/kube-score/pull/111/diff?src=pr&el=tree#diff-c2NvcmUvY29udGFpbmVyL2NvbnRhaW5lci5nbw==) | `94.11% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=footer). Last update [4a63458...d0180a2](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

codecov[bot]: # [Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=h1) Report
> Merging [#111](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=desc) into [master](https://codecov.io/gh/zegl/kube-score/commit/4a634587eb05d68ca0ff842299cc3382d19294be?src=pr&el=desc) will **decrease** coverage by `0.16%`.
> The diff coverage is `37.5%`.

[![Impacted file tree graph](https://codecov.io/gh/zegl/kube-score/pull/111/graphs/tree.svg?width=650&token=6cR05TgI8D&height=150&src=pr)](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #111      +/-   ##
==========================================
- Coverage   79.45%   79.29%   -0.17%     
==========================================
  Files          20       20              
  Lines         959      961       +2     
==========================================
  Hits          762      762              
- Misses        183      185       +2     
  Partials       14       14
```


| [Impacted Files](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/kube-score/main.go](https://codecov.io/gh/zegl/kube-score/pull/111/diff?src=pr&el=tree#diff-Y21kL2t1YmUtc2NvcmUvbWFpbi5nbw==) | `0% <0%> (ø)` | :arrow_up: |
| [score/container/container.go](https://codecov.io/gh/zegl/kube-score/pull/111/diff?src=pr&el=tree#diff-c2NvcmUvY29udGFpbmVyL2NvbnRhaW5lci5nbw==) | `94.11% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=footer). Last update [4a63458...d0180a2](https://codecov.io/gh/zegl/kube-score/pull/111?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

zegl: This PR has a conflict in `score/container/container.go`,  can you rebase and resolve the conflict? Thanks.

Patch:
diff --git a/cmd/kube-score/main.go b/cmd/kube-score/main.go
index 0ac73fe..e0883b6 100644
--- a/cmd/kube-score/main.go
+++ b/cmd/kube-score/main.go
@@ -3,11 +3,12 @@ package main
 import (
 	"encoding/csv"
 	"fmt"
-	"github.com/fatih/color"
-	flag "github.com/spf13/pflag"
 	"io"
 	"os"
 
+	"github.com/fatih/color"
+	flag "github.com/spf13/pflag"
+
 	"github.com/zegl/kube-score/config"
 	"github.com/zegl/kube-score/parser"
 	"github.com/zegl/kube-score/score"
@@ -73,6 +74,7 @@ func scoreFiles() error {
 	fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
 	exitOneOnWarning := fs.Bool("exit-one-on-warning", false, "Exit with code 1 in case of warnings")
 	ignoreContainerCpuLimit := fs.Bool("ignore-container-cpu-limit", false, "Disables the requirement of setting a container CPU limit")
+	ignoreContainerMemoryLimit := fs.Bool("ignore-container-memory-limit", false, "Disables the requirement of setting a container memory limit")
 	okThreshold := fs.Int("threshold-ok", 10, "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.")
 	warningThreshold := fs.Int("threshold-warning", 5, "The score threshold for treating a score as WARNING. Grades below this threshold are CRITICAL. Must be between 1 and 10 (inclusive).")
 	verboseOutput := fs.Bool("v", false, "Verbose output")
@@ -130,9 +132,10 @@ Use "-" as filename to read from STDIN.`)
 	}
 
 	cnf := config.Configuration{
-		AllFiles:                           allFilePointers,
-		VerboseOutput:                      *verboseOutput,
-		IgnoreContainerCpuLimitRequirement: *ignoreContainerCpuLimit,
+		AllFiles:                              allFilePointers,
+		VerboseOutput:                         *verboseOutput,
+		IgnoreContainerCpuLimitRequirement:    *ignoreContainerCpuLimit,
+		IgnoreContainerMemoryLimitRequirement: *ignoreContainerMemoryLimit,
 	}
 
 	parsedFiles, err := parser.ParseFiles(cnf)
diff --git a/config/config.go b/config/config.go
index 27c9284..359f662 100644
--- a/config/config.go
+++ b/config/config.go
@@ -3,7 +3,8 @@ package config
 import "io"
 
 type Configuration struct {
-	AllFiles                           []io.Reader
-	VerboseOutput                      bool
-	IgnoreContainerCpuLimitRequirement bool
+	AllFiles                              []io.Reader
+	VerboseOutput                         bool
+	IgnoreContainerCpuLimitRequirement    bool
+	IgnoreContainerMemoryLimitRequirement bool
 }
diff --git a/score/container/container.go b/score/container/container.go
index a754450..2535ab8 100644
--- a/score/container/container.go
+++ b/score/container/container.go
@@ -11,14 +11,14 @@ import (
 )
 
 func Register(allChecks *checks.Checks, cnf config.Configuration) {
-	allChecks.RegisterPodCheck("Container Resources", `Makes sure that all pods have resource limits and requests set. The --ignore-container-cpu-limit flag can be used to disable the requirement of having a CPU limit`, containerResources(!cnf.IgnoreContainerCpuLimitRequirement))
+	allChecks.RegisterPodCheck("Container Resources", `Makes sure that all pods have resource limits and requests set. The --ignore-container-cpu-limit flag can be used to disable the requirement of having a CPU limit`, containerResources(!cnf.IgnoreContainerCpuLimitRequirement, !cnf.IgnoreContainerMemoryLimitRequirement))
 	allChecks.RegisterPodCheck("Container Image Tag", `Makes sure that a explicit non-latest tag is used`, containerImageTag)
 	allChecks.RegisterPodCheck("Container Image Pull Policy", `Makes sure that the pullPolicy is set to Always. This makes sure that imagePullSecrets are always validated.`, containerImagePullPolicy)
 }
 
 // containerResources makes sure that the container has resource requests and limits set
 // The check for a CPU limit requirement can be enabled via the requireCPULimit flag parameter
-func containerResources(requireCPULimit bool) func(corev1.PodTemplateSpec, metav1.TypeMeta) scorecard.TestScore {
+func containerResources(requireCPULimit bool, requireMemoryLimit bool) func(corev1.PodTemplateSpec, metav1.TypeMeta) scorecard.TestScore {
 	return func(podTemplate corev1.PodTemplateSpec, typeMeta metav1.TypeMeta) (score scorecard.TestScore) {
 		pod := podTemplate.Spec
 
@@ -33,7 +33,7 @@ func containerResources(requireCPULimit bool) func(corev1.PodTemplateSpec, metav
 				score.AddComment(container.Name, "CPU limit is not set", "Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu")
 				hasMissingLimit = true
 			}
-			if container.Resources.Limits.Memory().IsZero() {
+			if container.Resources.Limits.Memory().IsZero() && requireMemoryLimit {
 				score.AddComment(container.Name, "Memory limit is not set", "Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory")
 				hasMissingLimit = true
 			}


Test patch:
diff --git a/score/score_test.go b/score/score_test.go
index ca0c2da..24bdd2c 100644
--- a/score/score_test.go
+++ b/score/score_test.go
@@ -90,6 +90,14 @@ func TestPodContainerResourceLimitCpuRequired(t *testing.T) {
 	}, "Container Resources", 1)
 }
 
+func TestPodContainerResourceNoLimitRequired(t *testing.T) {
+	testExpectedScoreWithConfig(t, config.Configuration{
+		IgnoreContainerCpuLimitRequirement:    true,
+		IgnoreContainerMemoryLimitRequirement: true,
+		AllFiles:                              []io.Reader{testFile("pod-test-resources-no-limits.yaml")},
+	}, "Container Resources", 10)
+}
+
 func TestDeploymentResources(t *testing.T) {
 	testExpectedScore(t, "deployment-test-resources.yaml", "Container Resources", 5)
 }
diff --git a/score/testdata/pod-test-resources-no-limits.yaml b/score/testdata/pod-test-resources-no-limits.yaml
new file mode 100644
index 0000000..171ae9b
--- /dev/null
+++ b/score/testdata/pod-test-resources-no-limits.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:123
+    resources:
+      requests:
+        cpu: 200m
+        memory: 1Gi