Repository: redhat-openshift-ecosystem/openshift-preflight
Pull request #466 (2022-03-09 18:12:56)

Pass docker config to the results upload
The docker config was not being passed to the results. This adss them
to the results, and makes the env var the same as the check operator
command.

This also rearranges some of the initialization code so that the viper
configs are initialized in time to be able to shortcut whether
--docker-config is required or not. If the PFLT_DOCKERCONFIG envvar
is set, it does not require the flag.

Signed-off-by: Brad P. Crochet <brad@redhat.com>

openshift-ci[bot]: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/466#" title="Author self-approved">bcrochet</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-openshift-ecosystem%2Fopenshift-preflight).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-openshift-ecosystem/openshift-preflight/blob/main/OWNERS)~~ [bcrochet]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/certification/pyxis/submit.go b/certification/pyxis/submit.go
index b78352c..a41be9b 100644
--- a/certification/pyxis/submit.go
+++ b/certification/pyxis/submit.go
@@ -2,21 +2,25 @@ package pyxis
 
 import (
 	"context"
+	"fmt"
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/errors"
 	log "github.com/sirupsen/logrus"
 )
 
-func (p *pyxisEngine) SubmitResults(certProject *CertProject, certImage *CertImage, rpmManifest *RPMManifest, testResults *TestResults) (*CertProject, *CertImage, *TestResults, error) {
+func (p *pyxisEngine) SubmitResults(ctx context.Context, certProject *CertProject, certImage *CertImage, rpmManifest *RPMManifest, testResults *TestResults) (*CertProject, *CertImage, *TestResults, error) {
 	var err error
-	ctx := context.Background()
-	oldProject := *certProject
 
 	if certProject.CertificationStatus == "Started" {
 		certProject.CertificationStatus = "In Progress"
 	}
 
-	if *certProject != oldProject {
+	oldCertProject, err := p.GetProject(ctx)
+	if err != nil {
+		return nil, nil, nil, fmt.Errorf("%w: %s", err, "could not retrieve project")
+	}
+
+	if *certProject != *oldCertProject {
 		certProject, err = p.updateProject(ctx, certProject)
 		if err != nil {
 			log.Error(err, "could not update project")
diff --git a/cmd/check.go b/cmd/check.go
index c258b4f..a7b812c 100644
--- a/cmd/check.go
+++ b/cmd/check.go
@@ -16,6 +16,8 @@ var checkCmd = &cobra.Command{
 }
 
 func init() {
+	cobra.OnInitialize(initConfig)
+
 	checkCmd.PersistentFlags().BoolP("list-checks", "l", false, "lists all the checks run for a given check")
 
 	rootCmd.AddCommand(checkCmd)
diff --git a/cmd/check_container.go b/cmd/check_container.go
index 93cb656..7a7c764 100644
--- a/cmd/check_container.go
+++ b/cmd/check_container.go
@@ -44,7 +44,7 @@ var checkContainerCmd = &cobra.Command{
 			return fmt.Errorf("%w: A container image positional argument is required", errors.ErrInsufficientPosArguments)
 		}
 
-		if submit {
+		if submit && !viper.IsSet("dockerConfig") {
 			cmd.MarkFlagRequired("docker-config")
 		}
 
@@ -59,6 +59,8 @@ var checkContainerCmd = &cobra.Command{
 
 		log.Info("certification library version ", version.Version.String())
 
+		ctx := context.Background()
+
 		containerImage := args[0]
 
 		cfg := runtime.Config{
@@ -75,7 +77,6 @@ var checkContainerCmd = &cobra.Command{
 			projectId = strings.Split(projectId, "-")[1]
 		}
 		apiToken := viper.GetString("pyxis_api_token")
-		ctx := context.Background()
 		pyxisEngine := pyxis.NewPyxisEngine(apiToken, projectId, &http.Client{Timeout: 60 * time.Second})
 		certProject, err := pyxisEngine.GetProject(ctx)
 		if err != nil {
@@ -88,6 +89,21 @@ var checkContainerCmd = &cobra.Command{
 			cfg.Scratch = true
 		}
 
+		if submit {
+			dockerConfigJsonFile, err := os.Open(viper.GetString("dockerConfig"))
+			if err != nil {
+				return err
+			}
+			defer dockerConfigJsonFile.Close()
+
+			dockerConfigJsonBytes, err := io.ReadAll(dockerConfigJsonFile)
+			if err != nil {
+				return err
+			}
+
+			certProject.Container.DockerConfigJSON = string(dockerConfigJsonBytes)
+		}
+
 		engine, err := engine.NewForConfig(cfg)
 		if err != nil {
 			return err
@@ -140,6 +156,7 @@ var checkContainerCmd = &cobra.Command{
 		// submitting results to pxysis if submit flag is set
 		if submit {
 			log.Info("preparing results that will be submitted to Red Hat")
+			log.Tracef("CertProject: %+v", certProject)
 
 			certImageJsonFile, err := os.Open(path.Join(artifacts.Path(), certification.DefaultCertImageFilename))
 			if err != nil {
@@ -194,7 +211,7 @@ var checkContainerCmd = &cobra.Command{
 				return err
 			}
 
-			_, certImage, _, err = pyxisEngine.SubmitResults(certProject, certImage, rpmManifest, testResults)
+			_, certImage, _, err = pyxisEngine.SubmitResults(ctx, certProject, certImage, rpmManifest, testResults)
 			if err != nil {
 				return err
 			}
@@ -214,7 +231,7 @@ func init() {
 	viper.BindPFlag("submit", checkContainerCmd.Flags().Lookup("submit"))
 
 	checkContainerCmd.Flags().StringP("docker-config", "d", "", "path to docker config.json file")
-	viper.BindPFlag("docker_config", checkContainerCmd.Flags().Lookup("docker-config"))
+	viper.BindPFlag("dockerConfig", checkContainerCmd.Flags().Lookup("docker-config"))
 
 	checkContainerCmd.Flags().String("pyxis-api-token", "", "API token for Pyxis authentication")
 	checkContainerCmd.MarkFlagRequired("pyxis-api-token")
diff --git a/cmd/utils.go b/cmd/utils.go
index 8bd9ccd..e0440c8 100644
--- a/cmd/utils.go
+++ b/cmd/utils.go
@@ -10,12 +10,13 @@ import (
 	"github.com/spf13/viper"
 )
 
+var configFileUsed bool
+
 func resultsFilenameWithExtension(ext string) string {
 	return strings.Join([]string{"results", ext}, ".")
 }
 
-// preRunConfig is used by cobra.PreRun in all non-root commands to load all necessary configurations
-func preRunConfig(cmd *cobra.Command, args []string) {
+func initConfig() {
 	// set up ENV var support
 	viper.SetEnvPrefix("pflt")
 	viper.AutomaticEnv()
@@ -25,7 +26,7 @@ func preRunConfig(cmd *cobra.Command, args []string) {
 	viper.SetConfigType("yaml")
 	viper.AddConfigPath(".")
 
-	configFileUsed := true
+	configFileUsed = true
 	if err := viper.ReadInConfig(); err != nil {
 		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
 			configFileUsed = false
@@ -47,7 +48,10 @@ func preRunConfig(cmd *cobra.Command, args []string) {
 	// Set up pyxis host
 	viper.SetDefault("pyxis_host", DefaultPyxisHost)
 	viper.SetDefault("pyxis_api_token", "")
+}
 
+// preRunConfig is used by cobra.PreRun in all non-root commands to load all necessary configurations
+func preRunConfig(cmd *cobra.Command, args []string) {
 	// set up logging
 	logname := viper.GetString("logfile")
 	logFile, err := os.OpenFile(logname, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
diff --git a/docs/CONFIG.md b/docs/CONFIG.md
index 64b61c0..cbd5bb4 100644
--- a/docs/CONFIG.md
+++ b/docs/CONFIG.md
@@ -39,3 +39,4 @@ is called.
 |--|--|--|--|--|
 |`PFLT_PYXIS_HOST`|env|The Pyxis host to connect to. Must contain any additional path information leading up to the API version|optional|catalog.redhat.com/api/containers|
 |`PFLT_PYXIS_API_TOKEN`|env|The API Token to be used when connecting to Pyxis. Used for authenticated calls only.|optional?|-|
+|`PFLT_DOCKERCONFIG`|env|The full path to a dockerconfigjson file, that has access to the container under test.|required|-|


Test patch:
diff --git a/certification/pyxis/submit_test.go b/certification/pyxis/submit_test.go
index dc3496b..e92a9b5 100644
--- a/certification/pyxis/submit_test.go
+++ b/certification/pyxis/submit_test.go
@@ -3,11 +3,14 @@ package pyxis
 import (
 	"context"
 	"errors"
+	"fmt"
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
 
+var ctx = context.Background()
+
 var _ = Describe("Pyxis Submit", func() {
 	var pyxisEngine *pyxisEngine
 
@@ -17,7 +20,7 @@ var _ = Describe("Pyxis Submit", func() {
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).ToNot(HaveOccurred())
 				Expect(certProject).ToNot(BeNil())
 				Expect(certImage).ToNot(BeNil())
@@ -36,8 +39,8 @@ var _ = Describe("Pyxis Submit updateProject 401 Unauthorized", func() {
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
-				Expect(err).To(MatchError(errors.New("error calling remote API")))
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				Expect(err).To(MatchError(fmt.Errorf("%w: %s", errors.New("error calling remote API"), "could not retrieve project")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())
 				Expect(testResults).To(BeNil())
@@ -55,7 +58,7 @@ var _ = Describe("Pyxis Submit with createImage 409 Conflict", func() {
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).ToNot(HaveOccurred())
 				Expect(certProject).ToNot(BeNil())
 				Expect(certImage).ToNot(BeNil())
@@ -74,7 +77,7 @@ var _ = Describe("Pyxis Submit with createImage 401 Unauthorized", func() {
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).To(MatchError(errors.New("error calling remote API")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())
@@ -93,7 +96,7 @@ var _ = Describe("Pyxis Submit with createImage 409 Conflict and getImage 401 Un
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).To(MatchError(errors.New("error calling remote API")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())
@@ -112,7 +115,7 @@ var _ = Describe("Pyxis Submit with createRPMManifest 409 Conflict", func() {
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).ToNot(HaveOccurred())
 				Expect(certProject).ToNot(BeNil())
 				Expect(certImage).ToNot(BeNil())
@@ -131,7 +134,7 @@ var _ = Describe("Pyxis Submit with createRPMManifest 401 Unauthorized", func()
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).To(MatchError(errors.New("error calling remote API")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())
@@ -150,7 +153,7 @@ var _ = Describe("Pyxis Submit with createRPMManifest 409 Conflict and getRPMMan
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).To(MatchError(errors.New("error calling remote API")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())
@@ -169,7 +172,7 @@ var _ = Describe("Pyxis Submit with createTestResults 401 Unauthorized", func()
 	Context("when a project is submitted", func() {
 		Context("and it is not already In Progress", func() {
 			It("should switch to In Progress", func() {
-				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(&CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
+				certProject, certImage, testResults, err := pyxisEngine.SubmitResults(ctx, &CertProject{CertificationStatus: "Started"}, &CertImage{}, &RPMManifest{}, &TestResults{})
 				Expect(err).To(MatchError(errors.New("error calling remote API")))
 				Expect(certProject).To(BeNil())
 				Expect(certImage).To(BeNil())