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

feat(RELEASE-1124): validate Application reference #560

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
29 changes: 29 additions & 0 deletions controllers/release/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func newAdapter(ctx context.Context, client client.Client, release *v1alpha1.Rel

releaseAdapter.validations = []controller.ValidationFunction{
releaseAdapter.validateProcessingResources,
releaseAdapter.validateApplication,
releaseAdapter.validateAuthor,
releaseAdapter.validatePipelineRef,
releaseAdapter.validateSinglePipeline,
Expand Down Expand Up @@ -582,6 +583,34 @@ func (a *adapter) registerProcessingStatus(pipelineRun *tektonv1.PipelineRun) er
return nil
}

// validateApplication will ensure that the same Application is used in both, the Snapshot and the ReleasePlan. If the
// resources reference different Applications, an error will be returned.
func (a *adapter) validateApplication() *controller.ValidationResult {
releasePlan, err := a.loader.GetReleasePlan(a.ctx, a.client, a.release)
if err != nil {
if errors.IsNotFound(err) {
a.release.MarkValidationFailed(err.Error())
return &controller.ValidationResult{Valid: false}
}
return &controller.ValidationResult{Err: err}
}

snapshot, err := a.loader.GetSnapshot(a.ctx, a.client, a.release)
if err != nil {
if errors.IsNotFound(err) {
a.release.MarkValidationFailed(err.Error())
return &controller.ValidationResult{Valid: false}
}
return &controller.ValidationResult{Err: err}
}

if releasePlan.Spec.Application != snapshot.Spec.Application {
return &controller.ValidationResult{Err: fmt.Errorf("different Application referenced in ReleasePlan and Snapshot")}
}

return &controller.ValidationResult{Valid: true}
}

// validateAuthor will ensure that a valid author exists for the Release and add it to its status. If the Release
// has the automated label but doesn't have automated set in its status, this function will return an error so the
// operation knows to requeue the Release.
Expand Down
60 changes: 60 additions & 0 deletions controllers/release/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,66 @@ var _ = Describe("Release adapter", Ordered, func() {
})
})

When("validateAuthor is called", func() {
var adapter *adapter

AfterEach(func() {
_ = adapter.client.Delete(ctx, adapter.release)
})

BeforeEach(func() {
adapter = createReleaseAndAdapter()
})

It("returns valid and no error if the Application match", func() {
result := adapter.validateApplication()
Expect(result.Valid).To(BeTrue())
Expect(result.Err).NotTo(HaveOccurred())
})

It("returns invalid and error if the Application doesn't match", func() {
newReleasePlan := releasePlan.DeepCopy()
newReleasePlan.Spec.Application = "non-existent"
adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{
{
ContextKey: loader.ReleasePlanContextKey,
Resource: newReleasePlan,
},
})

result := adapter.validateApplication()
Expect(result.Valid).To(BeFalse())
Expect(result.Err).To(HaveOccurred())
Expect(result.Err.Error()).To(Equal("different Application referenced in ReleasePlan and Snapshot"))
})

It("returns invalid if the ReleasePlan is not found", func() {
adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{
{
ContextKey: loader.ReleasePlanContextKey,
Err: errors.NewNotFound(schema.GroupResource{}, ""),
},
})

result := adapter.validateApplication()
Expect(result.Valid).To(BeFalse())
Expect(result.Err).NotTo(HaveOccurred())
})

It("returns invalid if the Snapshot is not found", func() {
adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{
{
ContextKey: loader.SnapshotContextKey,
Err: errors.NewNotFound(schema.GroupResource{}, ""),
},
})

result := adapter.validateApplication()
Expect(result.Valid).To(BeFalse())
Expect(result.Err).NotTo(HaveOccurred())
})
})

When("calling validateAuthor", func() {
var adapter *adapter
var conditionMsg string
Expand Down
Loading