Skip to content

Commit

Permalink
some additional cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
robscott committed Apr 29, 2019
1 parent 4fe39e7 commit 0db0e29
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 84 deletions.
9 changes: 4 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
FROM golang:1.11.4 AS build-env
FROM golang:1.12.4 AS build-env
WORKDIR /go/src/github.com/reactiveops/fairwinds/

COPY . .
RUN go get -u github.com/gobuffalo/packr/packr
RUN packr
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o fairwinds *.go
RUN go get -u github.com/gobuffalo/packr/v2/packr2
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 packr2 build -a -o fairwinds *.go

FROM alpine:3.8
FROM alpine:3.9
WORKDIR /usr/local/bin
RUN apk --no-cache add ca-certificates

Expand Down
14 changes: 10 additions & 4 deletions deploy/helm/fairwinds/templates/webhook.deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ spec:
name: webhook
ports:
- containerPort: 9876
# These are fairly useless readiness/liveness probes for now
# Follow this issue for potential improvements:
# https://github.com/kubernetes-sigs/controller-runtime/issues/356
livenessProbe:
exec:
command:
Expand All @@ -46,10 +49,13 @@ spec:
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
tcpSocket:
port: 9876
initialDelaySeconds: 15
periodSeconds: 20
exec:
command:
- sh
- -c
- ps -ef | grep fairwinds
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 100m
Expand Down
14 changes: 10 additions & 4 deletions deploy/webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ spec:
name: webhook
ports:
- containerPort: 9876
# These are fairly useless readiness/liveness probes for now
# Follow this issue for potential improvements:
# https://github.com/kubernetes-sigs/controller-runtime/issues/356
livenessProbe:
exec:
command:
Expand All @@ -199,10 +202,13 @@ spec:
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
tcpSocket:
port: 9876
initialDelaySeconds: 15
periodSeconds: 20
exec:
command:
- sh
- -c
- ps -ef | grep fairwinds
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 100m
Expand Down
29 changes: 14 additions & 15 deletions pkg/validator/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ import (
appsv1 "k8s.io/api/apps/v1"
)

// ValidateDeploy validates a single deployment, returns a ResourceResult.
func ValidateDeploy(conf conf.Configuration, deploy *appsv1.Deployment) ResourceResult {
// ValidateDeploy validates a single deployment, returns a PodResult.
func ValidateDeploy(conf conf.Configuration, deploy *appsv1.Deployment) PodResult {
pod := deploy.Spec.Template.Spec
resResult := ValidatePod(conf, &pod)
resResult.Name = deploy.Name
resResult.Type = "Deployment"
return resResult
podResult := ValidatePod(conf, &pod)
podResult.Name = deploy.Name
return podResult
}

// ValidateDeploys validates that each deployment conforms to the Fairwinds config,
Expand All @@ -39,31 +38,31 @@ func ValidateDeploys(config conf.Configuration, k8sAPI *kube.API) (NamespacedRes
}

for _, deploy := range deploys.Items {
resResult := ValidateDeploy(config, &deploy)
nsResults = addResult(resResult, nsResults, deploy.Namespace)
podResult := ValidateDeploy(config, &deploy)
nsResults = addResult(podResult, nsResults, deploy.Namespace)
}

return nsResults, nil
}

