Skip to content

Commit

Permalink
feat(RELEASE-1109): allow tenant and managed pipelines to run in same…
Browse files Browse the repository at this point in the history
… release

This commit modifies the release controller to execute both a tenant and
managed pipelineRun in the same Release if both are defined.

Signed-off-by: Johnny Bieren <[email protected]>
  • Loading branch information
johnbieren committed Sep 11, 2024
1 parent eb4b9aa commit 6ca7b1e
Show file tree
Hide file tree
Showing 21 changed files with 1,910 additions and 688 deletions.
14 changes: 10 additions & 4 deletions api/v1alpha1/release_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const (
// postActionsExecutedConditionType is the type used to track the status of Release post-actions
postActionsExecutedConditionType conditions.ConditionType = "PostActionsExecuted"

// processedConditionType is the type used to track the status of a Release processing
processedConditionType conditions.ConditionType = "Processed"
// managedProcessedConditionType is the type used to track the status of a Release Managed Pipeline processing
managedProcessedConditionType conditions.ConditionType = "ManagedPipelineProcessed"

// tenantProcessedConditionType is the type used to track the status of a Release Tenant Pipeline processing
tenantProcessedConditionType conditions.ConditionType = "TenantPipelineProcessed"

// releasedConditionType is the type used to track the status of a Release
releasedConditionType conditions.ConditionType = "Released"
Expand All @@ -20,9 +23,12 @@ const (
// FailedReason is the reason set when a failure occurs
FailedReason conditions.ConditionReason = "Failed"

// ProgressingReason is the reason set when an action is progressing
// ProgressingReason is the reason set when a phase is progressing
ProgressingReason conditions.ConditionReason = "Progressing"

// SucceededReason is the reason set when an action succeeds
// SucceededReason is the reason set when a phase succeeds
SucceededReason conditions.ConditionReason = "Succeeded"

// SkippedReason is the reason set when a phase is skipped
SkippedReason conditions.ConditionReason = "Skipped"
)
188 changes: 135 additions & 53 deletions api/v1alpha1/release_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,15 @@ type ReleaseStatus struct {

// PostActionsExecution contains information about the post-actions execution
// +optional
PostActionsExecution PostActionsExecutionInfo `json:"postActionsExecution,omitempty"`
PostActionsExecution PipelineInfo `json:"postActionsExecution,omitempty"`

// Processing contains information about the release processing
// ManagedProcessing contains information about the release managed processing
// +optional
Processing ProcessingInfo `json:"processing,omitempty"`
ManagedProcessing PipelineInfo `json:"managedProcessing,omitempty"`

// TenantProcessing contains information about the release tenant processing
// +optional
TenantProcessing PipelineInfo `json:"tenantProcessing,omitempty"`

// Validation contains information about the release validation
// +optional
Expand Down Expand Up @@ -111,19 +115,8 @@ type AttributionInfo struct {
StandingAuthorization bool `json:"standingAuthorization,omitempty"`
}

// PostActionsExecutionInfo defines the observed state of the post-actions execution.
type PostActionsExecutionInfo struct {
// CompletionTime is the time when the Release post-actions execution was completed
// +optional
CompletionTime *metav1.Time `json:"completionTime,omitempty"`

// StartTime is the time when the Release post-actions execution started
// +optional
StartTime *metav1.Time `json:"startTime,omitempty"`
}

// ProcessingInfo defines the observed state of the release processing.
type ProcessingInfo struct {
// PipelineInfo defines the observed state of the release pipeline processing.
type PipelineInfo struct {
// CompletionTime is the time when the Release processing was completed
// +optional
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
Expand Down Expand Up @@ -177,9 +170,14 @@ func (r *Release) HasEveryPostActionExecutionFinished() bool {
return r.hasPhaseFinished(postActionsExecutedConditionType)
}

// HasProcessingFinished checks whether the Release processing has finished, regardless of the result.
func (r *Release) HasProcessingFinished() bool {
return r.hasPhaseFinished(processedConditionType)
// HasManagedPipelineProcessingFinished checks whether the Release Managed Pipeline processing has finished, regardless of the result.
func (r *Release) HasManagedPipelineProcessingFinished() bool {
return r.hasPhaseFinished(managedProcessedConditionType)
}

// HasTenantPipelineProcessingFinished checks whether the Release Tenant Pipeline processing has finished, regardless of the result.
func (r *Release) HasTenantPipelineProcessingFinished() bool {
return r.hasPhaseFinished(tenantProcessedConditionType)
}

// HasReleaseFinished checks whether the Release has finished, regardless of the result.
Expand Down Expand Up @@ -207,14 +205,24 @@ func (r *Release) IsEachPostActionExecuting() bool {
return r.isPhaseProgressing(postActionsExecutedConditionType)
}

// IsProcessed checks whether the Release was successfully processed.
func (r *Release) IsProcessed() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, processedConditionType.String())
// IsManagedPipelineProcessed checks whether the Release Managed Pipeline was successfully processed.
func (r *Release) IsManagedPipelineProcessed() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, managedProcessedConditionType.String())
}

// IsTenantPipelineProcessed checks whether the Release Tenant Pipeline was successfully processed.
func (r *Release) IsTenantPipelineProcessed() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, tenantProcessedConditionType.String())
}

