cmd/validate.go (89 lines of code) (raw):

package cmd import ( "context" "fmt" "github.com/Azure/draft/pkg/safeguards" "github.com/Azure/draft/pkg/safeguards/types" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "helm.sh/helm/v3/pkg/chartutil" ) type validateCmd struct { manifestPath string imagePullSecret bool releaseName string releaseNamespace string } func init() { rootCmd.AddCommand(newValidateCmd()) } func newValidateCmd() *cobra.Command { vc := &validateCmd{} var cmd = &cobra.Command{ Use: "validate", Short: "Validates manifests against AKS best practices", Long: `This command validates manifests against several AKS best practices.`, RunE: func(cmd *cobra.Command, args []string) error { if err := vc.run(cmd); err != nil { return err } return nil }, } f := cmd.Flags() f.StringVarP(&vc.manifestPath, "manifest", "m", "", "'manifest' asks for the path to the manifest") f.BoolVarP(&vc.imagePullSecret, "imagePullSecret", "s", false, "'imagePullSecret' enables the Safeguard that checks for usage of an image pull secret within the manifest(s)") f.StringVarP(&vc.releaseName, "releaseName", "n", "", "'releaseName' asks for a user-defined release name for the Helm package to use when rendering Helm projects in Draft") f.StringVarP(&vc.releaseNamespace, "releaseNamespace", "e", "", "'releaseNamespace' asks for a user-defined release namespace for the Helm package to use when rendering Helm projects in Draft") return cmd } // run is our entry point to GetManifestResults func (vc *validateCmd) run(c *cobra.Command) error { if vc.manifestPath == "" { return fmt.Errorf("path to the manifests cannot be empty") } // AddSafeguardCRIP just adds Container Restricted Image Pulls to the list of safeguards the client will review // against the given manifest if vc.imagePullSecret { safeguards.AddSafeguardCRIP() } var opt chartutil.ReleaseOptions if vc.releaseName != "" { opt.Name = vc.releaseName } if vc.releaseNamespace != "" { opt.Namespace = vc.releaseNamespace } ctx := context.Background() var manifestFiles []types.ManifestFile manifestFiles, err := safeguards.GetManifestFiles(vc.manifestPath, opt) if err != nil { return fmt.Errorf("error retrieving manifest files: %w", err) } log.Debugf("validating manifests") manifestViolations, err := safeguards.GetManifestResults(ctx, manifestFiles) if err != nil { log.Errorf("validating safeguards: %s", err.Error()) return err } anyViolationsFound := false for _, v := range manifestViolations { log.Printf("Analyzing %s for violations", v.Name) manifestHasViolations := false // returning the full list of violations after each manifest is checked for file, violations := range v.ObjectViolations { log.Printf(" %s:", file) for _, violation := range violations { log.Printf(" ❌ %s", violation) anyViolationsFound = true manifestHasViolations = true } } if !manifestHasViolations { log.Printf(" ✅ no violations found.") } } if anyViolationsFound { c.SilenceUsage = true // suppress default Cobra behaviour of printing usage on all errors return fmt.Errorf("violations found") } else { log.Printf("✅ No violations found in \"%s\".", vc.manifestPath) } return nil }