-
-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
all: setup initial project and a first test for pods and deployments
- Loading branch information
0 parents
commit d99c77b
Showing
8 changed files
with
325 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module github.com/zegl/kube-score | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/ghodss/yaml v1.0.0 // indirect | ||
github.com/gogo/protobuf v1.1.1 // indirect | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect | ||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect | ||
github.com/ikgo/gocode v0.0.0-20180912135031-6e257e1c6842 // indirect | ||
github.com/json-iterator/go v1.1.5 // indirect | ||
github.com/labstack/echo v3.2.1+incompatible // indirect | ||
github.com/labstack/gommon v0.2.7 // indirect | ||
github.com/mattn/go-colorable v0.0.9 // indirect | ||
github.com/mattn/go-isatty v0.0.4 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/stretchr/testify v1.2.2 | ||
github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 // indirect | ||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b // indirect | ||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3 // indirect | ||
golang.org/x/text v0.3.0 // indirect | ||
gopkg.in/inf.v0 v0.9.1 // indirect | ||
gopkg.in/yaml.v2 v2.2.0 | ||
k8s.io/api v0.0.0-20180913155108-f456898a08e4 | ||
k8s.io/apimachinery v0.0.0-20180912233634-99c5fa21f872 | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= | ||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= | ||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= | ||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= | ||
github.com/ikgo/gocode v0.0.0-20180912135031-6e257e1c6842 h1:xEjS0/c3SJtqJZgoxJsB89FKwaYfWEgowP09Uf635dY= | ||
github.com/ikgo/gocode v0.0.0-20180912135031-6e257e1c6842/go.mod h1:/vQ5DCTq0XUco6jXwdF04kI1ek0jqRrI8YtYY1VJ+sY= | ||
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= | ||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||
github.com/labstack/echo v3.2.1+incompatible h1:J2M7YArHx4gi8p/3fDw8tX19SXhBCoRpviyAZSN3I88= | ||
github.com/labstack/echo v3.2.1+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= | ||
github.com/labstack/gommon v0.2.7 h1:2qOPq/twXDrQ6ooBGrn3mrmVOC+biLlatwgIu8lbzRM= | ||
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4= | ||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= | ||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= | ||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= | ||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | ||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8= | ||
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw= | ||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ= | ||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3 h1:czFLhve3vsQetD6JOJ8NZZvGQIXlnN3/yXxbT6/awxI= | ||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/tools v0.0.0-20180831211245-7ca132754999 h1:mf2VYfMpSMTlp0I/UXrX13w5LejDx34QeUUHH4TrUA8= | ||
golang.org/x/tools v0.0.0-20180831211245-7ca132754999/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= | ||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= | ||
gopkg.in/yaml.v2 v2.0.0 h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs= | ||
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | ||
gopkg.in/yaml.v2 v2.2.0 h1:ucE2Go3MGv/WipgucyA7X3+4pRLSbl5sd8WaEs60obQ= | ||
gopkg.in/yaml.v2 v2.2.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= | ||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
k8s.io/api v0.0.0-20180913155108-f456898a08e4 h1:ULsewO4HnVexbLMSexmlht7KBZgsrSHaFCiekvs+1eg= | ||
k8s.io/api v0.0.0-20180913155108-f456898a08e4/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= | ||
k8s.io/apimachinery v0.0.0-20180912233634-99c5fa21f872 h1:gCsLgEftNQkx/C6l4elbT4r/wrwU2M76IPhRQYuohWY= | ||
k8s.io/apimachinery v0.0.0-20180912233634-99c5fa21f872/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package score | ||
|
||
import ( | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
|
||
"gopkg.in/yaml.v2" | ||
|
||
//"errors" | ||
//"fmt" | ||
// "github.com/labstack/echo" | ||
// "k8s.io/api/admission/v1beta1" | ||
appsv1 "k8s.io/api/apps/v1" | ||
// batchv1 "k8s.io/api/batch/v1" | ||
// batchv1beta1 "k8s.io/api/batch/v1beta1" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/runtime/serializer" | ||
// "reflect" | ||
) | ||
|
||
var scheme = runtime.NewScheme() | ||
var codecs = serializer.NewCodecFactory(scheme) | ||
|
||
func init() { | ||
addToScheme(scheme) | ||
} | ||
|
||
func addToScheme(scheme *runtime.Scheme) { | ||
corev1.AddToScheme(scheme) | ||
appsv1.AddToScheme(scheme) | ||
// batchv1.AddToScheme(scheme) | ||
// batchv1beta1.AddToScheme(scheme) | ||
// v1beta1.AddToScheme(scheme) | ||
} | ||
|
||
type Scorecard struct { | ||
Scores []TestScore | ||
} | ||
|
||
type TestScore struct { | ||
Name string | ||
Description string | ||
Grade int | ||
Comments []string | ||
} | ||
|
||
func Score(file io.Reader) (*Scorecard, error) { | ||
allData, err := ioutil.ReadAll(file) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
type detectKind struct { | ||
Kind string `yaml:"kind"` | ||
} | ||
|
||
var detect detectKind | ||
err = yaml.Unmarshal(allData, &detect) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var pods []corev1.Pod | ||
var deployments []appsv1.Deployment | ||
|
||
decode := func(data []byte, object runtime.Object) { | ||
deserializer := codecs.UniversalDeserializer() | ||
if _, _, err := deserializer.Decode(data, nil, object); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
switch detect.Kind { | ||
case "Pod": | ||
var pod corev1.Pod | ||
decode(allData, &pod) | ||
pods = append(pods, pod) | ||
|
||
case "Deployment": | ||
var deployment appsv1.Deployment | ||
decode(allData, &deployment) | ||
deployments = append(deployments, deployment) | ||
} | ||
|
||
podTests := []func(corev1.PodSpec) TestScore{ | ||
scoreContainerLimits, | ||
} | ||
|
||
scoreCard := Scorecard{} | ||
|
||
for _, pod := range pods { | ||
for _, podTest := range podTests { | ||
scoreCard.Scores = append(scoreCard.Scores, podTest(pod.Spec)) | ||
} | ||
} | ||
|
||
for _, deployment := range deployments { | ||
for _, podTest := range podTests { | ||
scoreCard.Scores = append(scoreCard.Scores, podTest(deployment.Spec.Template.Spec)) | ||
} | ||
} | ||
|
||
return &scoreCard, nil | ||
} | ||
|
||
func scoreContainerLimits(pod corev1.PodSpec) (score TestScore) { | ||
score.Name = "Container Resources" | ||
|
||
allContainers := pod.InitContainers | ||
allContainers = append(allContainers, pod.Containers...) | ||
|
||
hasMissingLimit := false | ||
hasMissingRequest := false | ||
|
||
for _, container := range allContainers { | ||
if container.Resources.Limits.Cpu().IsZero() { | ||
score.Comments = append(score.Comments, "CPU limit is not set") | ||
hasMissingLimit = true | ||
} | ||
if container.Resources.Limits.Memory().IsZero() { | ||
score.Comments = append(score.Comments, "Memory limit is not set") | ||
hasMissingLimit = true | ||
} | ||
if container.Resources.Requests.Cpu().IsZero() { | ||
score.Comments = append(score.Comments, "CPU request is not set") | ||
hasMissingRequest = true | ||
} | ||
if container.Resources.Requests.Memory().IsZero() { | ||
score.Comments = append(score.Comments, "Memory request is not set") | ||
hasMissingRequest = true | ||
} | ||
} | ||
|
||
if len(allContainers) == 0 { | ||
score.Grade = 0 | ||
score.Comments = append(score.Comments, "No containers defined") | ||
} else if hasMissingLimit { | ||
score.Grade = 0 | ||
} else if hasMissingRequest { | ||
score.Grade = 5 | ||
} else { | ||
score.Grade = 10 | ||
} | ||
|
||
return | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package score | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func testFile(name string) *os.File { | ||
fp, err := os.Open("testdata/" + name) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return fp | ||
} | ||
|
||
func testExpectedScore(t *testing.T, filename string, testcase string, expectedScore int) { | ||
sc, err := Score(testFile(filename)) | ||
assert.NoError(t, err) | ||
tested := false | ||
for _, s := range sc.Scores { | ||
if s.Name == testcase { | ||
assert.Equal(t, expectedScore, s.Grade) | ||
tested = true | ||
} | ||
} | ||
assert.True(t, tested, "Was not tested") | ||
} | ||
|
||
func TestPodContainerNoResources(t *testing.T) { | ||
testExpectedScore(t, "pod-test-resources-none.yaml", "Container Resources", 0) | ||
} | ||
|
||
func TestPodContainerResourceLimits(t *testing.T) { | ||
testExpectedScore(t, "pod-test-resources-only-limits.yaml", "Container Resources", 5) | ||
} | ||
|
||
func TestPodContainerResourceLimitsAndRequests(t *testing.T) { | ||
testExpectedScore(t, "pod-test-resources-limits-and-requests.yaml", "Container Resources", 10) | ||
} | ||
|
||
func TestDeploymentResources(t *testing.T) { | ||
testExpectedScore(t, "deployment-test-resources.yaml", "Container Resources", 5) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: deployment-test-1 | ||
spec: | ||
template: | ||
spec: | ||
containers: | ||
- name: foobar | ||
image: foo/bar:123 | ||
resources: | ||
limits: | ||
cpu: 200m | ||
memory: 1Gi | ||
|
15 changes: 15 additions & 0 deletions
15
score/testdata/pod-test-resources-limits-and-requests.yaml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: pod-test-1 | ||
spec: | ||
containers: | ||
- name: foobar | ||
image: foo/bar:123 | ||
resources: | ||
limits: | ||
cpu: 200m | ||
memory: 1Gi | ||
requests: | ||
cpu: 200m | ||
memory: 1Gi |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: pod-test-1 | ||
spec: | ||
containers: | ||
- name: foobar | ||
image: foo/bar:123 |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: pod-test-1 | ||
spec: | ||
containers: | ||
- name: foobar | ||
image: foo/bar:123 | ||
resources: | ||
limits: | ||
cpu: 200m | ||
memory: 1Gi |