Skip to content
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

Add lib to preflight #809

Merged
merged 1 commit into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion certification/runtime/result_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"os"
)

// ResultWriterFile implements a resultWriter for use at preflight runtime.
// ResultWriterFile implements a ResultWriter for use at preflight runtime.
type ResultWriterFile struct {
file *os.File
}
Expand Down
50 changes: 0 additions & 50 deletions cmd/check.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
package cmd

import (
"bytes"
"context"
"fmt"
"strings"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/formatters"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand All @@ -36,52 +28,10 @@ func checkCmd() *cobra.Command {
return checkCmd
}

// writeJUnit will write results as JUnit XML using the built-in formatter.
func writeJUnit(ctx context.Context, results runtime.Results) error {
var cfg runtime.Config
cfg.ResponseFormat = "junitxml"

junitformatter, err := formatters.NewForConfig(cfg.ReadOnly())
if err != nil {
return err
}
junitResults, err := junitformatter.Format(ctx, results)
if err != nil {
return err
}

junitFilename, err := artifacts.WriteFile("results-junit.xml", bytes.NewReader((junitResults)))
if err != nil {
return err
}
log.Tracef("JUnitXML written to %s", junitFilename)

return nil
}

func resultsFilenameWithExtension(ext string) string {
return strings.Join([]string{"results", ext}, ".")
}

func buildConnectURL(projectID string) string {
connectURL := fmt.Sprintf("https://connect.redhat.com/projects/%s", projectID)

pyxisEnv := viper.GetString("pyxis_env")
if len(pyxisEnv) > 0 && pyxisEnv != "prod" {
connectURL = fmt.Sprintf("https://connect.%s.redhat.com/projects/%s", viper.GetString("pyxis_env"), projectID)
}

return connectURL
}

func buildOverviewURL(projectID string) string {
return fmt.Sprintf("%s/overview", buildConnectURL(projectID))
}

func buildScanResultsURL(projectID string, imageID string) string {
return fmt.Sprintf("%s/images/%s/scan-results", buildConnectURL(projectID), imageID)
}

func convertPassedOverall(passedOverall bool) string {
if passedOverall {
return "PASSED"
Expand Down
106 changes: 9 additions & 97 deletions cmd/check_container.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package cmd

import (
"context"
"fmt"
"strings"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/engine"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/formatters"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/policy"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/lib"
"github.com/redhat-openshift-ecosystem/openshift-preflight/version"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -52,53 +50,6 @@ func checkContainerCmd() *cobra.Command {
return checkContainerCmd
}

// checkContainerRunner contains all of the components necessary to run checkContainer.
type checkContainerRunner struct {
cfg *runtime.Config
pc pyxisClient
eng engine.CheckEngine
formatter formatters.ResponseFormatter
rw resultWriter
rs resultSubmitter
}

func newCheckContainerRunner(ctx context.Context, cfg *runtime.Config) (*checkContainerRunner, error) {
cfg.Policy = policy.PolicyContainer
cfg.Submit = submit

pyxisClient := newPyxisClient(ctx, cfg.ReadOnly())
// If we have a pyxisClient, we can query for container policy exceptions.
if pyxisClient != nil {
policy, err := getContainerPolicyExceptions(ctx, pyxisClient)
if err != nil {
return nil, err
}

cfg.Policy = policy
}

engine, err := engine.NewForConfig(ctx, cfg.ReadOnly())
if err != nil {
return nil, err
}

fmttr, err := formatters.NewForConfig(cfg.ReadOnly())
if err != nil {
return nil, err
}

rs := resolveSubmitter(pyxisClient, cfg.ReadOnly())

return &checkContainerRunner{
cfg: cfg,
pc: pyxisClient,
eng: engine,
formatter: fmttr,
rw: &runtime.ResultWriterFile{},
rs: rs,
}, nil
}

// checkContainerRunE executes checkContainer using the user args to inform the execution.
func checkContainerRunE(cmd *cobra.Command, args []string) error {
log.Info("certification library version ", version.Version.String())
Expand All @@ -114,62 +65,23 @@ func checkContainerRunE(cmd *cobra.Command, args []string) error {
cfg.Image = containerImage
cfg.ResponseFormat = formatters.DefaultFormat

checkContainer, err := newCheckContainerRunner(ctx, cfg)
checkContainer, err := lib.NewCheckContainerRunner(ctx, cfg, submit)
if err != nil {
return err
}

// Run the container check.
cmd.SilenceUsage = true
return preflightCheck(ctx,
checkContainer.cfg,
checkContainer.pc,
checkContainer.eng,
checkContainer.formatter,
checkContainer.rw,
checkContainer.rs,
return lib.PreflightCheck(ctx,
checkContainer.Cfg,
checkContainer.Pc,
checkContainer.Eng,
checkContainer.Formatter,
checkContainer.Rw,
checkContainer.Rs,
)
}

// resolveSubmitter will build out a resultSubmitter if the provided pyxisClient, pc, is not nil.
// The pyxisClient is a required component of the submitter. If pc is nil, then a noop submitter
// is returned instead, which does nothing.
func resolveSubmitter(pc pyxisClient, cfg certification.Config) resultSubmitter {
if pc != nil {
return &containerCertificationSubmitter{
certificationProjectID: cfg.CertificationProjectID(),
pyxis: pc,
dockerConfig: cfg.DockerConfig(),
preflightLogFile: cfg.LogFile(),
}
}

return &noopSubmitter{emitLog: true}
}

// getContainerPolicyExceptions will query Pyxis to determine if
// a given project has a certification excemptions, such as root or scratch.
// This will then return the corresponding policy.
//
// If no policy exception flags are found on the project, the standard
// container policy is returned.
func getContainerPolicyExceptions(ctx context.Context, pc pyxisClient) (policy.Policy, error) {
certProject, err := pc.GetProject(ctx)
if err != nil {
return "", fmt.Errorf("could not retrieve project: %w", err)
}
log.Debugf("Certification project name is: %s", certProject.Name)
if certProject.Container.Type == "scratch" {
return policy.PolicyScratch, nil
}

// if a partner sets `Host Level Access` in connect to `Privileged`, enable RootExceptionContainerPolicy checks
if certProject.Container.Privileged {
return policy.PolicyRoot, nil
}
return policy.PolicyContainer, nil
}

func checkContainerPositionalArgs(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("a container image positional argument is required")
Expand Down
Loading