constellation/hack/bazel-deps-mirror/check.go
miampf f16ccf5679
rewrote packages
keyservice
joinservice
upgrade-agent
measurement-reader
debugd
disk-mapper

rewrote joinservice main

rewrote some unit tests

rewrote upgrade-agent + some grpc functions

rewrote measurement-reader

rewrote debugd

removed unused import

removed forgotten zap reference in measurements reader

rewrote disk-mapper + tests

rewrote packages

verify
disk-mapper
malicious join
bootstrapper
attestationconfigapi
versionapi
internal/cloud/azure
disk-mapper tests
image/upload/internal/cmd

rewrote verify (WIP with loglevel increase)

rewrote forgotten zap references in disk-mapper

rewrote malicious join

rewrote bootstrapper

rewrote parts of internal/

rewrote attestationconfigapi (WIP)

rewrote versionapi cli

rewrote internal/cloud/azure

rewrote disk-mapper tests (untested by me rn)

rewrote image/upload/internal/cmd

removed forgotten zap references in verify/cmd

rewrote packages

hack/oci-pin
hack/qemu-metadata-api
debugd/internal/debugd/deploy
hack/bazel-deps-mirror
cli/internal/cmd
cli-k8s-compatibility

rewrote hack/qemu-metadata-api/server

rewrote debugd/internal/debugd/deploy

rewrote hack/bazel-deps-mirror

rewrote rest of hack/qemu-metadata-api

rewrote forgotten zap references in joinservice server

rewrote cli/internal/cmd

rewrote cli-k8s-compatibility

rewrote packages

internal/staticupload
e2d/internal/upgrade
internal/constellation/helm
internal/attestation/aws/snp
internal/attestation/azure/trustedlaunch
joinservice/internal/certcache/amkds

some missed unit tests

rewrote e2e/internal/upgrade

rewrote internal/constellation/helm

internal/attestation/aws/snp

internal/attestation/azure/trustedlaunch

joinservice/internal/certcache/amkds

search and replace test logging over all left *_test.go
2024-02-08 13:14:14 +01:00

