Skip to content

Commit

Permalink
a lot of cleanup and restructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
robscott committed Mar 28, 2019
1 parent 4c6d546 commit f5cde2d
Show file tree
Hide file tree
Showing 15 changed files with 338 additions and 289 deletions.
20 changes: 10 additions & 10 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ resources:
below: 100M
above: 4G
images:
tagNotSpecified: 'error'
pullPolicyNotAlways: 'warning'
error:
whitelist:
tagNotSpecified: error
pullPolicyNotAlways: warning
whitelist:
error:
- gcr.io/*
warning:
blacklist:
blacklist:
warning:
- docker.io/*
healthChecks:
readinessProbeMissing: warning
Expand All @@ -54,13 +54,13 @@ security:
notReadOnlyRootFileSystem: warning
runAsNonRoot: warning
capabilities:
warning:
blacklist:
blacklist:
error:
- CHOWN
- SYS_CHROOT
- AUDIT_WRITE
error:
whitelist:
whitelist:
warning:
- CHOWN
- DAC_OVERRIDE
- FSETID
Expand Down
20 changes: 10 additions & 10 deletions deploy/all.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ data:
below: 100M
above: 4G
images:
tagNotSpecified: 'error'
pullPolicyNotAlways: 'warning'
error:
whitelist:
tagNotSpecified: error
pullPolicyNotAlways: warning
whitelist:
error:
- gcr.io/*
warning:
blacklist:
blacklist:
warning:
- docker.io/*
healthChecks:
readinessProbeMissing: warning
Expand All @@ -131,13 +131,13 @@ data:
notReadOnlyRootFileSystem: warning
runAsNonRoot: warning
capabilities:
warning:
blacklist:
blacklist:
error:
- CHOWN
- SYS_CHROOT
- AUDIT_WRITE
error:
whitelist:
whitelist:
warning:
- CHOWN
- DAC_OVERRIDE
- FSETID
Expand Down
25 changes: 10 additions & 15 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,16 @@ type HealthChecks struct {

// Images contains the config for images.
type Images struct {
TagNotSpecified Severity `json:"tagNotSpecified"`
PullPolicyNotAlways Severity `json:"pullPolicyNotAlways"`
Repositories Repositories `json:"repositories"`
TagNotSpecified Severity `json:"tagNotSpecified"`
PullPolicyNotAlways Severity `json:"pullPolicyNotAlways"`
Whitelist ErrorWarningLists `json:"whitelist"`
Blacklist ErrorWarningLists `json:"blacklist"`
}

// Repositories provides lists of patterns to match or avoid in image tags.
type Repositories struct {
Error WhitelistBlacklist `json:"error"`
Warning WhitelistBlacklist `json:"warning"`
}

// WhitelistBlacklist can contain a whitelist or blacklist.
type WhitelistBlacklist struct {
Whitelist []string `json:"whitelist"`
Blacklist []string `json:"blacklist"`
// ErrorWarningLists provides lists of patterns to match or avoid in image tags.
type ErrorWarningLists struct {
Error []string `json:"error"`
Warning []string `json:"warning"`
}

// Networking contains the config for networking validations.
Expand All @@ -101,8 +96,8 @@ type Security struct {

// SecurityCapabilities contains the config for security capabilities validations.
type SecurityCapabilities struct {
Error WhitelistBlacklist `json:"error"`
Warning WhitelistBlacklist `json:"warning"`
Whitelist ErrorWarningLists `json:"whitelist"`
Blacklist ErrorWarningLists `json:"blacklist"`
}

// ParseFile parses config from a file.
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/severity.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ package config
type Severity string

const (
// SeveritySuccess indicates validation success
SeveritySuccess Severity = "success"

// SeverityIgnore ignores validation failures
SeverityIgnore Severity = "ignore"

Expand Down
6 changes: 3 additions & 3 deletions pkg/dashboard/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ func getTemplateData(config conf.Configuration, kubeAPI *kube.API) (TemplateData
return TemplateData{}, err
}

var clusterSuccesses, clusterFailures, clusterWarnings uint
var clusterSuccesses, clusterErrors, clusterWarnings uint

// Aggregate all summary counts to get a clusterwide count.
for _, nsRes := range nsResults {
for _, rr := range nsRes.Results {
clusterFailures += rr.Summary.Failures
clusterErrors += rr.Summary.Errors
clusterWarnings += rr.Summary.Warnings
clusterSuccesses += rr.Summary.Successes
}
}

templateData := TemplateData{
ClusterSummary: &validator.ResultSummary{
Failures: clusterFailures,
Errors: clusterErrors,
Warnings: clusterWarnings,
Successes: clusterSuccesses,
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/dashboard/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestGetTemplateData(t *testing.T) {
sum := &validator.ResultSummary{
Successes: uint(4),
Warnings: uint(1),
Failures: uint(1),
Errors: uint(1),
}

actualTmplData, _ := getTemplateData(c, k8s)
Expand Down
6 changes: 3 additions & 3 deletions pkg/dashboard/templates/dashboard.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<tr>
<td class="resource-info">
<div class="name"><span class="caret-expander"></span>{{ .Type }}: <strong>{{ .Name }}</strong></div>

{{ range .PodResults}}
<div class="extra">
<h4>Pod:</h4>
Expand Down Expand Up @@ -126,7 +126,7 @@
label: 'Failing',
data: [
{{ range $namespace, $results := .NamespacedResults }}
"{{ $results.Summary.Failures }}",
"{{ $results.Summary.Errors }}",
{{ end }}
],
backgroundColor: '#a11f4c',
Expand Down Expand Up @@ -155,7 +155,7 @@
data: {
labels: ["Passing", "Warning", "Failing"],
datasets: [{
data: [{{ .ClusterSummary.Successes }}, {{ .ClusterSummary.Warnings }}, {{ .ClusterSummary.Failures }}],
data: [{{ .ClusterSummary.Successes }}, {{ .ClusterSummary.Warnings }}, {{ .ClusterSummary.Errors }}],
backgroundColor: ['#8BD2DC','#f26c21','#a11f4c'],
}]
},
Expand Down
84 changes: 22 additions & 62 deletions pkg/validator/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,23 @@ import (

// ContainerValidation tracks validation failures associated with a Container.
type ContainerValidation struct {
Container corev1.Container
Summary ResultSummary
Failures []ResultMessage
Warnings []ResultMessage
Successes []ResultMessage
*ResourceValidation
Container *corev1.Container
}

func (cv *ContainerValidation) messages() []ResultMessage {
mssgs := []ResultMessage{}
mssgs = append(mssgs, cv.Failures...)
mssgs = append(mssgs, cv.Warnings...)
mssgs = append(mssgs, cv.Successes...)
return mssgs
}

func validateContainer(conf conf.Configuration, container corev1.Container) ResourceResult {
// ValidateContainer validates that each pod conforms to the Fairwinds config, returns a ResourceResult.
func ValidateContainer(cnConf *conf.Configuration, container *corev1.Container) ResourceResult {
cv := ContainerValidation{
Container: container,
Summary: ResultSummary{},
ResourceValidation: &ResourceValidation{
Summary: &ResultSummary{},
},
}

cv.validateResources(&conf.Resources)
cv.validateHealthChecks(&conf.HealthChecks)
cv.validateImage(&conf.Images)
cv.validateNetworking(&conf.Networking)
cv.validateResources(&cnConf.Resources)
cv.validateHealthChecks(&cnConf.HealthChecks)
cv.validateImage(&cnConf.Images)
cv.validateNetworking(&cnConf.Networking)

cRes := ContainerResult{
Name: container.Name,
Expand All @@ -59,68 +51,36 @@ func validateContainer(conf conf.Configuration, container corev1.Container) Reso
rr := ResourceResult{
Name: container.Name,
Type: "Container",
Summary: &cv.Summary,
Summary: cv.Summary,
ContainerResults: []ContainerResult{cRes},
}

return rr
}

func (cv *ContainerValidation) addMessage(message string, severity conf.Severity) {
if severity == conf.SeverityError {
cv.addFailure(message)
} else if severity == conf.SeverityWarning {
cv.addWarning(message)
}
}

func (cv *ContainerValidation) addFailure(message string) {
cv.Summary.Failures++
cv.Failures = append(cv.Failures, ResultMessage{
Message: message,
Type: "failure",
})
}

func (cv *ContainerValidation) addWarning(message string) {
cv.Summary.Warnings++
cv.Warnings = append(cv.Warnings, ResultMessage{
Message: message,
Type: "warning",
})
}

func (cv *ContainerValidation) addSuccess(message string) {
cv.Summary.Successes++
cv.Successes = append(cv.Successes, ResultMessage{
Message: message,
Type: "success",
})
}

func (cv *ContainerValidation) validateResources(resConf *conf.Resources) {
res := cv.Container.Resources

if resConf.CPURequestsMissing.IsActionable() && res.Requests.Cpu().MilliValue() == 0 {
cv.addMessage("CPU Requests are not set", resConf.CPURequestsMissing)
cv.addFailure("CPU Requests are not set", resConf.CPURequestsMissing)
} else {
cv.validateResourceRange("CPU Requests", &resConf.CPURequestRanges, res.Requests.Cpu())
}

if resConf.CPULimitsMissing.IsActionable() && res.Limits.Cpu().MilliValue() == 0 {
cv.addMessage("CPU Limits are not set", resConf.CPULimitsMissing)
cv.addFailure("CPU Limits are not set", resConf.CPULimitsMissing)
} else {
cv.validateResourceRange("CPU Limits", &resConf.CPULimitRanges, res.Requests.Cpu())
}

if resConf.MemoryRequestsMissing.IsActionable() && res.Requests.Memory().MilliValue() == 0 {
cv.addMessage("Memory Requests are not set", resConf.MemoryRequestsMissing)
cv.addFailure("Memory Requests are not set", resConf.MemoryRequestsMissing)
} else {
cv.validateResourceRange("Memory Requests", &resConf.MemoryRequestRanges, res.Requests.Memory())
}

if resConf.MemoryLimitsMissing.IsActionable() && res.Limits.Memory().MilliValue() == 0 {
cv.addMessage("Memory Limits are not set", resConf.MemoryLimitsMissing)
cv.addFailure("Memory Limits are not set", resConf.MemoryLimitsMissing)
} else {
cv.validateResourceRange("Memory Limits", &resConf.MemoryLimitRanges, res.Limits.Memory())
}
Expand All @@ -133,11 +93,11 @@ func (cv *ContainerValidation) validateResourceRange(resourceName string, rangeC
errorBelow := rangeConf.Error.Below

if errorAbove != nil && errorAbove.MilliValue() < res.MilliValue() {
cv.addFailure(fmt.Sprintf("%s are too high", resourceName))
cv.addError(fmt.Sprintf("%s are too high", resourceName))
} else if warnAbove != nil && warnAbove.MilliValue() < res.MilliValue() {
cv.addWarning(fmt.Sprintf("%s are too high", resourceName))
} else if errorBelow != nil && errorBelow.MilliValue() > res.MilliValue() {
cv.addFailure(fmt.Sprintf("%s are too low", resourceName))
cv.addError(fmt.Sprintf("%s are too low", resourceName))
} else if warnBelow != nil && warnBelow.MilliValue() > res.MilliValue() {
cv.addWarning(fmt.Sprintf("%s are too low", resourceName))
} else {
Expand All @@ -148,15 +108,15 @@ func (cv *ContainerValidation) validateResourceRange(resourceName string, rangeC
func (cv *ContainerValidation) validateHealthChecks(conf *conf.HealthChecks) {
if conf.ReadinessProbeMissing.IsActionable() {
if cv.Container.ReadinessProbe == nil {
cv.addMessage("Readiness probe needs to be configured", conf.ReadinessProbeMissing)
cv.addFailure("Readiness probe needs to be configured", conf.ReadinessProbeMissing)
} else {
cv.addSuccess("Readiness probe configured")
}
}

if conf.LivenessProbeMissing.IsActionable() {
if cv.Container.LivenessProbe == nil {
cv.addMessage("Liveness probe needs to be configured", conf.LivenessProbeMissing)
cv.addFailure("Liveness probe needs to be configured", conf.LivenessProbeMissing)
} else {
cv.addSuccess("Liveness probe configured")
}
Expand All @@ -167,7 +127,7 @@ func (cv *ContainerValidation) validateImage(imageConf *conf.Images) {
if imageConf.TagNotSpecified.IsActionable() {
img := strings.Split(cv.Container.Image, ":")
if len(img) == 1 || img[1] == "latest" {
cv.addMessage("Image tag should be specified", imageConf.TagNotSpecified)
cv.addFailure("Image tag should be specified", imageConf.TagNotSpecified)
} else {
cv.addSuccess("Image tag specified")
}
Expand All @@ -185,7 +145,7 @@ func (cv *ContainerValidation) validateNetworking(networkConf *conf.Networking)
}

if hostPortSet {
cv.addMessage("Host port is configured, but it shouldn't be", networkConf.HostAliasSet)
cv.addFailure("Host port is configured, but it shouldn't be", networkConf.HostAliasSet)
} else {
cv.addSuccess("Host port is not configured")
}
Expand Down
Loading

0 comments on commit f5cde2d

Please sign in to comment.