// IsManagedPipelineProcessing checks whether the Release Managed Pipeline processing is in progress.
func (r *Release) IsManagedPipelineProcessing() bool {
return r.isPhaseProgressing(managedProcessedConditionType)
}

// IsProcessing checks whether the Release processing is in progress.
func (r *Release) IsProcessing() bool {
return r.isPhaseProgressing(processedConditionType)
// IsTenantPipelineProcessing checks whether the Release Tenant Pipeline processing is in progress.
func (r *Release) IsTenantPipelineProcessing() bool {
return r.isPhaseProgressing(tenantProcessedConditionType)
}

// IsReleased checks whether the Release has finished successfully.
Expand All @@ -232,60 +240,132 @@ func (r *Release) IsValid() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, validatedConditionType.String())
}

// MarkProcessed marks the Release as processed.
func (r *Release) MarkProcessed() {
if !r.IsProcessing() || r.HasProcessingFinished() {
// MarkManagedPipelineProcessed marks the Release Managed Pipeline as processed.
func (r *Release) MarkManagedPipelineProcessed() {
if !r.IsManagedPipelineProcessing() || r.HasManagedPipelineProcessingFinished() {
return
}

r.Status.Processing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetCondition(&r.Status.Conditions, processedConditionType, metav1.ConditionTrue, SucceededReason)
r.Status.ManagedProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetCondition(&r.Status.Conditions, managedProcessedConditionType, metav1.ConditionTrue, SucceededReason)

go metrics.RegisterCompletedReleaseProcessing(
r.Status.Processing.StartTime,
r.Status.Processing.CompletionTime,
go metrics.RegisterCompletedReleaseManagedPipelineProcessing(
r.Status.ManagedProcessing.StartTime,
r.Status.ManagedProcessing.CompletionTime,
SucceededReason.String(),
r.Status.Target,
)
}

// MarkProcessing marks the Release as processing.
func (r *Release) MarkProcessing(message string) {
if r.HasProcessingFinished() {
// MarkTenantPipelineProcessed marks the Release Tenant Pipeline as processed.
func (r *Release) MarkTenantPipelineProcessed() {
if !r.IsTenantPipelineProcessing() || r.HasTenantPipelineProcessingFinished() {
return
}

if !r.IsProcessing() {
r.Status.Processing.StartTime = &metav1.Time{Time: time.Now()}
r.Status.TenantProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetCondition(&r.Status.Conditions, tenantProcessedConditionType, metav1.ConditionTrue, SucceededReason)

go metrics.RegisterCompletedReleaseTenantPipelineProcessing(
r.Status.TenantProcessing.StartTime,
r.Status.TenantProcessing.CompletionTime,
SucceededReason.String(),
r.Status.Target,
)
}

// MarkManagedPipelineProcessing marks the Release Managed Pipeline as processing.
func (r *Release) MarkManagedPipelineProcessing() {
if r.HasManagedPipelineProcessingFinished() {
return
}

conditions.SetConditionWithMessage(&r.Status.Conditions, processedConditionType, metav1.ConditionFalse, ProgressingReason, message)
if !r.IsManagedPipelineProcessing() {
r.Status.ManagedProcessing.StartTime = &metav1.Time{Time: time.Now()}
}

conditions.SetCondition(&r.Status.Conditions, managedProcessedConditionType, metav1.ConditionFalse, ProgressingReason)

go metrics.RegisterNewReleaseProcessing(
r.Status.Processing.StartTime,
go metrics.RegisterNewReleaseManagedPipelineProcessing(
r.Status.ManagedProcessing.StartTime,
r.Status.StartTime,
ProgressingReason.String(),
r.Status.Target,
)
}

// MarkProcessingFailed marks the Release processing as failed.
func (r *Release) MarkProcessingFailed(message string) {
if !r.IsProcessing() || r.HasProcessingFinished() {
// MarkTenantPipelineProcessing marks the Release Tenant Pipeline as processing.
func (r *Release) MarkTenantPipelineProcessing() {
if r.HasTenantPipelineProcessingFinished() {
return
}

r.Status.Processing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetConditionWithMessage(&r.Status.Conditions, processedConditionType, metav1.ConditionFalse, FailedReason, message)
if !r.IsTenantPipelineProcessing() {
r.Status.TenantProcessing.StartTime = &metav1.Time{Time: time.Now()}
}

conditions.SetCondition(&r.Status.Conditions, tenantProcessedConditionType, metav1.ConditionFalse, ProgressingReason)

go metrics.RegisterCompletedReleaseProcessing(
r.Status.Processing.StartTime,
r.Status.Processing.CompletionTime,
go metrics.RegisterNewReleaseTenantPipelineProcessing(
r.Status.TenantProcessing.StartTime,
r.Status.StartTime,
ProgressingReason.String(),
r.Status.Target,
)
}

// MarkManagedPipelineProcessingFailed marks the Release Managed Pipeline processing as failed.
func (r *Release) MarkManagedPipelineProcessingFailed(message string) {
if !r.IsManagedPipelineProcessing() || r.HasManagedPipelineProcessingFinished() {
return
}

r.Status.ManagedProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetConditionWithMessage(&r.Status.Conditions, managedProcessedConditionType, metav1.ConditionFalse, FailedReason, message)

go metrics.RegisterCompletedReleaseManagedPipelineProcessing(
r.Status.ManagedProcessing.StartTime,
r.Status.ManagedProcessing.CompletionTime,
FailedReason.String(),
r.Status.Target,
)
}

// MarkTenantPipelineProcessingFailed marks the Release Tenant Pipeline processing as failed.
func (r *Release) MarkTenantPipelineProcessingFailed(message string) {
if !r.IsTenantPipelineProcessing() || r.HasTenantPipelineProcessingFinished() {
return
}

r.Status.TenantProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetConditionWithMessage(&r.Status.Conditions, tenantProcessedConditionType, metav1.ConditionFalse, FailedReason, message)

go metrics.RegisterCompletedReleaseTenantPipelineProcessing(
r.Status.TenantProcessing.StartTime,
r.Status.TenantProcessing.CompletionTime,
FailedReason.String(),
r.Status.Target,
)
}

// MarkManagedPipelineProcessingSkipped marks the Release Managed Pipeline processing as skipped.
func (r *Release) MarkManagedPipelineProcessingSkipped() {
if r.HasManagedPipelineProcessingFinished() {
return
}

conditions.SetCondition(&r.Status.Conditions, managedProcessedConditionType, metav1.ConditionTrue, SkippedReason)
}

// MarkTenantPipelineProcessingSkipped marks the Release Tenant Pipeline processing as skipped.
func (r *Release) MarkTenantPipelineProcessingSkipped() {
if r.HasTenantPipelineProcessingFinished() {
return
}

conditions.SetCondition(&r.Status.Conditions, tenantProcessedConditionType, metav1.ConditionTrue, SkippedReason)
}

// MarkPostActionsExecuted marks the Release post-actions as executed.
func (r *Release) MarkPostActionsExecuted() {
if !r.IsEachPostActionExecuting() || r.HasEveryPostActionExecutionFinished() {
Expand Down Expand Up @@ -327,8 +407,8 @@ func (r *Release) MarkPostActionsExecutionFailed(message string) {
conditions.SetConditionWithMessage(&r.Status.Conditions, postActionsExecutedConditionType, metav1.ConditionFalse, FailedReason, message)

go metrics.RegisterCompletedReleasePostActionsExecuted(
r.Status.Processing.StartTime,
r.Status.Processing.CompletionTime,
r.Status.PostActionsExecution.StartTime,
r.Status.PostActionsExecution.CompletionTime,
FailedReason.String(),
)
}
Expand All @@ -345,10 +425,11 @@ func (r *Release) MarkReleased() {
go metrics.RegisterCompletedRelease(
r.Status.StartTime,
r.Status.CompletionTime,
r.getPhaseReason(managedProcessedConditionType),
r.getPhaseReason(postActionsExecutedConditionType),
r.getPhaseReason(processedConditionType),
SucceededReason.String(),
r.Status.Target,
r.getPhaseReason(tenantProcessedConditionType),
r.getPhaseReason(validatedConditionType),
)
}
Expand Down Expand Up @@ -381,7 +462,8 @@ func (r *Release) MarkReleaseFailed(message string) {
r.Status.StartTime,
r.Status.CompletionTime,
r.getPhaseReason(postActionsExecutedConditionType),
r.getPhaseReason(processedConditionType),
r.getPhaseReason(tenantProcessedConditionType),
r.getPhaseReason(managedProcessedConditionType),
FailedReason.String(),
r.Status.Target,
r.getPhaseReason(validatedConditionType),
Expand Down
Loading

0 comments on commit 6ca7b1e

Please sign in to comment.