184 lines
5.4 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package main
import (
"context"
"errors"
"log/slog"
"os"
"github.com/edgelesssys/constellation/v2/hack/bazel-deps-mirror/internal/bazelfiles"
"github.com/edgelesssys/constellation/v2/hack/bazel-deps-mirror/internal/issues"
"github.com/edgelesssys/constellation/v2/hack/bazel-deps-mirror/internal/mirror"
"github.com/edgelesssys/constellation/v2/hack/bazel-deps-mirror/internal/rules"
"github.com/spf13/cobra"
)
func newCheckCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "check",
Short: "Check if all Bazel dependencies are mirrored and the corresponding rules are properly formatted.",
RunE: runCheck,
}
cmd.Flags().Bool("mirror", false, "Performs authenticated checks to validate if all referenced CAS objects are still consistent within the mirror.")
cmd.Flags().Bool("mirror-unauthenticated", false, "Performs unauthenticated, slow checks to validate if all referenced CAS objects are still consistent within the mirror. Doesn't require authentication to the mirror but may be inefficient.")
cmd.MarkFlagsMutuallyExclusive("mirror", "mirror-unauthenticated")
return cmd
}
func runCheck(cmd *cobra.Command, _ []string) error {
flags, err := parseCheckFlags(cmd)
if err != nil {
return err
}
log := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: flags.logLevel}))
log.Debug("Parsed flags: %+v", flags)
filesHelper, err := bazelfiles.New()
if err != nil {
return err
}
log.Debug("Searching for Bazel files in the current WORKSPACE and all subdirectories...")
bazelFiles, err := filesHelper.FindFiles()
if err != nil {
return err
}
var mirrorCheck mirrorChecker
switch {
case flags.mirrorUnauthenticated:
log.Debug("Checking consistency of all referenced CAS objects without authentication.")
mirrorCheck = mirror.NewUnauthenticated(flags.mirrorBaseURL, mirror.Run, log)
case flags.mirror:
log.Debug("Checking consistency of all referenced CAS objects using AWS S3.")
mirrorCheck, err = mirror.New(cmd.Context(), flags.region, flags.bucket, flags.mirrorBaseURL, mirror.Run, log)
if err != nil {
return err
}
default:
mirrorCheck = &noOpMirrorChecker{}
}
iss := issues.New()
for _, bazelFile := range bazelFiles {
issByFile, err := checkBazelFile(cmd.Context(), filesHelper, mirrorCheck, bazelFile, log)
if err != nil {
return err
}
if len(issByFile) > 0 {
iss.Set(bazelFile.AbsPath, issByFile)
}
}
if len(iss) > 0 {
log.Info("Found issues in rules")
iss.Report(cmd.OutOrStdout())
return errors.New("found issues in rules")
}
log.Info("No issues found 🦭")
return nil
}
func checkBazelFile(ctx context.Context, fileHelper *bazelfiles.Helper, mirrorCheck mirrorChecker, bazelFile bazelfiles.BazelFile, log *slog.Logger) (issByFile issues.ByFile, err error) {
log.Debug("Checking file: %s", bazelFile.RelPath)
issByFile = issues.NewByFile()
buildfile, err := fileHelper.LoadFile(bazelFile)
if err != nil {
return nil, err
}
found := rules.Rules(buildfile, rules.SupportedRules)
if len(found) == 0 {
log.Debug("No rules found in file: %s", bazelFile.RelPath)
return issByFile, nil
}
log.Debug("Found %d rules in file: %s", len(found), bazelFile.RelPath)
for _, rule := range found {
log.Debug("Checking rule: %s", rule.Name())
// check if the rule is a valid pinned dependency rule (has all required attributes)
if issues := rules.ValidatePinned(rule); len(issues) > 0 {
issByFile.Add(rule.Name(), issues...)
continue
}
// check if the rule is a valid mirror rule
if issues := rules.Check(rule); len(issues) > 0 {
issByFile.Add(rule.Name(), issues...)
}
// check if the referenced CAS object is still consistent
// may be a no-op if --check-consistency is not set
expectedHash, expectedHashErr := rules.GetHash(rule)
if expectedHashErr == nil && rules.HasMirrorURL(rule) {
if issue := mirrorCheck.Check(ctx, expectedHash); issue != nil {
issByFile.Add(rule.Name(), issue)
}
}
}
return issByFile, nil
}
type checkFlags struct {
mirrorUnauthenticated bool
mirror bool
region string
bucket string
mirrorBaseURL string
logLevel slog.Level
}
func parseCheckFlags(cmd *cobra.Command) (checkFlags, error) {
mirrorUnauthenticated, err := cmd.Flags().GetBool("mirror-unauthenticated")
if err != nil {
return checkFlags{}, err
}
mirror, err := cmd.Flags().GetBool("mirror")
if err != nil {
return checkFlags{}, err
}
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return checkFlags{}, err
}
logLevel := slog.LevelInfo
if verbose {
logLevel = slog.LevelDebug
}
region, err := cmd.Flags().GetString("region")
if err != nil {
return checkFlags{}, err
}
bucket, err := cmd.Flags().GetString("bucket")
if err != nil {
return checkFlags{}, err
}
mirrorBaseURL, err := cmd.Flags().GetString("mirror-base-url")
if err != nil {
return checkFlags{}, err
}
return checkFlags{
mirrorUnauthenticated: mirrorUnauthenticated,
mirror: mirror,
region: region,
bucket: bucket,
mirrorBaseURL: mirrorBaseURL,
logLevel: logLevel,
}, nil
}
type mirrorChecker interface {
Check(ctx context.Context, expectedHash string) error
}
type noOpMirrorChecker struct{}
func (m *noOpMirrorChecker) Check(_ context.Context, _ string) error {
return nil
}