Skip to content

Commit

Permalink
some refactoring on the list of actions (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
djeebus authored Oct 11, 2023
1 parent 6de1593 commit 08b878e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 106 deletions.
156 changes: 75 additions & 81 deletions pkg/events/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ import (
"sync/atomic"
"time"

"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/errgroup"

"github.com/zapier/kubechecks/pkg"
"github.com/zapier/kubechecks/pkg/affected_apps"
"github.com/zapier/kubechecks/pkg/argo_client"
Expand All @@ -22,10 +28,6 @@ import (
"github.com/zapier/kubechecks/pkg/validate"
"github.com/zapier/kubechecks/pkg/vcs_clients"
"github.com/zapier/kubechecks/telemetry"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/errgroup"
)

type CheckEvent struct {
Expand Down Expand Up @@ -171,6 +173,9 @@ func (ce *CheckEvent) GenerateListOfAffectedApps(ctx context.Context) error {
} else if viper.GetBool("monitor-all-applications") {
log.Debug().Msg("using an argocd matcher")
matcher = affected_apps.NewArgocdMatcher(ce.cfg.VcsToArgoMap, ce.repo)
if err != nil {
return errors.Wrap(err, "failed to create argocd matcher")
}
} else {
log.Debug().Msg("using best effort matcher")
ce.repoFiles, err = ce.repo.GetListOfRepoFiles()
Expand Down Expand Up @@ -337,115 +342,104 @@ func (ce *CheckEvent) processApp(ctx context.Context, app, dir string) error {
}

grp, grpCtx := errgroup.WithContext(ctx)
grp.Go(func() error {
const taskDescription = "validating app against schema"
defer func() {
if r := recover(); r != nil {
telemetry.SetError(span, fmt.Errorf("%v", r), taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, r))
}
}()
wrap := ce.createWrapper(span, grpCtx, app)

s, err := validate.ArgoCdAppValidate(grpCtx, app, k8sVersion, formattedManifests)
if err != nil {
telemetry.SetError(span, err, taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, err))
return fmt.Errorf("argo Validate: %s", err)
}
grp.Go(wrap("validating app against schema", ce.validateSchemas(grpCtx, app, k8sVersion, formattedManifests)))
grp.Go(wrap("generating diff for app", ce.generateDiff(grpCtx, app, manifests)))

if s != "" {
ce.vcsNote.AddToAppMessage(grpCtx, app, s)
}
return nil
if viper.GetBool("enable-conftest") {
grp.Go(wrap("validation policy", ce.validatePolicy(grpCtx, app)))
}

})
grp.Go(wrap("running pre-upgrade check", ce.runPreupgradeCheck(grpCtx, app, k8sVersion, formattedManifests)))

grp.Go(func() error {
const taskDescription = "generating diff for app"
defer func() {
if r := recover(); r != nil {
telemetry.SetError(span, fmt.Errorf("%v", r), taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, r))
}
}()
err = grp.Wait()
if err != nil {
telemetry.SetError(span, err, "running checks")
}

s, rawDiff, err := diff.GetDiff(grpCtx, app, manifests)
if err != nil {
telemetry.SetError(span, err, taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, err))
return fmt.Errorf("argo Diff: %s", err)
}
ce.vcsNote.AddToAppMessage(ctx, app, renderInfoFooter(time.Since(start), ce.repo.SHA))

if s != "" {
ce.vcsNote.AddToAppMessage(grpCtx, app, s)
diff.AIDiffSummary(grpCtx, ce.vcsNote, app, manifests, rawDiff)
}
return err
}

return nil
})
type checkFunction func() (string, error)