func addResult(resResult ResourceResult, nsResults NamespacedResults, nsName string) NamespacedResults {
nsResult := &NamespacedResult{}
func addResult(podResult PodResult, nsResults NamespacedResults, nsName string) NamespacedResults {
nsResult := &NamespaceResult{}

// If there is already data stored for this namespace name,
// then append to the ResourceResults to the existing data.
switch nsResults[nsName] {
case nil:
nsResult = &NamespacedResult{
Summary: &ResultSummary{},
Results: []ResourceResult{},
nsResult = &NamespaceResult{
Summary: &ResultSummary{},
PodResults: []PodResult{},
}
nsResults[nsName] = nsResult
default:
nsResult = nsResults[nsName]
}

nsResult.Results = append(nsResult.Results, resResult)
nsResult.Summary.appendResults(*resResult.Summary)
nsResult.PodResults = append(nsResult.PodResults, podResult)
nsResult.Summary.appendResults(*podResult.Summary)

return nsResults
}
4 changes: 2 additions & 2 deletions pkg/validator/fullaudit.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func RunAudit(config conf.Configuration, kubeAPI *kube.API) (AuditData, error) {

// Aggregate all summary counts to get a clusterwide count.
for _, nsRes := range nsResults {
for _, rr := range nsRes.Results {
clusterResults.appendResults(*rr.Summary)
for _, pr := range nsRes.PodResults {
clusterResults.appendResults(*pr.Summary)
}
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/validator/fullaudit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ func TestGetTemplateData(t *testing.T) {
assert.Equal(t, err, nil, "error should be nil")

assert.EqualValues(t, sum, actualAudit.ClusterSummary.Results)
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].Results), "should be equal")
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].Results[0].PodResults), "should be equal")
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].Results[0].PodResults[0].ContainerResults), "should be equal")
assert.Equal(t, 6, len(actualAudit.NamespacedResults["test"].Results[0].PodResults[0].ContainerResults[0].Messages), "should be equal")
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].PodResults), "should be equal")
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].PodResults), "should be equal")
assert.Equal(t, 1, len(actualAudit.NamespacedResults["test"].PodResults[0].ContainerResults), "should be equal")
assert.Equal(t, 6, len(actualAudit.NamespacedResults["test"].PodResults[0].ContainerResults[0].Messages), "should be equal")
}
12 changes: 4 additions & 8 deletions pkg/validator/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type PodValidation struct {
}

