Skip to content

Commit

Permalink
move update logic into started since we should only care about upda…
Browse files Browse the repository at this point in the history
…ting net new projects all other updates are taken care of by backend systems (#603)

Signed-off-by: Adam D. Cornett <[email protected]>
  • Loading branch information
acornett21 authored May 6, 2022
1 parent 14517e2 commit 8374f32
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 19 deletions.
9 changes: 9 additions & 0 deletions certification/pyxis/pyxis_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ func (p *pyxisProjectHandler) ServeHTTP(response http.ResponseWriter, request *h
switch {
case request.Header["X-Api-Key"][0] == "my-bad-project-api-token":
response.WriteHeader(401)
case request.Header["X-Api-Key"][0] == "my-update-project-api-token":
if request.Method == http.MethodGet {
mustWrite(response, `{"_id":"deadb33f","certification_status":"Started","name":"My Spiffy Project","project_status":"Foo","type":"Containers","container":{"docker_config_json":"{}","type":"Containers"}}`)
break
}

response.WriteHeader(500)
case request.Header["X-Api-Key"][0] == "my-index-docker-io-project-api-token":
mustWrite(response, `{"_id":"deadb33f","certification_status":"Started","name":"My Index Docker IO Project","project_status":"Foo","type":"Containers","container":{"docker_config_json":"{}","type":"Containers","registry":"docker.io", "repository":"my/repo"}}`)
case request.Method == http.MethodPost:
body, err := io.ReadAll(request.Body)
if err != nil {
Expand Down
50 changes: 32 additions & 18 deletions certification/pyxis/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import (
"context"
"fmt"

"github.com/google/go-containerregistry/pkg/name"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/errors"
log "github.com/sirupsen/logrus"
)

var defaultRegistryAlias = "docker.io"

// SubmitResults takes certInput and sends requests to Pyxis to create or update entries
// based on certInput.
func (p *pyxisClient) SubmitResults(ctx context.Context, certInput *certificationInput) (*CertificationResults, error) {
Expand All @@ -17,31 +20,42 @@ func (p *pyxisClient) SubmitResults(ctx context.Context, certInput *certificatio
certImage := certInput.CertImage

// Submission effectively starts the certification process, so switch
// the status to reflect this if needed.
// the status to reflect this if needed. This only needs to be done for net new projects.
// Existing projects that are in "In Progress" can stay "In Progress" until they moved to "Published" which is triggered
// once an image in a project is moved to "Published" status. The status on the project would stay in "Published" status,
// unless the partner decides to un-publish all of their images. At that point backed systems/processes would move
// the project back to "In Process" and there would still be nothing that preflight need to update on the project.
if certProject.CertificationStatus == "Started" {
certProject.CertificationStatus = "In Progress"
}

// You must have an existing repository.
if len(certImage.Repositories) == 0 {
return nil, errors.ErrInvalidCertImage
}
// You must have an existing repository.
if len(certImage.Repositories) == 0 {
return nil, errors.ErrInvalidCertImage
}

// Set this project's metadata to match the image that we're certifying.
certProject.Container.Registry = certImage.Repositories[0].Registry
certProject.Container.Repository = certImage.Repositories[0].Repository
// Setting registry to the value we get from certImage from crane and then normalizing
// index.docker.io to docker.io so project info shows properly in the Red Hat Catalog
registry := certImage.Repositories[0].Registry
if registry == name.DefaultRegistry {
registry = defaultRegistryAlias
}

// Compare the original
oldCertProject, err := p.GetProject(ctx)
if err != nil {
return nil, fmt.Errorf("%w: %s", err, "could not retrieve project")
}
// Set this project's metadata to match the image that we're certifying.
certProject.Container.Registry = registry
certProject.Container.Repository = certImage.Repositories[0].Repository

if *certProject != *oldCertProject {
certProject, err = p.updateProject(ctx, certProject)
// Compare the original
oldCertProject, err := p.GetProject(ctx)
if err != nil {
log.Error(err, "could not update project")
return nil, err
return 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")
return nil, err
}
}
}

Expand Down
78 changes: 77 additions & 1 deletion certification/pyxis/submit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,83 @@ var _ = Describe("Pyxis Submit", func() {
})
})

Context("updateProject 401 Unauthorized", func() {
Context("when a project is submitted with an empty registry", func() {
BeforeEach(func() {
pyxisClient = NewPyxisClient("my.pyxis.host/api", "my-spiffy-api-token", "my-awesome-project-id", &http.Client{Transport: localRoundTripper{handler: mux}})
})
Context("and it is not already In Progress", func() {
It("should get invalid cert image error", func() {
certResults, err := pyxisClient.SubmitResults(ctx, &certificationInput{
CertProject: &CertProject{CertificationStatus: "Started"},
CertImage: &CertImage{},
RpmManifest: &RPMManifest{},
TestResults: &TestResults{},
Artifacts: []Artifact{},
})
Expect(err).To(MatchError(errors.New("certImage has not been properly populated")))
Expect(certResults).To(BeNil())
})
})
})

Context("when an index.docker.io project is submitted", func() {
BeforeEach(func() {
pyxisClient = NewPyxisClient("my.pyxis.host/api", "my-index-docker-io-project-api-token", "my-index-docker-io-project-api-token", &http.Client{Transport: localRoundTripper{handler: mux}})
})
Context("and it is not already In Progress", func() {
It("should switch to In Progress and certResults.CertProject.Container.Registry should equal 'docker.io'", func() {
certResults, err := pyxisClient.SubmitResults(ctx, &certificationInput{
CertProject: &CertProject{CertificationStatus: "Started"},
CertImage: &CertImage{
Repositories: []Repository{
{
Registry: "index.docker.io",
Repository: "my/repo",
},
},
},
RpmManifest: &RPMManifest{},
TestResults: &TestResults{},
Artifacts: []Artifact{},
})
Expect(err).ToNot(HaveOccurred())
Expect(certResults).ToNot(BeNil())
Expect(certResults.CertProject.Container.Registry).Should(Equal(defaultRegistryAlias))
Expect(certResults.CertImage).ToNot(BeNil())
Expect(certResults.TestResults).ToNot(BeNil())
})
})
})

Context("updateProject 500 Internal Error", func() {
BeforeEach(func() {
pyxisClient = NewPyxisClient("my.pyxis.host/api", "my-update-project-api-token", "my-awesome-project-id", &http.Client{Transport: localRoundTripper{handler: mux}})
})
Context("when a project is submitted", func() {
Context("and the client sends an update token", func() {
It("GetProject should succeed and updateProject should 500 Internal Error", func() {
certResults, err := pyxisClient.SubmitResults(ctx, &certificationInput{
CertProject: &CertProject{CertificationStatus: "Started"},
CertImage: &CertImage{
Repositories: []Repository{
{
Registry: "my.registry",
Repository: "my/repo",
},
},
},
RpmManifest: &RPMManifest{},
TestResults: &TestResults{},
Artifacts: []Artifact{},
})
Expect(err).To(MatchError(errors.New("error calling remote API")))
Expect(certResults).To(BeNil())
})
})
})
})

Context("GetProject 401 Unauthorized", func() {
BeforeEach(func() {
pyxisClient = NewPyxisClient("my.pyxis.host/api", "my-bad-project-api-token", "my-awesome-project-id", &http.Client{Transport: localRoundTripper{handler: mux}})
})
Expand Down

0 comments on commit 8374f32

Please sign in to comment.