if viper.GetBool("enable-conftest") {
grp.Go(func() error {
const taskDescription = "validating app against policy"
func (ce *CheckEvent) createWrapper(span trace.Span, grpCtx context.Context, app string) func(string, checkFunction) func() error {
return func(desc string, fn checkFunction) func() error {
return func() error {
defer func() {
if r := recover(); r != nil {
telemetry.SetError(span, fmt.Errorf("%v", r), taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, r))
telemetry.SetError(span, fmt.Errorf("%v", r), desc)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, desc, r))
}
}()

argoApp, err := argo_client.GetArgoClient().GetApplicationByName(grpCtx, app)
s, err := fn()
if err != nil {
telemetry.SetError(span, err, taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf("Could not retrieve Argo App details. %v", err))
return fmt.Errorf("could not retrieve ArgoCD App data: %v", err)
}

s, err := conftest.Conftest(grpCtx, argoApp, ce.TempWorkingDir)
if err != nil {
telemetry.SetError(span, err, taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, err))
return fmt.Errorf("confTest: %s", err)
telemetry.SetError(span, err, desc)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, desc, err))
return errors.Wrapf(err, "error while %s", desc)
}

if s != "" {
ce.vcsNote.AddToAppMessage(grpCtx, app, s)
}

return nil
})
}
}
}

grp.Go(func() error {
const taskDescription = "running pre-upgrade check"
defer func() {
if r := recover(); r != nil {
telemetry.SetError(span, fmt.Errorf("%v", r), taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, r))
}
}()

func (ce *CheckEvent) runPreupgradeCheck(grpCtx context.Context, app string, k8sVersion string, formattedManifests []string) func() (string, error) {
return func() (string, error) {
s, err := kubepug.CheckApp(grpCtx, app, k8sVersion, formattedManifests)
if err != nil {
telemetry.SetError(span, err, taskDescription)
ce.vcsNote.AddToAppMessage(grpCtx, app, fmt.Sprintf(errorCommentFormat, taskDescription, err))
return fmt.Errorf("kubePug: %s", err)
return "", err
}

if s != "" {
ce.vcsNote.AddToAppMessage(grpCtx, app, s)
return s, nil
}
}

func (ce *CheckEvent) validatePolicy(ctx context.Context, app string) func() (string, error) {
return func() (string, error) {
argoApp, err := argo_client.GetArgoClient().GetApplicationByName(ctx, app)
if err != nil {
return "", errors.Wrapf(err, "could not retrieve ArgoCD App data: %q", app)
}
return nil

})
s, err := conftest.Conftest(ctx, argoApp, ce.TempWorkingDir)
if err != nil {
return "", err
}

err = grp.Wait()
if err != nil {
telemetry.SetError(span, err, "running checks")
return s, nil
}
}

ce.vcsNote.AddToAppMessage(ctx, app, renderInfoFooter(time.Since(start), ce.repo.SHA))
func (ce *CheckEvent) generateDiff(ctx context.Context, app string, manifests []string) func() (string, error) {
return func() (string, error) {
s, rawDiff, err := diff.GetDiff(ctx, app, manifests)
if err != nil {
return "", err
}

return err
diff.AIDiffSummary(ctx, ce.vcsNote, app, manifests, rawDiff)

return s, nil
}
}

func (ce *CheckEvent) validateSchemas(ctx context.Context, app string, k8sVersion string, formattedManifests []string) func() (string, error) {
return func() (string, error) {
s, err := validate.ArgoCdAppValidate(ctx, app, k8sVersion, formattedManifests)
if err != nil {
return "", err
}

return s, nil
}
}

// Creates a generic Note struct that we can write into across all worker threads
Expand Down
25 changes: 0 additions & 25 deletions pkg/utils.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
package pkg

import (
"fmt"

argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/ghodss/yaml"
"github.com/rs/zerolog/log"
)

var (
GitTag = ""
GitCommit = ""
)

func BuildManifest(resp *apiclient.ManifestResponse) []string {
manifests := []string{}
for _, m := range resp.Manifests {
obj, err := argoappv1.UnmarshalToUnstructured(m)
if err != nil {
log.Warn().Msgf("error processing Argo manifest: %v", err)
continue
}

yamlBytes, _ := yaml.Marshal(obj)
manifests = append(manifests, fmt.Sprintf("---\n%s", string(yamlBytes)))
}

return manifests
}

func PassEmoji() string {
return " :white_check_mark: "
}
Expand Down

0 comments on commit 08b878e

Please sign in to comment.