-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support for kyverno policies #333
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
earthly 0.8.15 | ||
golang 1.22.7 | ||
golang 1.23.4 | ||
golangci-lint 1.62.2 | ||
helm 3.16.3 | ||
helm-cr 1.6.1 | ||
|
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package kyverno | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/zapier/kubechecks/pkg/checks" | ||
"github.com/zapier/kubechecks/pkg/msg" | ||
) | ||
|
||
func Check(ctx context.Context, request checks.Request) (msg.Result, error) { | ||
return kyvernoValidate(ctx, request.Container, request.AppName, request.KubernetesVersion, request.YamlManifests) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package kyverno | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"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" | ||
) | ||
|
||
var tracer = otel.Tracer("pkg/checks/kyverno") | ||
|
||
func kyvernoValidate(ctx context.Context, ctr container.Container, appName, targetKubernetesVersion string, appManifests []string) (msg.Result, error) { | ||
_, span := tracer.Start(ctx, "KyvernoValidate") | ||
defer span.End() | ||
|
||
log.Debug().Msg("Creating temporary file for app manifests") | ||
tempFile, err := os.CreateTemp("/tmp", "appManifests-*.yaml") | ||
if err != nil { | ||
log.Error().Err(err).Msg("Failed to create temporary file") | ||
return msg.Result{}, err | ||
} | ||
defer os.Remove(tempFile.Name()) | ||
|
||
log.Debug().Str("tempFile", tempFile.Name()).Msg("Temporary file created") | ||
|
||
for _, manifest := range appManifests { | ||
if _, err := tempFile.WriteString(manifest + "\n"); err != nil { | ||
log.Error().Err(err).Msg("Failed to write manifest to temporary file") | ||
return msg.Result{}, err | ||
} | ||
} | ||
|
||
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") | ||
return msg.Result{}, err | ||
} | ||
log.Info().Msg(output.String()) | ||
|
||
var cr msg.Result | ||
if output.Len() == 0 { | ||
cr.State = pkg.StateWarning | ||
} else { | ||
cr.State = pkg.StateSuccess | ||
} | ||
Comment on lines
+61
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there's no output, then it failed? This seems ... strange, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is more like a dummy script to just see what happens. We'll need to parse the output to know if it failed or not. |
||
|
||
log.Debug().Str("report", output.String()).Msg("Kyverno validation completed") | ||
cr.Summary = "<b>Show kyverno report:</b>" | ||
cr.Details = fmt.Sprintf(">Kyverno Policy Report \n\n%s", output.String()) | ||
|
||
log.Debug().Msg("Kyverno validation completed") | ||
|
||
return cr, nil | ||
} | ||
|
||
func getPoliciesLocations(ctr container.Container) []string { | ||
cfg := ctr.Config | ||
|
||
// schemas configured globally | ||
var locations []string | ||
|
||
for _, location := range cfg.KyvernoPoliciesLocation { | ||
for _, path := range cfg.KyvernoPoliciesPaths { | ||
locations = append(locations, filepath.Join(location, path)) | ||
} | ||
} | ||
|
||
log.Debug().Strs("locations", locations).Msg("processed kyverno policies locations") | ||
|
||
return locations | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,10 @@ type ServerConfig struct { | |
// -- preupgrade | ||
EnablePreupgrade bool `mapstructure:"enable-preupgrade"` | ||
WorstPreupgradeState pkg.CommitState `mapstructure:"worst-preupgrade-state"` | ||
// -- kyverno | ||
EnableKyvernoChecks bool `mapstructure:"enable-kyverno-checks"` | ||
KyvernoPoliciesLocation []string `mapstructure:"kyverno-policies-location"` | ||
KyvernoPoliciesPaths []string `mapstructure:"kyverno-policies-paths"` | ||
Comment on lines
+72
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah! That'll be added |
||
|
||
// misc | ||
AdditionalAppsNamespaces []string `mapstructure:"additional-apps-namespaces"` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you need
---
to seperate the manifests from each other here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's right! Nice catch.
FYI, this is still in progress. So, it's not fully ready