// ValidatePod validates that each pod conforms to the Fairwinds config, returns a ResourceResult.
func ValidatePod(podConf conf.Configuration, pod *corev1.PodSpec) ResourceResult {
func ValidatePod(podConf conf.Configuration, pod *corev1.PodSpec) PodResult {
pv := PodValidation{
Pod: pod,
ResourceValidation: &ResourceValidation{},
Expand All @@ -39,21 +39,17 @@ func ValidatePod(podConf conf.Configuration, pod *corev1.PodSpec) ResourceResult
pRes := PodResult{
Messages: pv.messages(),
ContainerResults: []ContainerResult{},
Summary: pv.summary(),
}

pv.validateContainers(pod.InitContainers, &pRes, &podConf)
pv.validateContainers(pod.Containers, &pRes, &podConf)

rr := ResourceResult{
Type: "Pod",
Summary: pv.summary(),
PodResults: []PodResult{pRes},
}
for _, cRes := range pRes.ContainerResults {
rr.Summary.appendResults(*cRes.Summary)
pRes.Summary.appendResults(*cRes.Summary)
}

return rr
return pRes
}

func (pv *PodValidation) validateContainers(containers []corev1.Container, pRes *PodResult, podConf *conf.Configuration) {
Expand Down
9 changes: 4 additions & 5 deletions pkg/validator/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ func TestValidatePod(t *testing.T) {
{Message: "Host network is not configured", Type: "success", Category: "Networking"},
}

actualRR := ValidatePod(c, &pod.Spec)
actualPodResult := ValidatePod(c, &pod.Spec)

assert.Equal(t, actualRR.Type, "Pod", "should be equal")
assert.Equal(t, len(actualRR.ContainerResults), 0, "should be equal")
assert.EqualValues(t, actualRR.Summary, &expectedSum)
assert.EqualValues(t, actualRR.PodResults[0].Messages, expectedMessages)
assert.Equal(t, len(actualPodResult.ContainerResults), 1, "should be equal")
assert.EqualValues(t, actualPodResult.Summary, &expectedSum)
assert.EqualValues(t, actualPodResult.Messages, expectedMessages)
}
20 changes: 6 additions & 14 deletions pkg/validator/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,14 @@ const (
MessageTypeError MessageType = "error"
)

// NamespacedResult groups resource results by namespace.
type NamespacedResult struct {
Summary *ResultSummary
Results []ResourceResult
}

// NamespacedResults is a mapping of namespace name to the validation results.
type NamespacedResults map[string]*NamespacedResult
type NamespacedResults map[string]*NamespaceResult

// ResourceResult groups container results by parent resource.
type ResourceResult struct {
Name string
Type string
Summary *ResultSummary
ContainerResults []ContainerResult
PodResults []PodResult
// NamespaceResult groups container results by parent resource.
type NamespaceResult struct {
Name string
Summary *ResultSummary
PodResults []PodResult
}

// CountSummary provides a high level overview of success, warnings, and errors.
Expand Down
38 changes: 15 additions & 23 deletions pkg/webhook/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func NewWebhook(name string, mgr manager.Manager, validator Validator, apiType r
// Handle for Validator to run validation checks.
func (v *Validator) Handle(ctx context.Context, req types.Request) types.Response {
var err error
var results validator.ResourceResult
var podResult validator.PodResult

allowed := true
reason := ""
Expand All @@ -94,49 +94,41 @@ func (v *Validator) Handle(ctx context.Context, req types.Request) types.Respons
case "Deployment":
deploy := appsv1.Deployment{}
err = v.decoder.Decode(req, &deploy)
results = validator.ValidateDeploy(v.Config, &deploy)
podResult = validator.ValidateDeploy(v.Config, &deploy)
case "Pod":
pod := corev1.Pod{}
err = v.decoder.Decode(req, &pod)
results = validator.ValidatePod(v.Config, &pod.Spec)
podResult = validator.ValidatePod(v.Config, &pod.Spec)
}

if err != nil {
logrus.Errorf("Error validating request: %v", err)
return admission.ErrorResponse(http.StatusBadRequest, err)
}

if results.Summary.Totals.Errors > 0 {
if podResult.Summary.Totals.Errors > 0 {
allowed = false
logrus.Infof("Errors %v", results.Summary.Totals.Errors)
logrus.Infof("%d validation errors found when validating %s", podResult.Summary.Totals.Errors, podResult.Name)

reason = getFailureReason(results.PodResults)
reason = getFailureReason(podResult)
}

return admission.ValidationResponse(allowed, reason)
}

func getFailureReason(podResults []validator.PodResult) string {
func getFailureReason(podResult validator.PodResult) string {
reason := "\nFairwinds prevented this deployment due to configuration problems:\n"

for _, podResult := range podResults {
logrus.Infof("podResult %v", podResult)
for _, message := range podResult.Messages {
logrus.Infof("message %v", message)
if message.Type == validator.MessageTypeError {
logrus.Infof("error %v", fmt.Sprintf("- Pod: %s\n", message.Message))
reason += fmt.Sprintf("- Pod: %s\n", message.Message)
}
for _, message := range podResult.Messages {
if message.Type == validator.MessageTypeError {
reason += fmt.Sprintf("- Pod: %s\n", message.Message)
}
}

for _, containerResult := range podResult.ContainerResults {
logrus.Infof("containerResult %v", containerResult)
for _, message := range containerResult.Messages {
logrus.Infof("message %v", message)
if message.Type == validator.MessageTypeError {
logrus.Infof("error %v", fmt.Sprintf("- Container %s: %s\n", containerResult.Name, message.Message))
reason += fmt.Sprintf("- Container %s: %s\n", containerResult.Name, message.Message)
}
for _, containerResult := range podResult.ContainerResults {
for _, message := range containerResult.Messages {
if message.Type == validator.MessageTypeError {
reason += fmt.Sprintf("- Container %s: %s\n", containerResult.Name, message.Message)
}
}
}
Expand Down

0 comments on commit 0db0e29

Please sign in to comment.