Skip to content

Commit

Permalink
fix kyverno apply
Browse files Browse the repository at this point in the history
Signed-off-by: Mmadu Manasseh <[email protected]>
  • Loading branch information
MeNsaaH committed Jan 8, 2025
1 parent 0ac7b28 commit 0d7e165
Show file tree
Hide file tree
Showing 8 changed files with 841 additions and 20 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/chainguard-dev/git-urls v1.0.2
github.com/creasty/defaults v1.7.0
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399
github.com/go-logr/zerologr v1.2.3
github.com/google/go-github/v62 v62.0.0
Expand All @@ -31,6 +32,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/olekukonko/tablewriter v0.0.5
github.com/open-policy-agent/conftest v0.49.1
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
github.com/prometheus/client_golang v1.20.4
Expand Down Expand Up @@ -207,7 +209,6 @@ require (
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-git/v5 v5.12.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
Expand Down Expand Up @@ -340,7 +341,6 @@ require (
github.com/open-policy-agent/opa v0.68.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
Expand Down
9 changes: 8 additions & 1 deletion localdev/kubechecks/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ configMap:
KUBECHECKS_ENABLE_CONFTEST: "false"
KUBECHECKS_ENABLE_KYVERNO_CHECKS: "true"
KUBECHECKS_KYVERNO_POLICIES_LOCATION: "https://gitlab.com/zapier/team-sre/service-kyverno.git"
KUBECHECKS_KYVERNO_POLICIES_PATHS: "argocd/production/templates/checks"
KUBECHECKS_KYVERNO_POLICIES_PATHS: "argocd/development/templates/checks"
KUBECHECKS_ARGOCD_SEND_FULL_REPOSITORY: "true"
KUBECHECKS_ARGOCD_REPOSITORY_ENDPOINT: argocd-repo-server.kubechecks:8081
GRPC_ENFORCE_ALPN_ENABLED: false
Expand All @@ -41,6 +41,13 @@ deployment:
name: "kubechecks"
tag: ""

resources:
limits:
memory: 1Gi
requests:
memory: 256Mi
cpu: 200m

secrets:
create: true
env:
Expand Down
63 changes: 46 additions & 17 deletions pkg/checks/kyverno/kyverno.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ package kyverno
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"

engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/rs/zerolog/log"
"github.com/zapier/kubechecks/pkg"
"github.com/zapier/kubechecks/pkg/container"
"github.com/zapier/kubechecks/pkg/msg"
"go.opentelemetry.io/otel"

"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/commands/apply"
apply "github.com/zapier/kubechecks/pkg/kyverno-kubectl"
)

var tracer = otel.Tracer("pkg/checks/kyverno")
Expand All @@ -33,41 +34,69 @@ func kyvernoValidate(ctx context.Context, ctr container.Container, appName, targ
log.Debug().Str("tempFile", tempFile.Name()).Msg("Temporary file created")

for _, manifest := range appManifests {
if _, err := tempFile.WriteString(manifest + "\n"); err != nil {
if _, err := tempFile.WriteString(manifest + "\n---"); err != nil {
log.Error().Err(err).Msg("Failed to write manifest to temporary file")
return msg.Result{}, err
}
}

log.Debug().Msg("App manifests written to temporary file")
_, _ = io.Copy(os.Stdout, tempFile)

if err := tempFile.Close(); err != nil {
log.Error().Err(err).Msg("Failed to close temporary file")
return msg.Result{}, err
}

// This calls the kyverno apply -r <RESOURCE_FILE> <POLICY LOCATIONS ...> command
applyCommand := apply.Command()
applyCommand.SetArgs(
append(
getPoliciesLocations(ctr),
[]string{"-r", tempFile.Name()}...))
var output strings.Builder
applyCommand.SetOutput(&output)
if err := applyCommand.Execute(); err != nil {
log.Error().Err(err).Msg("Failed to execute kyverno apply command")
policyPaths := getPoliciesLocations(ctr)
resourcesPath := []string{tempFile.Name()}
applyResult := apply.RunKyvernoApply(policyPaths, resourcesPath)
if applyResult.Error != nil {
return msg.Result{}, err
}
log.Info().Msg(output.String())

var cr msg.Result
if output.Len() == 0 {
if applyResult.RC.Fail > 0 || applyResult.RC.Error > 0 {
cr.State = pkg.StateWarning
} else {
cr.State = pkg.StateSuccess
}
out := os.Stdout
failedRulesMsg := ""

for _, response := range applyResult.Responses {
var failedRules []engineapi.RuleResponse
resPath := fmt.Sprintf("%s/%s/%s", response.Resource.GetNamespace(), response.Resource.GetKind(), response.Resource.GetName())
for _, rule := range response.PolicyResponse.Rules {
if rule.Status() == engineapi.RuleStatusFail {
failedRules = append(failedRules, rule)
}
if rule.RuleType() == engineapi.Mutation {
if rule.Status() == engineapi.RuleStatusSkip {
fmt.Fprintln(out, "\nskipped mutate policy", response.Policy().GetName(), "->", "resource", resPath)
} else if rule.Status() == engineapi.RuleStatusError {
fmt.Fprintln(out, "\nerror while applying mutate policy", response.Policy().GetName(), "->", "resource", resPath, "\nerror: ", rule.Message())
}
}
}
if len(failedRules) > 0 {
failedRulesMsg = fmt.Sprintf(failedRulesMsg, "policy %s -> resource %s failed: \n", response.Policy().GetName(), resPath)
fmt.Fprintln(out, "policy", response.Policy().GetName(), "->", "resource", resPath, "failed:")
for i, rule := range failedRules {
fmt.Fprintln(out, i+1, "-", rule.Name(), rule.Message())
failedRulesMsg = fmt.Sprintf(failedRulesMsg, "%d - %s %s \n", i+1, rule.Name(), rule.Message())
}
failedRulesMsg = fmt.Sprintf(failedRulesMsg, "\n")
}
}

log.Debug().Str("report", output.String()).Msg("Kyverno validation completed")
log.Debug().Msg("Kyverno validation completed")
cr.Summary = "<b>Show kyverno report:</b>"
cr.Details = fmt.Sprintf(">Kyverno Policy Report \n\n%s", output.String())
cr.Details = fmt.Sprintf(`> Kyverno Policy Report \n\n
%s \n\n
\npass: %d, fail: %d, warn: %d, error: %d, skip: %d \n`,
failedRulesMsg, applyResult.RC.Pass, applyResult.RC.Fail, applyResult.RC.Warn, applyResult.RC.Error, applyResult.RC.Skip,
)

log.Debug().Msg("Kyverno validation completed")

Expand Down
Loading

0 comments on commit 0d7e165

Please sign in to comment.