diff --git a/Dockerfile b/Dockerfile index 5f899003..833f3703 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,6 @@ COPY main.go main.go COPY api/ api/ COPY cache/ cache/ COPY controllers/ controllers/ -COPY gitops/ gitops/ COPY loader/ loader/ COPY metadata/ metadata/ COPY metrics/ metrics/ diff --git a/README.md b/README.md index 3e20c4cc..efa6d9a1 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,8 @@ by default, this operator exports the following custom metrics: | Metric name | Type | Description | |--------------------------------------------------|-----------|---------------------------------------------------------------------| | release_concurrent_total | Gauge | Total number of concurrent release attempts. | -| release_concurrent_deployments_total | Gauge | Total number of concurrent release deployment attempts. | | release_concurrent_post_actions_executions_total | Gauge | Total number of concurrent release post actions executions attempts | | release_concurrent_processings_total | Gauge | Total number of concurrent release processing attempts. | -| release_deployment_duration_seconds | Histogram | How long in seconds a Release deployment takes to complete. | | release_duration_seconds | Histogram | How long in seconds a Release takes to complete. | | release_post_actions_execution_duration_seconds | Histogram | How long in seconds Release post-actions take to complete. | | release_processing_duration_seconds | Histogram | How long in seconds a Release processing takes to complete. | diff --git a/api/v1alpha1/release_types.go b/api/v1alpha1/release_types.go index 9d879039..be572845 100644 --- a/api/v1alpha1/release_types.go +++ b/api/v1alpha1/release_types.go @@ -61,10 +61,6 @@ type ReleaseStatus struct { // +optional Conditions []metav1.Condition `json:"conditions"` - // Deployment contains information about the deployment - // +optional - Deployment DeploymentInfo `json:"deployment,omitempty"` - // PostActionsExecution contains information about the post-actions execution // +optional PostActionsExecution PostActionsExecutionInfo `json:"postActionsExecution,omitempty"` @@ -110,27 +106,6 @@ type AttributionInfo struct { StandingAuthorization bool `json:"standingAuthorization,omitempty"` } -// DeploymentInfo defines the observed state of the deployment. -type DeploymentInfo struct { - // CompletionTime is the time when the Release deployment was completed - // +optional - CompletionTime *metav1.Time `json:"completionTime,omitempty"` - - // Environment is the environment where the Release will be deployed to - // +optional - Environment string `json:"environment,omitempty"` - - // SnapshotEnvironmentBinding contains the namespaced name of the SnapshotEnvironmentBinding created as part of - // this release - // +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?\/[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - // +optional - SnapshotEnvironmentBinding string `json:"snapshotEnvironmentBinding,omitempty"` - - // StartTime is the time when the Release deployment started - // +optional - StartTime *metav1.Time `json:"startTime,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 @@ -191,11 +166,6 @@ type Release struct { Status ReleaseStatus `json:"status,omitempty"` } -// HasDeploymentFinished checks whether the Release deployment has finished, regardless of the result. -func (r *Release) HasDeploymentFinished() bool { - return r.hasPhaseFinished(deployedConditionType) -} - // HasEveryPostActionExecutionFinished checks whether the Release post-actions execution has finished, // regardless of the result. func (r *Release) HasEveryPostActionExecutionFinished() bool { @@ -222,16 +192,6 @@ func (r *Release) IsAutomated() bool { return r.Status.Automated } -// IsDeployed checks whether the Release was successfully deployed. -func (r *Release) IsDeployed() bool { - return meta.IsStatusConditionTrue(r.Status.Conditions, deployedConditionType.String()) -} - -// IsDeploying checks whether the Release deployment is in progress. -func (r *Release) IsDeploying() bool { - return r.isPhaseProgressing(deployedConditionType) -} - // IsEveryPostActionExecuted checks whether the Release post-actions were successfully executed. func (r *Release) IsEveryPostActionExecuted() bool { return meta.IsStatusConditionTrue(r.Status.Conditions, postActionsExecutedConditionType.String()) @@ -267,57 +227,6 @@ func (r *Release) IsValid() bool { return meta.IsStatusConditionTrue(r.Status.Conditions, validatedConditionType.String()) } -// MarkDeployed marks the Release as deployed. -func (r *Release) MarkDeployed() { - if !r.IsDeploying() || r.HasDeploymentFinished() { - return - } - - r.Status.Deployment.CompletionTime = &metav1.Time{Time: time.Now()} - conditions.SetCondition(&r.Status.Conditions, deployedConditionType, metav1.ConditionTrue, SucceededReason) - - go metrics.RegisterCompletedReleaseDeployment( - r.Status.Deployment.StartTime, - r.Status.Deployment.CompletionTime, - r.Status.Deployment.Environment, - SucceededReason.String(), - r.Status.Target, - ) -} - -// MarkDeploying marks the Release as deploying. -func (r *Release) MarkDeploying(message string) { - if r.HasDeploymentFinished() { - return - } - - if !r.IsDeploying() { - r.Status.Deployment.StartTime = &metav1.Time{Time: time.Now()} - } - - conditions.SetConditionWithMessage(&r.Status.Conditions, deployedConditionType, metav1.ConditionFalse, ProgressingReason, message) - - go metrics.RegisterNewReleaseDeployment() -} - -// MarkDeploymentFailed marks the Release deployment as failed. -func (r *Release) MarkDeploymentFailed(message string) { - if !r.IsDeploying() || r.HasDeploymentFinished() { - return - } - - r.Status.Deployment.CompletionTime = &metav1.Time{Time: time.Now()} - conditions.SetConditionWithMessage(&r.Status.Conditions, deployedConditionType, metav1.ConditionFalse, FailedReason, message) - - go metrics.RegisterCompletedReleaseDeployment( - r.Status.Deployment.StartTime, - r.Status.Deployment.CompletionTime, - r.Status.Deployment.Environment, - FailedReason.String(), - r.Status.Target, - ) -} - // MarkProcessed marks the Release as processed. func (r *Release) MarkProcessed() { if !r.IsProcessing() || r.HasProcessingFinished() { @@ -431,7 +340,6 @@ func (r *Release) MarkReleased() { go metrics.RegisterCompletedRelease( r.Status.StartTime, r.Status.CompletionTime, - r.getPhaseReason(deployedConditionType), r.getPhaseReason(postActionsExecutedConditionType), r.getPhaseReason(processedConditionType), SucceededReason.String(), @@ -467,7 +375,6 @@ func (r *Release) MarkReleaseFailed(message string) { go metrics.RegisterCompletedRelease( r.Status.StartTime, r.Status.CompletionTime, - r.getPhaseReason(deployedConditionType), r.getPhaseReason(postActionsExecutedConditionType), r.getPhaseReason(processedConditionType), FailedReason.String(), diff --git a/api/v1alpha1/release_types_test.go b/api/v1alpha1/release_types_test.go index 6c1e9301..d3ad60ca 100644 --- a/api/v1alpha1/release_types_test.go +++ b/api/v1alpha1/release_types_test.go @@ -30,38 +30,6 @@ import ( var _ = Describe("Release type", func() { - When("HasDeploymentFinished method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should return false when the deployed condition is missing", func() { - Expect(release.HasDeploymentFinished()).To(BeFalse()) - }) - - It("should return true when the deployed condition status is True", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionTrue, SucceededReason) - Expect(release.HasDeploymentFinished()).To(BeTrue()) - }) - - It("should return false when the deployed condition status is False and the reason is Progressing", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionFalse, ProgressingReason) - Expect(release.HasDeploymentFinished()).To(BeFalse()) - }) - - It("should return true when the deployed condition status is False and the reason is not Progressing", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionFalse, FailedReason) - Expect(release.HasDeploymentFinished()).To(BeTrue()) - }) - - It("should return false when the deployed condition status is Unknown", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionUnknown, ProgressingReason) - Expect(release.HasDeploymentFinished()).To(BeFalse()) - }) - }) - When("HasEveryPostActionExecutionFinished method is called", func() { var release *Release @@ -197,65 +165,6 @@ var _ = Describe("Release type", func() { }) }) - When("IsDeployed method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should return true when the deployed condition status is True", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionTrue, SucceededReason) - Expect(release.IsDeployed()).To(BeTrue()) - }) - - It("should return false when the deployed condition status is False", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionFalse, SucceededReason) - Expect(release.IsDeployed()).To(BeFalse()) - }) - - It("should return false when the deployed condition status is Unknown", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionUnknown, SucceededReason) - Expect(release.IsDeployed()).To(BeFalse()) - }) - - It("should return false when the deployed condition is missing", func() { - Expect(release.IsDeployed()).To(BeFalse()) - }) - }) - - When("IsDeploying method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should return false when the deployed condition is missing", func() { - Expect(release.IsDeploying()).To(BeFalse()) - }) - - It("should return false when the deployed condition status is True", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionTrue, SucceededReason) - Expect(release.IsDeploying()).To(BeFalse()) - }) - - It("should return true when the deployed condition status is False and the reason is Progressing", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionFalse, ProgressingReason) - Expect(release.IsDeploying()).To(BeTrue()) - }) - - It("should return false when the deployed condition status is False and the reason is not Progressing", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionFalse, FailedReason) - Expect(release.IsDeploying()).To(BeFalse()) - }) - - It("should return false when the deployed condition status is Unknown", func() { - conditions.SetCondition(&release.Status.Conditions, deployedConditionType, metav1.ConditionUnknown, ProgressingReason) - Expect(release.IsDeploying()).To(BeFalse()) - }) - }) - When("IsEveryPostActionExecuted method is called", func() { var release *Release @@ -460,135 +369,6 @@ var _ = Describe("Release type", func() { }) }) - When("MarkDeployed method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should do nothing if the Release deployment has not started", func() { - release.MarkDeployed() - Expect(release.Status.Deployment.CompletionTime).To(BeNil()) - }) - - It("should do nothing if the Release deployment finished", func() { - release.MarkDeploying("") - release.MarkDeployed() - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeFalse()) - release.Status.Deployment.CompletionTime = &metav1.Time{} - release.MarkDeployed() - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeTrue()) - }) - - It("should register the completion time", func() { - release.MarkDeploying("") - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeTrue()) - release.MarkDeployed() - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeFalse()) - }) - - It("should register the condition", func() { - Expect(release.Status.Conditions).To(HaveLen(0)) - release.MarkDeploying("") - release.MarkDeployed() - - condition := meta.FindStatusCondition(release.Status.Conditions, deployedConditionType.String()) - Expect(condition).NotTo(BeNil()) - Expect(*condition).To(MatchFields(IgnoreExtras, Fields{ - "Reason": Equal(SucceededReason.String()), - "Status": Equal(metav1.ConditionTrue), - })) - }) - }) - - When("MarkDeploying method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should do nothing if the Release deployment finished", func() { - release.MarkDeploying("") - release.MarkDeployed() - Expect(release.IsDeploying()).To(BeFalse()) - release.MarkDeploying("") - Expect(release.IsDeploying()).To(BeFalse()) - }) - - It("should register the start time if it's not deploying", func() { - Expect(release.Status.Deployment.StartTime).To(BeNil()) - release.MarkDeploying("") - Expect(release.Status.Deployment.StartTime).NotTo(BeNil()) - }) - - It("should not register the start time if it's deploying already", func() { - Expect(release.Status.Deployment.StartTime).To(BeNil()) - release.MarkDeploying("") - release.Status.Deployment.StartTime = &metav1.Time{} - Expect(release.Status.Deployment.StartTime.IsZero()).To(BeTrue()) - release.MarkDeploying("") - Expect(release.Status.Deployment.StartTime.IsZero()).To(BeTrue()) - }) - - It("should register the condition", func() { - Expect(release.Status.Conditions).To(HaveLen(0)) - release.MarkDeploying("foo") - - condition := meta.FindStatusCondition(release.Status.Conditions, deployedConditionType.String()) - Expect(condition).NotTo(BeNil()) - Expect(*condition).To(MatchFields(IgnoreExtras, Fields{ - "Message": Equal("foo"), - "Reason": Equal(ProgressingReason.String()), - "Status": Equal(metav1.ConditionFalse), - })) - }) - }) - - When("MarkDeploymentFailed method is called", func() { - var release *Release - - BeforeEach(func() { - release = &Release{} - }) - - It("should do nothing if the Release deployment has not started", func() { - release.MarkDeploymentFailed("") - Expect(release.Status.Deployment.CompletionTime).To(BeNil()) - }) - - It("should do nothing if the Release deployment finished", func() { - release.MarkDeploying("") - release.MarkDeployed() - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeFalse()) - release.Status.Deployment.CompletionTime = &metav1.Time{} - release.MarkDeploymentFailed("") - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeTrue()) - }) - - It("should register the completion time", func() { - release.MarkDeploying("") - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeTrue()) - release.MarkDeploymentFailed("") - Expect(release.Status.Deployment.CompletionTime.IsZero()).To(BeFalse()) - }) - - It("should register the condition", func() { - Expect(release.Status.Conditions).To(HaveLen(0)) - release.MarkDeploying("") - release.MarkDeploymentFailed("foo") - - condition := meta.FindStatusCondition(release.Status.Conditions, deployedConditionType.String()) - Expect(condition).NotTo(BeNil()) - Expect(*condition).To(MatchFields(IgnoreExtras, Fields{ - "Message": Equal("foo"), - "Reason": Equal(FailedReason.String()), - "Status": Equal(metav1.ConditionFalse), - })) - }) - }) - When("MarkProcessed method is called", func() { var release *Release diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 9aa55f8e..2cc1f24e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -42,29 +42,6 @@ func (in *AttributionInfo) DeepCopy() *AttributionInfo { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DeploymentInfo) DeepCopyInto(out *DeploymentInfo) { - *out = *in - if in.CompletionTime != nil { - in, out := &in.CompletionTime, &out.CompletionTime - *out = (*in).DeepCopy() - } - if in.StartTime != nil { - in, out := &in.StartTime, &out.StartTime - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentInfo. -func (in *DeploymentInfo) DeepCopy() *DeploymentInfo { - if in == nil { - return nil - } - out := new(DeploymentInfo) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MatchedReleasePlan) DeepCopyInto(out *MatchedReleasePlan) { *out = *in @@ -544,7 +521,6 @@ func (in *ReleaseStatus) DeepCopyInto(out *ReleaseStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - in.Deployment.DeepCopyInto(&out.Deployment) in.PostActionsExecution.DeepCopyInto(&out.PostActionsExecution) in.Processing.DeepCopyInto(&out.Processing) in.Validation.DeepCopyInto(&out.Validation) diff --git a/cache/cache.go b/cache/cache.go index 5fdf5c6c..3aa9e968 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -54,13 +54,3 @@ func SetupReleasePlanAdmissionCache(mgr ctrl.Manager) error { return mgr.GetCache().IndexField(context.Background(), &v1alpha1.ReleasePlanAdmission{}, "spec.origin", releasePlanAdmissionIndexFunc) } - -// SetupSnapshotEnvironmentBindingCache adds a new index field to be able to search SnapshotEnvironmentBindings by environment. -func SetupSnapshotEnvironmentBindingCache(mgr ctrl.Manager) error { - snapshotEnvironmentBindingIndexFunc := func(obj client.Object) []string { - return []string{obj.(*applicationapiv1alpha1.SnapshotEnvironmentBinding).Spec.Environment} - } - - return mgr.GetCache().IndexField(context.Background(), &applicationapiv1alpha1.SnapshotEnvironmentBinding{}, - "spec.environment", snapshotEnvironmentBindingIndexFunc) -} diff --git a/config/crd/bases/appstudio.redhat.com_releases.yaml b/config/crd/bases/appstudio.redhat.com_releases.yaml index b4f08902..2ec9fb81 100644 --- a/config/crd/bases/appstudio.redhat.com_releases.yaml +++ b/config/crd/bases/appstudio.redhat.com_releases.yaml @@ -165,30 +165,6 @@ spec: - type type: object type: array - deployment: - description: Deployment contains information about the deployment - properties: - completionTime: - description: CompletionTime is the time when the Release deployment - was completed - format: date-time - type: string - environment: - description: Environment is the environment where the Release - will be deployed to - type: string - snapshotEnvironmentBinding: - description: SnapshotEnvironmentBinding contains the namespaced - name of the SnapshotEnvironmentBinding created as part of this - release - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?\/[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - startTime: - description: StartTime is the time when the Release deployment - started - format: date-time - type: string - type: object expirationTime: description: ExpirationTime is the time when a Release can be purged format: date-time diff --git a/config/grafana/dashboards/release_dashboard.json b/config/grafana/dashboards/release_dashboard.json index 58ddcb02..374bced8 100644 --- a/config/grafana/dashboards/release_dashboard.json +++ b/config/grafana/dashboards/release_dashboard.json @@ -551,72 +551,6 @@ "title": "Failed releases", "type": "stat" }, - { - "datasource": {}, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "red", - "value": null - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 3, - "y": 3 - }, - "id": 21, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "max" - ], - "fields": "", - "values": false - }, - "text": {}, - "textMode": "auto" - }, - "pluginVersion": "9.1.6", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PF224BEF3374A25F8" - }, - "editorMode": "code", - "exemplar": false, - "expr": "sum by (namespace) (release_total{deployment_reason=\"Failed\"})", - "instant": true, - "interval": "", - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Failed deployments", - "type": "stat" - }, { "datasource": {}, "description": "", diff --git a/controllers/release/adapter.go b/controllers/release/adapter.go index b70ce5bd..3b34336a 100644 --- a/controllers/release/adapter.go +++ b/controllers/release/adapter.go @@ -24,12 +24,9 @@ import ( "time" "github.com/go-logr/logr" - libhandler "github.com/operator-framework/operator-lib/handler" - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" integrationgitops "github.com/redhat-appstudio/integration-service/gitops" "github.com/redhat-appstudio/operator-toolkit/controller" "github.com/redhat-appstudio/release-service/api/v1alpha1" - "github.com/redhat-appstudio/release-service/gitops" "github.com/redhat-appstudio/release-service/loader" "github.com/redhat-appstudio/release-service/metadata" "github.com/redhat-appstudio/release-service/syncer" @@ -37,7 +34,6 @@ import ( tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" rbac "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/apis" @@ -163,72 +159,11 @@ func (a *adapter) EnsureReleaseIsCompleted() (controller.OperationResult, error) return controller.ContinueProcessing() } - // The deployment has to complete if the environment field in the ReleasePlanAdmission is set - releasePlanAdmission, err := a.loader.GetActiveReleasePlanAdmissionFromRelease(a.ctx, a.client, a.release) - if err == nil && releasePlanAdmission.Spec.Environment != "" && !a.release.HasDeploymentFinished() { - return controller.ContinueProcessing() - } - patch := client.MergeFrom(a.release.DeepCopy()) a.release.MarkReleased() return controller.RequeueOnErrorOrContinue(a.client.Status().Patch(a.ctx, a.release, patch)) } -// EnsureReleaseIsDeployed is an operation that will ensure that a SnapshotEnvironmentBinding -// associated to the Release being processed exists. Otherwise, it will create a new one. -func (a *adapter) EnsureReleaseIsDeployed() (controller.OperationResult, error) { - if !a.release.IsProcessed() || a.release.HasDeploymentFinished() || a.release.IsDeploying() { - return controller.ContinueProcessing() - } - - releasePlanAdmission, err := a.loader.GetActiveReleasePlanAdmissionFromRelease(a.ctx, a.client, a.release) - if err != nil { - return controller.RequeueWithError(err) - } - - // If no environment is set in the ReleasePlanAdmission, skip the Binding creation - if releasePlanAdmission.Spec.Environment == "" { - return controller.ContinueProcessing() - } - - err = a.syncResources() - if err != nil { - return controller.RequeueWithError(err) - } - - binding, err := a.createOrUpdateSnapshotEnvironmentBinding(releasePlanAdmission) - if err != nil { - return controller.RequeueWithError(err) - } - - a.logger.Info("Created/updated SnapshotEnvironmentBinding", - "SnapshotEnvironmentBinding.Name", binding.Name, "SnapshotEnvironmentBinding.Namespace", binding.Namespace) - - return controller.RequeueOnErrorOrContinue(a.registerDeploymentData(binding, releasePlanAdmission)) -} - -// EnsureReleaseDeploymentIsTracked is an operation that will ensure that the SnapshotEnvironmentBinding -// Deployment status is tracked in the Release being processed. -func (a *adapter) EnsureReleaseDeploymentIsTracked() (controller.OperationResult, error) { - if !a.release.IsDeploying() || a.release.HasDeploymentFinished() { - return controller.ContinueProcessing() - } - - // Search for an existing binding - binding, err := a.loader.GetSnapshotEnvironmentBindingFromReleaseStatus(a.ctx, a.client, a.release) - if err != nil { - return controller.RequeueWithError(err) - } - - // Do nothing if the release does not own the binding - if binding.GetAnnotations()[libhandler.TypeAnnotation] != a.release.GetObjectKind().GroupVersionKind().GroupKind().String() || - binding.GetAnnotations()[libhandler.NamespacedNameAnnotation] != fmt.Sprintf("%s/%s", a.release.GetNamespace(), a.release.GetName()) { - return controller.ContinueProcessing() - } - - return controller.RequeueOnErrorOrContinue(a.registerDeploymentStatus(binding)) -} - // EnsureReleaseIsRunning is an operation that will ensure that a Release has not finished already and that // it is marked as releasing. If the Release has finished, no other operation after this one will be executed. func (a *adapter) EnsureReleaseIsRunning() (controller.OperationResult, error) { @@ -418,53 +353,6 @@ func (a *adapter) createManagedPipelineRun(resources *loader.ProcessingResources return pipelineRun, nil } -// createSnapshotEnvironmentBinding creates or updates a SnapshotEnvironmentBinding for the Release being processed. -func (a *adapter) createOrUpdateSnapshotEnvironmentBinding(releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) { - resources, err := a.loader.GetDeploymentResources(a.ctx, a.client, a.release, releasePlanAdmission) - if err != nil { - return nil, err - } - - // The binding information needs to be updated no matter if it already exists or not - binding := gitops.NewSnapshotEnvironmentBinding(resources.ApplicationComponents, resources.Snapshot, resources.Environment) - - // Search for an existing binding - existingBinding, err := a.loader.GetSnapshotEnvironmentBinding(a.ctx, a.client, releasePlanAdmission) - if err != nil && !errors.IsNotFound(err) { - return nil, err - } - - if existingBinding == nil { - // Set owner references so the binding is deleted if the application is deleted - err = ctrl.SetControllerReference(resources.Application, binding, a.client.Scheme()) - if err != nil { - return nil, err - } - - // Add owner annotations so the controller can watch for status updates to the binding and track them - // in the release - err = libhandler.SetOwnerAnnotations(a.release, binding) - if err != nil { - return nil, err - } - - return binding, a.client.Create(a.ctx, binding) - } else { - // We create the binding so if the owner reference is not already present, there must be a good reason for that - patch := client.MergeFrom(existingBinding.DeepCopy()) - existingBinding.Spec = binding.Spec - - // Add owner annotations so the controller can watch for status updates to the binding and track them - // in the release - err = libhandler.SetOwnerAnnotations(a.release, existingBinding) - if err != nil { - return nil, err - } - - return existingBinding, a.client.Patch(a.ctx, existingBinding, patch) - } -} - // createRoleBindingForClusterRole creates a RoleBinding that binds the serviceAccount from the passed // ReleasePlanAdmission to the passed ClusterRole. If the creation fails, the error is returned. If the creation // is successful, the RoleBinding is returned. @@ -547,57 +435,6 @@ func (a *adapter) getEmptyReleaseServiceConfig(namespace string) *v1alpha1.Relea return releaseServiceConfig } -// registerDeploymentData adds all the Release deployment information to its Status and marks it as processing. -func (a *adapter) registerDeploymentData(snapshotEnvironmentBinding *applicationapiv1alpha1.SnapshotEnvironmentBinding, - releasePlanAdmission *v1alpha1.ReleasePlanAdmission) error { - if snapshotEnvironmentBinding == nil || releasePlanAdmission == nil { - return nil - } - - patch := client.MergeFrom(a.release.DeepCopy()) - - if releasePlanAdmission.Spec.Environment != "" { - a.release.Status.Deployment.Environment = fmt.Sprintf("%s%c%s", - releasePlanAdmission.Namespace, types.Separator, releasePlanAdmission.Spec.Environment) - } - - a.release.Status.Deployment.SnapshotEnvironmentBinding = fmt.Sprintf("%s%c%s", - snapshotEnvironmentBinding.Namespace, types.Separator, snapshotEnvironmentBinding.Name) - - a.release.MarkDeploying("") - - return a.client.Status().Patch(a.ctx, a.release, patch) -} - -// registerDeploymentStatus updates the status of the Release being processed by monitoring the status of the -// associated SnapshotEnvironmentBinding and setting the appropriate state in the Release. -func (a *adapter) registerDeploymentStatus(binding *applicationapiv1alpha1.SnapshotEnvironmentBinding) error { - if binding == nil { - return nil - } - - condition := meta.FindStatusCondition(binding.Status.ComponentDeploymentConditions, - applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed) - if condition == nil { - return nil - } - - patch := client.MergeFrom(a.release.DeepCopy()) - - if condition.Status == metav1.ConditionTrue { - a.release.MarkDeployed() - } else { - if condition.Reason == applicationapiv1alpha1.ComponentDeploymentConditionErrorOccurred { - a.release.MarkDeploymentFailed(condition.Message) - a.release.MarkReleaseFailed("Release deployment failed") - } else { - a.release.MarkDeploying(condition.Message) - } - } - - return a.client.Status().Patch(a.ctx, a.release, patch) -} - // registerProcessingData adds all the Release processing information to its Status and marks it as processing. func (a *adapter) registerProcessingData(releasePipelineRun *tektonv1.PipelineRun, roleBinding *rbac.RoleBinding) error { if releasePipelineRun == nil { diff --git a/controllers/release/adapter_test.go b/controllers/release/adapter_test.go index bc4d4153..55b9abe4 100644 --- a/controllers/release/adapter_test.go +++ b/controllers/release/adapter_test.go @@ -17,7 +17,6 @@ limitations under the License. package release import ( - "context" "encoding/json" "fmt" "os" @@ -60,13 +59,11 @@ var _ = Describe("Release adapter", Ordered, func() { component *applicationapiv1alpha1.Component enterpriseContractConfigMap *corev1.ConfigMap enterpriseContractPolicy *ecapiv1alpha1.EnterpriseContractPolicy - environment *applicationapiv1alpha1.Environment releasePlan *v1alpha1.ReleasePlan releasePlanAdmission *v1alpha1.ReleasePlanAdmission releaseServiceConfig *v1alpha1.ReleaseServiceConfig roleBinding *rbac.RoleBinding snapshot *applicationapiv1alpha1.Snapshot - snapshotEnvironmentBinding *applicationapiv1alpha1.SnapshotEnvironmentBinding ) AfterAll(func() { @@ -241,8 +238,6 @@ var _ = Describe("Release adapter", Ordered, func() { }) adapter.release.MarkProcessing("") adapter.release.MarkProcessed() - adapter.release.MarkDeploying("") - adapter.release.MarkDeployed() adapter.release.MarkReleaseFailed("") result, err := adapter.EnsureReleaseIsCompleted() Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) @@ -258,21 +253,6 @@ var _ = Describe("Release adapter", Ordered, func() { Expect(adapter.release.HasReleaseFinished()).To(BeFalse()) }) - It("should do nothing if a deployment is required and it's not complete", func() { - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.ReleasePlanAdmissionContextKey, - Resource: releasePlanAdmission, - }, - }) - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - result, err := adapter.EnsureReleaseIsCompleted() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - Expect(adapter.release.HasReleaseFinished()).To(BeFalse()) - }) - It("should complete the release if all the required phases have completed", func() { adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ { @@ -282,8 +262,6 @@ var _ = Describe("Release adapter", Ordered, func() { }) adapter.release.MarkProcessing("") adapter.release.MarkProcessed() - adapter.release.MarkDeploying("") - adapter.release.MarkDeployed() result, err := adapter.EnsureReleaseIsCompleted() Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) Expect(err).NotTo(HaveOccurred()) @@ -291,238 +269,6 @@ var _ = Describe("Release adapter", Ordered, func() { }) }) - When("EnsureReleaseIsDeployed is called", func() { - var adapter *adapter - - AfterEach(func() { - _ = adapter.client.Delete(ctx, adapter.release) - }) - - BeforeEach(func() { - adapter = createReleaseAndAdapter() - }) - - It("skips the operation if the Release processing has not succeeded yet", func() { - result, err := adapter.EnsureReleaseIsDeployed() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - - It("skips the operation if the Release has already being deployed", func() { - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - adapter.release.MarkDeploying("") - adapter.release.MarkDeployed() - - result, err := adapter.EnsureReleaseIsDeployed() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - - It("skips the operation if no environment is set in the ReleasePlanAdmission", func() { - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - - newReleasePlanAdmission := &v1alpha1.ReleasePlanAdmission{ - ObjectMeta: metav1.ObjectMeta{ - Name: "release-plan-admission", - Namespace: "default", - }, - Spec: v1alpha1.ReleasePlanAdmissionSpec{ - Applications: []string{"app"}, - Origin: "default", - Pipeline: &tektonutils.Pipeline{ - PipelineRef: tektonutils.PipelineRef{ - Resolver: "bundles", - Params: []tektonutils.Param{ - {Name: "bundle", Value: "quay.io/some/bundle"}, - {Name: "name", Value: "release-pipeline"}, - {Name: "kind", Value: "pipeline"}, - }, - }, - }, - Policy: enterpriseContractPolicy.Name, - }, - } - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.ReleasePlanAdmissionContextKey, - Resource: newReleasePlanAdmission, - }, - }) - - result, err := adapter.EnsureReleaseIsDeployed() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).To(BeEmpty()) - }) - - It("fails when the ReleasePlanAdmission is not present", func() { - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.ReleasePlanAdmissionContextKey, - Err: fmt.Errorf("not found"), - }, - }) - - result, err := adapter.EnsureReleaseIsDeployed() - Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("not found")) - }) - - It("updates the binding if one already exists", func() { - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.ReleasePlanAdmissionContextKey, - Resource: releasePlanAdmission, - }, - { - ContextKey: loader.SnapshotEnvironmentBindingContextKey, - Resource: snapshotEnvironmentBinding, - }, - { - ContextKey: loader.DeploymentResourcesContextKey, - Resource: &loader.DeploymentResources{ - Application: application, - ApplicationComponents: []applicationapiv1alpha1.Component{*component}, - Environment: environment, - Snapshot: snapshot, - }, - }, - }) - - result, err := adapter.EnsureReleaseIsDeployed() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).NotTo(BeEmpty()) - - binding, _ := adapter.loader.GetSnapshotEnvironmentBindingFromReleaseStatus(adapter.ctx, adapter.client, adapter.release) - Expect(binding).NotTo(BeNil()) - Expect(binding.Annotations).To(HaveLen(2)) - Expect(binding.Annotations[handler.NamespacedNameAnnotation]).To( - Equal(adapter.release.Namespace + "/" + adapter.release.Name), - ) - Expect(binding.Annotations[handler.TypeAnnotation]).To(Equal(adapter.release.Kind)) - }) - - It("creates a binding and updates the release status", func() { - adapter.release.MarkProcessing("") - adapter.release.MarkProcessed() - - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.ReleasePlanAdmissionContextKey, - Resource: releasePlanAdmission, - }, - { - ContextKey: loader.SnapshotEnvironmentBindingContextKey, - }, - { - ContextKey: loader.DeploymentResourcesContextKey, - Resource: &loader.DeploymentResources{ - Application: application, - ApplicationComponents: []applicationapiv1alpha1.Component{*component}, - Environment: environment, - Snapshot: snapshot, - }, - }, - }) - - result, err := adapter.EnsureReleaseIsDeployed() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).NotTo(BeEmpty()) - - // Restore the context to get the actual binding - adapter.ctx = context.TODO() - - binding, err := adapter.loader.GetSnapshotEnvironmentBindingFromReleaseStatus(adapter.ctx, adapter.client, adapter.release) - Expect(binding).NotTo(BeNil()) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient.Delete(ctx, binding)).Should(Succeed()) - }) - }) - - When("EnsureReleaseDeploymentIsTracked is called", func() { - var adapter *adapter - - AfterEach(func() { - _ = adapter.client.Delete(ctx, adapter.release) - }) - - BeforeEach(func() { - adapter = createReleaseAndAdapter() - }) - - It("skips the operation if the deployment has not started yet", func() { - result, err := adapter.EnsureReleaseDeploymentIsTracked() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - - It("skips the operation if the deployment has finished", func() { - adapter.release.MarkDeploying("") - adapter.release.MarkDeployed() - - result, err := adapter.EnsureReleaseDeploymentIsTracked() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - - It("fails if the binding is not found", func() { - adapter.release.MarkDeploying("") - adapter.release.Status.Deployment.SnapshotEnvironmentBinding = "not/found" - - result, err := adapter.EnsureReleaseDeploymentIsTracked() - Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).To(HaveOccurred()) - }) - - It("skips the operation if the binding isn't owned by the release", func() { - adapter.release.MarkDeploying("") - - newSnapshotEnvironmentBinding := snapshotEnvironmentBinding.DeepCopy() - newSnapshotEnvironmentBinding.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionTrue, - Reason: "Deployed", - }, - } - newSnapshotEnvironmentBinding.Annotations = map[string]string{ - handler.TypeAnnotation: adapter.release.Kind, - handler.NamespacedNameAnnotation: "other-release", - } - adapter.release.Status.Deployment.SnapshotEnvironmentBinding = newSnapshotEnvironmentBinding.Namespace + "/" + newSnapshotEnvironmentBinding.Name - - result, err := adapter.EnsureReleaseDeploymentIsTracked() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - - It("tracks the binding if one is found", func() { - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.SnapshotEnvironmentBindingContextKey, - Resource: snapshotEnvironmentBinding, - }, - }) - adapter.release.MarkDeploying("") - adapter.release.Status.Deployment.SnapshotEnvironmentBinding = snapshotEnvironmentBinding.Namespace + "/" + snapshotEnvironmentBinding.Name - - result, err := adapter.EnsureReleaseDeploymentIsTracked() - Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) - Expect(err).NotTo(HaveOccurred()) - }) - }) - When("EnsureReleaseIsRunning is called", func() { var adapter *adapter @@ -707,7 +453,6 @@ var _ = Describe("Release adapter", Ordered, func() { Spec: v1alpha1.ReleasePlanAdmissionSpec{ Applications: []string{application.Name}, Origin: "default", - Environment: environment.Name, Pipeline: &tektonutils.Pipeline{ PipelineRef: tektonutils.PipelineRef{ Resolver: "git", @@ -1198,89 +943,6 @@ var _ = Describe("Release adapter", Ordered, func() { }) }) - When("createOrUpdateSnapshotEnvironmentBinding is called", func() { - var adapter *adapter - - AfterEach(func() { - _ = adapter.client.Delete(ctx, adapter.release) - }) - - BeforeEach(func() { - adapter = createReleaseAndAdapter() - }) - - It("fails when the required resources are not present", func() { - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.DeploymentResourcesContextKey, - Err: fmt.Errorf("not found"), - }, - }) - - _, err := adapter.createOrUpdateSnapshotEnvironmentBinding(releasePlanAdmission) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("not found")) - }) - - It("creates a new binding owned by the release if the required resources are present", func() { - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.SnapshotEnvironmentBindingContextKey, - }, - { - ContextKey: loader.DeploymentResourcesContextKey, - Resource: &loader.DeploymentResources{ - Application: application, - ApplicationComponents: []applicationapiv1alpha1.Component{*component}, - Environment: environment, - Snapshot: snapshot, - }, - }, - }) - - binding, err := adapter.createOrUpdateSnapshotEnvironmentBinding(releasePlanAdmission) - Expect(binding).NotTo(BeNil()) - Expect(err).NotTo(HaveOccurred()) - - Expect(binding.OwnerReferences).To(HaveLen(1)) - Expect(binding.Annotations).To(HaveLen(2)) - Expect(binding.Annotations[handler.NamespacedNameAnnotation]).To( - Equal(adapter.release.Namespace + "/" + adapter.release.Name), - ) - Expect(binding.Annotations[handler.TypeAnnotation]).To(Equal(adapter.release.Kind)) - - Expect(k8sClient.Delete(ctx, binding)).Should(Succeed()) - }) - - It("updates a binding and marks it as owned by the release if a binding is already present", func() { - adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: loader.SnapshotEnvironmentBindingContextKey, - Resource: snapshotEnvironmentBinding, - }, - { - ContextKey: loader.DeploymentResourcesContextKey, - Resource: &loader.DeploymentResources{ - Application: application, - ApplicationComponents: []applicationapiv1alpha1.Component{*component}, - Environment: environment, - Snapshot: snapshot, - }, - }, - }) - - binding, err := adapter.createOrUpdateSnapshotEnvironmentBinding(releasePlanAdmission) - Expect(binding).NotTo(BeNil()) - Expect(err).NotTo(HaveOccurred()) - - Expect(binding.Annotations).To(HaveLen(2)) - Expect(binding.Annotations[handler.NamespacedNameAnnotation]).To( - Equal(adapter.release.Namespace + "/" + adapter.release.Name), - ) - Expect(binding.Annotations[handler.TypeAnnotation]).To(Equal(adapter.release.Kind)) - }) - }) - When("createRoleBindingForClusterRole is called", func() { var adapter *adapter @@ -1301,7 +963,6 @@ var _ = Describe("Release adapter", Ordered, func() { Spec: v1alpha1.ReleasePlanAdmissionSpec{ Applications: []string{application.Name}, Origin: "default", - Environment: environment.Name, Pipeline: &tektonutils.Pipeline{ PipelineRef: tektonutils.PipelineRef{ Resolver: "git", @@ -1393,115 +1054,6 @@ var _ = Describe("Release adapter", Ordered, func() { }) }) - When("registerDeploymentData is called", func() { - var adapter *adapter - - AfterEach(func() { - _ = adapter.client.Delete(ctx, adapter.release) - }) - - BeforeEach(func() { - adapter = createReleaseAndAdapter() - }) - - It("does nothing if there is no binding", func() { - Expect(adapter.registerDeploymentData(nil, releasePlanAdmission)).To(Succeed()) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).To(BeEmpty()) - }) - - It("does nothing if there is no ReleasePlanAdmission", func() { - Expect(adapter.registerDeploymentData(snapshotEnvironmentBinding, nil)).To(Succeed()) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).To(BeEmpty()) - }) - - It("registers the Release deployment data", func() { - Expect(adapter.registerDeploymentData(snapshotEnvironmentBinding, releasePlanAdmission)).To(Succeed()) - Expect(adapter.release.Status.Deployment.Environment).To(Equal(fmt.Sprintf("%s%c%s", - releasePlanAdmission.Namespace, types.Separator, releasePlanAdmission.Spec.Environment))) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).To(Equal(fmt.Sprintf("%s%c%s", - snapshotEnvironmentBinding.Namespace, types.Separator, snapshotEnvironmentBinding.Name))) - Expect(adapter.release.IsDeploying()).To(BeTrue()) - }) - - It("should not register the environment if the ReleasePlanAdmission does not reference any", func() { - newReleasePlanAdmission := releasePlanAdmission.DeepCopy() - newReleasePlanAdmission.Spec.Environment = "" - - Expect(adapter.registerDeploymentData(snapshotEnvironmentBinding, newReleasePlanAdmission)).To(Succeed()) - Expect(adapter.release.Status.Deployment.Environment).To(Equal("")) - Expect(adapter.release.Status.Deployment.SnapshotEnvironmentBinding).To(Equal(fmt.Sprintf("%s%c%s", - snapshotEnvironmentBinding.Namespace, types.Separator, snapshotEnvironmentBinding.Name))) - Expect(adapter.release.IsDeploying()).To(BeTrue()) - }) - }) - - When("registerDeploymentStatus is called", func() { - var adapter *adapter - - AfterEach(func() { - _ = adapter.client.Delete(ctx, adapter.release) - }) - - BeforeEach(func() { - adapter = createReleaseAndAdapter() - }) - - It("does nothing if there is no binding", func() { - Expect(adapter.registerDeploymentStatus(nil)).To(Succeed()) - Expect(adapter.release.IsDeploying()).To(BeFalse()) - }) - - It("does nothing if the binding doesn't have the expected condition", func() { - Expect(adapter.registerDeploymentStatus(snapshotEnvironmentBinding)).To(Succeed()) - Expect(adapter.release.IsDeploying()).To(BeFalse()) - }) - - It("registers the deployment status when the the deployment succeeded deployed", func() { - adapter.release.MarkDeploying("") - newSnapshotEnvironmentBinding := snapshotEnvironmentBinding.DeepCopy() - newSnapshotEnvironmentBinding.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionTrue, - Reason: "Deployed", - }, - } - Expect(adapter.registerDeploymentStatus(newSnapshotEnvironmentBinding)).To(Succeed()) - Expect(adapter.release.HasDeploymentFinished()).To(BeTrue()) - Expect(adapter.release.IsDeployed()).To(BeTrue()) - }) - - It("registers the deployment status when the deployment failed", func() { - adapter.release.MarkDeploying("") - newSnapshotEnvironmentBinding := snapshotEnvironmentBinding.DeepCopy() - newSnapshotEnvironmentBinding.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionFalse, - Reason: applicationapiv1alpha1.ComponentDeploymentConditionErrorOccurred, - }, - } - Expect(adapter.registerDeploymentStatus(newSnapshotEnvironmentBinding)).To(Succeed()) - Expect(adapter.release.HasDeploymentFinished()).To(BeTrue()) - Expect(adapter.release.IsDeployed()).To(BeFalse()) - Expect(adapter.release.IsReleased()).To(BeFalse()) - }) - - It("registers the deployment status when the deployment is progressing", func() { - adapter.release.MarkDeploying("") - newSnapshotEnvironmentBinding := snapshotEnvironmentBinding.DeepCopy() - newSnapshotEnvironmentBinding.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionFalse, - Reason: "Deploying", - }, - } - Expect(adapter.registerDeploymentStatus(newSnapshotEnvironmentBinding)).To(Succeed()) - Expect(adapter.release.HasDeploymentFinished()).To(BeFalse()) - }) - }) - When("registerProcessingData is called", func() { var adapter *adapter @@ -1903,7 +1455,6 @@ var _ = Describe("Release adapter", Ordered, func() { Spec: v1alpha1.ReleasePlanAdmissionSpec{ Applications: []string{application.Name}, Origin: "default", - Environment: environment.Name, Pipeline: &tektonutils.Pipeline{ PipelineRef: tektonutils.PipelineRef{ Resolver: "cluster", @@ -2022,22 +1573,6 @@ var _ = Describe("Release adapter", Ordered, func() { Expect(k8sClient.Create(ctx, enterpriseContractPolicy)).Should(Succeed()) enterpriseContractPolicy.Kind = "EnterpriseContractPolicy" - environment = &applicationapiv1alpha1.Environment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "environment", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.EnvironmentSpec{ - DeploymentStrategy: applicationapiv1alpha1.DeploymentStrategy_Manual, - DisplayName: "production", - Type: applicationapiv1alpha1.EnvironmentType_POC, - Configuration: applicationapiv1alpha1.EnvironmentConfiguration{ - Env: []applicationapiv1alpha1.EnvVarPair{}, - }, - }, - } - Expect(k8sClient.Create(ctx, environment)).Should(Succeed()) - releasePlan = &v1alpha1.ReleasePlan{ ObjectMeta: metav1.ObjectMeta{ Name: "release-plan", @@ -2071,7 +1606,6 @@ var _ = Describe("Release adapter", Ordered, func() { Spec: v1alpha1.ReleasePlanAdmissionSpec{ Applications: []string{application.Name}, Origin: "default", - Environment: environment.Name, Pipeline: &tektonutils.Pipeline{ PipelineRef: tektonutils.PipelineRef{ Resolver: "git", @@ -2116,20 +1650,6 @@ var _ = Describe("Release adapter", Ordered, func() { } Expect(k8sClient.Create(ctx, snapshot)).To(Succeed()) snapshot.Kind = "Snapshot" - - snapshotEnvironmentBinding = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "snapshot-environment-binding", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: application.Name, - Environment: environment.Name, - Snapshot: snapshot.Name, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - Expect(k8sClient.Create(ctx, snapshotEnvironmentBinding)).To(Succeed()) } deleteResources = func() { @@ -2137,12 +1657,10 @@ var _ = Describe("Release adapter", Ordered, func() { Expect(k8sClient.Delete(ctx, component)).Should(Succeed()) Expect(k8sClient.Delete(ctx, enterpriseContractConfigMap)).Should(Succeed()) Expect(k8sClient.Delete(ctx, enterpriseContractPolicy)).Should(Succeed()) - Expect(k8sClient.Delete(ctx, environment)).Should(Succeed()) Expect(k8sClient.Delete(ctx, releasePlan)).To(Succeed()) Expect(k8sClient.Delete(ctx, releasePlanAdmission)).Should(Succeed()) Expect(k8sClient.Delete(ctx, releaseServiceConfig)).Should(Succeed()) Expect(k8sClient.Delete(ctx, snapshot)).To(Succeed()) - Expect(k8sClient.Delete(ctx, snapshotEnvironmentBinding)).To(Succeed()) } }) diff --git a/controllers/release/controller.go b/controllers/release/controller.go index ae928cfd..04485927 100644 --- a/controllers/release/controller.go +++ b/controllers/release/controller.go @@ -28,10 +28,8 @@ import ( applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" "github.com/redhat-appstudio/release-service/api/v1alpha1" "github.com/redhat-appstudio/release-service/cache" - "github.com/redhat-appstudio/release-service/gitops" "github.com/redhat-appstudio/release-service/loader" "github.com/redhat-appstudio/release-service/tekton" - tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" @@ -85,8 +83,6 @@ func (c *Controller) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu adapter.EnsureReleaseExpirationTimeIsAdded, adapter.EnsureReleaseIsProcessed, adapter.EnsureReleaseProcessingIsTracked, - adapter.EnsureReleaseIsDeployed, - adapter.EnsureReleaseDeploymentIsTracked, adapter.EnsureReleaseIsCompleted, }) } @@ -105,12 +101,6 @@ func (c *Controller) Register(mgr ctrl.Manager, log *logr.Logger, _ cluster.Clus Kind: "Release", Group: "appstudio.redhat.com", }, - }, builder.WithPredicates(predicates.GenerationUnchangedOnUpdatePredicate{}, gitops.DeploymentFinishedPredicate())). - Watches(&tektonv1.PipelineRun{}, &libhandler.EnqueueRequestForAnnotation{ - Type: schema.GroupKind{ - Kind: "Release", - Group: "appstudio.redhat.com", - }, }, builder.WithPredicates(tekton.ReleasePipelineRunSucceededPredicate())). Complete(c) } @@ -124,9 +114,5 @@ func (c *Controller) SetupCache(mgr ctrl.Manager) error { // NOTE: Both the release and releaseplan controller need this ReleasePlanAdmission cache. However, it only needs to be added // once to the manager, so only one controller should add it. If it is removed here, it should be added to the ReleasePlan controller. - if err := cache.SetupReleasePlanAdmissionCache(mgr); err != nil { - return err - } - - return cache.SetupSnapshotEnvironmentBindingCache(mgr) + return cache.SetupReleasePlanAdmissionCache(mgr) } diff --git a/controllers/release/controller_test.go b/controllers/release/controller_test.go index f367a59b..d371d33e 100644 --- a/controllers/release/controller_test.go +++ b/controllers/release/controller_test.go @@ -18,6 +18,7 @@ package release import ( "reflect" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" . "github.com/onsi/ginkgo/v2" diff --git a/gitops/binding.go b/gitops/binding.go deleted file mode 100644 index 9bd7a6c8..00000000 --- a/gitops/binding.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "math" -) - -// NewSnapshotEnvironmentBinding creates a new SnapshotEnvironmentBinding. -func NewSnapshotEnvironmentBinding(components []applicationapiv1alpha1.Component, snapshot *applicationapiv1alpha1.Snapshot, environment *applicationapiv1alpha1.Environment) *applicationapiv1alpha1.SnapshotEnvironmentBinding { - return &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: v1.ObjectMeta{ - GenerateName: environment.Name + "-", - Namespace: environment.Namespace, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: snapshot.Spec.Application, - Environment: environment.Name, - Snapshot: snapshot.Name, - Components: getComponentBindings(components), - }, - } -} - -// getComponentBindings returns a list of BindingComponents created by using the information of the given Components. -func getComponentBindings(components []applicationapiv1alpha1.Component) []applicationapiv1alpha1.BindingComponent { - var bindingComponents []applicationapiv1alpha1.BindingComponent - - for _, component := range components { - var replicas int - if component.Spec.Replicas != nil { - replicas = int(math.Max(1, float64(*component.Spec.Replicas))) - } else { - replicas = 1 - } - bindingComponents = append(bindingComponents, applicationapiv1alpha1.BindingComponent{ - Name: component.Name, - Configuration: applicationapiv1alpha1.BindingComponentConfiguration{ - Replicas: &replicas, - }, - }) - } - - return bindingComponents -} diff --git a/gitops/binding_test.go b/gitops/binding_test.go deleted file mode 100644 index 718dbe6d..00000000 --- a/gitops/binding_test.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2022 Red Hat Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "math" - "reflect" -) - -var _ = Describe("Binding", func() { - var replicas int = 2 - - components := []applicationapiv1alpha1.Component{ - { - Spec: applicationapiv1alpha1.ComponentSpec{ - Application: "app", - ComponentName: "foo", - Source: applicationapiv1alpha1.ComponentSource{ - ComponentSourceUnion: applicationapiv1alpha1.ComponentSourceUnion{ - GitSource: &applicationapiv1alpha1.GitSource{ - URL: "https://foo", - }, - }, - }, - }, - }, - { - Spec: applicationapiv1alpha1.ComponentSpec{ - Application: "app", - ComponentName: "bar", - Replicas: &replicas, - Source: applicationapiv1alpha1.ComponentSource{ - ComponentSourceUnion: applicationapiv1alpha1.ComponentSourceUnion{ - GitSource: &applicationapiv1alpha1.GitSource{ - URL: "https://foo", - }, - }, - }, - }, - }, - } - - environment := &applicationapiv1alpha1.Environment{ - ObjectMeta: v1.ObjectMeta{ - Name: "environment", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.EnvironmentSpec{ - DeploymentStrategy: applicationapiv1alpha1.DeploymentStrategy_Manual, - DisplayName: "production", - Type: applicationapiv1alpha1.EnvironmentType_POC, - }, - } - - snapshot := &applicationapiv1alpha1.Snapshot{ - ObjectMeta: v1.ObjectMeta{ - GenerateName: "snapshot-", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.SnapshotSpec{ - Application: "app", - Components: []applicationapiv1alpha1.SnapshotComponent{}, - }, - } - - When("calling getComponentBindings with a list of Components", func() { - bindingComponents := getComponentBindings(components) - - It("can create and return a new BindingComponent slice", func() { - Expect(reflect.TypeOf(bindingComponents)).To(Equal(reflect.TypeOf([]applicationapiv1alpha1.BindingComponent{}))) - Expect(len(bindingComponents)).To(Equal(len(components))) - }) - - It("respect the number of replicas defined in the components", func() { - for i, component := range components { - var replicas int - if component.Spec.Replicas != nil { - replicas = int(math.Max(1, float64(*component.Spec.Replicas))) - } else { - replicas = 1 - } - Expect(bindingComponents[i].Configuration.Replicas).To(Equal(&replicas)) - } - }) - }) - - When("calling NewSnapshotEnvironmentBinding", func() { - It("can create and return a new SnapshotEnvironmentBinding", func() { - binding := NewSnapshotEnvironmentBinding(components, snapshot, environment) - Expect(reflect.TypeOf(binding)).To(Equal(reflect.TypeOf(&applicationapiv1alpha1.SnapshotEnvironmentBinding{}))) - Expect(*binding).To(MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": MatchFields(IgnoreExtras, Fields{ - "GenerateName": Equal(environment.Name + "-"), - "Namespace": Equal(environment.Namespace), - }), - "Spec": MatchFields(IgnoreExtras, Fields{ - "Application": Equal(snapshot.Spec.Application), - "Environment": Equal(environment.Name), - "Snapshot": Equal(snapshot.Name), - "Components": HaveLen(len(components)), - }), - })) - }) - }) -}) diff --git a/gitops/predicates.go b/gitops/predicates.go deleted file mode 100644 index 2ff7f3ef..00000000 --- a/gitops/predicates.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -// DeploymentFinishedPredicate returns a predicate which filters out update events to a -// SnapshotEnvironmentBinding where the component deployment status goes from unknown to true/false. -func DeploymentFinishedPredicate() predicate.Predicate { - return predicate.Funcs{ - UpdateFunc: func(e event.UpdateEvent) bool { - return hasDeploymentFinished(e.ObjectOld, e.ObjectNew) - }, - } -} diff --git a/gitops/predicates_test.go b/gitops/predicates_test.go deleted file mode 100644 index 6232af9e..00000000 --- a/gitops/predicates_test.go +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright 2022 Red Hat Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/event" - - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -var _ = Describe("Predicates", Ordered, func() { - - const ( - namespace = "default" - applicationName = "test-application" - environmentName = "test-environment" - snapshotName = "test-snapshot" - ) - - var bindingNoStatus, bindingTrueStatus, bindingUnknownStatus *applicationapiv1alpha1.SnapshotEnvironmentBinding - - BeforeAll(func() { - bindingNoStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingnostatus", - Namespace: namespace, - Generation: 1, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - bindingTrueStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingtruestatus", - Namespace: namespace, - Generation: 1, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - bindingUnknownStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingunknownstatus", - Namespace: namespace, - Generation: 1, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - ctx := context.Background() - - Expect(k8sClient.Create(ctx, bindingNoStatus)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingTrueStatus)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingUnknownStatus)).Should(Succeed()) - - // Set the binding statuses after they are created - bindingTrueStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionTrue, - }, - } - bindingUnknownStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionUnknown, - }, - } - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, bindingNoStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingTrueStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingUnknownStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - }) - - When("testing DeploymentFinishedPredicate predicate", func() { - instance := DeploymentFinishedPredicate() - - It("returns true when the old SnapshotEnvironmentBinding has no AllComponentsDeployed status and the new one has true status", func() { - contextEvent := event.UpdateEvent{ - ObjectOld: bindingNoStatus, - ObjectNew: bindingTrueStatus, - } - Expect(instance.Update(contextEvent)).To(BeTrue()) - }) - - It("returns true when the old SnapshotEnvironmentBinding has unknown status and the new one has true status", func() { - contextEvent := event.UpdateEvent{ - ObjectOld: bindingUnknownStatus, - ObjectNew: bindingTrueStatus, - } - Expect(instance.Update(contextEvent)).To(BeTrue()) - }) - }) -}) diff --git a/gitops/suite_test.go b/gitops/suite_test.go deleted file mode 100644 index 1e03a882..00000000 --- a/gitops/suite_test.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2022 Red Hat Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - "context" - "go/build" - "path/filepath" - "testing" - - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - "github.com/redhat-appstudio/operator-toolkit/test" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - appstudiov1alpha1 "github.com/redhat-appstudio/release-service/api/v1alpha1" - clientsetscheme "k8s.io/client-go/kubernetes/scheme" - - logf "sigs.k8s.io/controller-runtime/pkg/log" - //+kubebuilder:scaffold:imports -) - -var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - ctx context.Context - cancel context.CancelFunc -) - -func Test(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "GitOps Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancel = context.WithCancel(context.TODO()) - - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "config", "crd", "bases"), - filepath.Join( - build.Default.GOPATH, - "pkg", "mod", test.GetRelativeDependencyPath("application-api"), "config", "crd", "bases", - ), - }, - ErrorIfCRDPathMissing: true, - } - - var err error - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = appstudiov1alpha1.AddToScheme(clientsetscheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = applicationapiv1alpha1.AddToScheme(clientsetscheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - k8sClient, err = client.New(cfg, client.Options{ - Scheme: clientsetscheme.Scheme, - }) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) -}) - -var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/gitops/utils.go b/gitops/utils.go deleted file mode 100644 index 206ab6a4..00000000 --- a/gitops/utils.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// hasDeploymentFinished returns a boolean that is only true if the first passed object -// is a SnapshotEnvironmentBinding with the componentDeployment status missing or not true and the -// second passed object is a SnapshotEnvironmentBinding with the componentDeployment status True/False. -func hasDeploymentFinished(objectOld, objectNew client.Object) bool { - var ok bool - var oldBinding, newBinding *applicationapiv1alpha1.SnapshotEnvironmentBinding - var oldCondition, newCondition *metav1.Condition - - if oldBinding, ok = objectOld.(*applicationapiv1alpha1.SnapshotEnvironmentBinding); !ok { - return false - } - if newBinding, ok = objectNew.(*applicationapiv1alpha1.SnapshotEnvironmentBinding); !ok { - return false - } - - oldCondition = meta.FindStatusCondition(oldBinding.Status.ComponentDeploymentConditions, - applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed) - - newCondition = meta.FindStatusCondition(newBinding.Status.ComponentDeploymentConditions, - applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed) - - return (oldCondition == nil || oldCondition.Status != metav1.ConditionTrue) && - (newCondition != nil && newCondition.Status != metav1.ConditionUnknown) -} diff --git a/gitops/utils_test.go b/gitops/utils_test.go deleted file mode 100644 index 12f85c05..00000000 --- a/gitops/utils_test.go +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright 2022 Red Hat Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gitops - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -var _ = Describe("Utils", Ordered, func() { - const ( - namespace = "default" - applicationName = "test-application" - environmentName = "test-environment" - snapshotName = "test-snapshot" - ) - - var pod *corev1.Pod - var bindingFalseStatus, bindingMissingComponentStatus, - bindingTrueStatus, bindingUnknownStatus *applicationapiv1alpha1.SnapshotEnvironmentBinding - - BeforeAll(func() { - pod = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - GenerateName: "testpod-", - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "test", - Image: "test", - }, - }, - }, - } - bindingFalseStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingfalsestatus", - Namespace: namespace, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - bindingMissingComponentStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingmissingcomponentstatus", - Namespace: namespace, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - bindingTrueStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingtruestatus", - Namespace: namespace, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - bindingUnknownStatus = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bindingunknownstatus", - Namespace: namespace, - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: applicationName, - Environment: environmentName, - Snapshot: snapshotName, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - ctx := context.Background() - - Expect(k8sClient.Create(ctx, pod)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingFalseStatus)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingMissingComponentStatus)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingTrueStatus)).Should(Succeed()) - Expect(k8sClient.Create(ctx, bindingUnknownStatus)).Should(Succeed()) - - // Set the AllComponentsDeployed status of the bindings after they are created - bindingFalseStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionFalse, - }, - } - bindingTrueStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionTrue, - }, - } - bindingUnknownStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionAllComponentsDeployed, - Status: metav1.ConditionUnknown, - }, - } - // After it is created, set the status of the missing component status binding to include a - // ComponentDeploymentCondition status, but not the AllComponentsDeployed condition - bindingMissingComponentStatus.Status.ComponentDeploymentConditions = []metav1.Condition{ - { - Type: applicationapiv1alpha1.ComponentDeploymentConditionCommitsSynced, - Status: metav1.ConditionTrue, - }, - } - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, pod) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingFalseStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingMissingComponentStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingTrueStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - err = k8sClient.Delete(ctx, bindingUnknownStatus) - Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) - }) - - When("using utility functions on SnapshotEnvironmentBinding objects", func() { - It("returns false when called with an old object that isn't a SnapshotEnvironmentBinding", func() { - Expect(hasDeploymentFinished(pod, bindingTrueStatus)).To(Equal(false)) - }) - - It("returns false when called with a new object that isn't a SnapshotEnvironmentBinding", func() { - Expect(hasDeploymentFinished(bindingTrueStatus, pod)).To(Equal(false)) - }) - - It("returns false when the new SnapshotEnvironmentBinding has no status field", func() { - Expect(hasDeploymentFinished(bindingTrueStatus, bindingMissingComponentStatus)).To(Equal(false)) - }) - - It("returns false when the new SnapshotEnvironmentBinding does not have status set to true or false", func() { - Expect(hasDeploymentFinished(bindingUnknownStatus, bindingUnknownStatus)).To(Equal(false)) - }) - - It("returns false when the old SnapshotEnvironmentBinding has no AllComponentsDeployed status and the new one has unknown status", func() { - Expect(hasDeploymentFinished(bindingMissingComponentStatus, bindingUnknownStatus)).To(Equal(false)) - }) - - It("returns true when the old SnapshotEnvironmentBinding has unknown status and the new one has false status", func() { - Expect(hasDeploymentFinished(bindingUnknownStatus, bindingFalseStatus)).To(Equal(true)) - }) - - It("returns true when the old SnapshotEnvironmentBinding has unknown status and the new one has true status", func() { - Expect(hasDeploymentFinished(bindingUnknownStatus, bindingTrueStatus)).To(Equal(true)) - }) - - It("returns true when the old SnapshotEnvironmentBinding has no AllComponentsDeployed status and the new one has false status", func() { - Expect(hasDeploymentFinished(bindingMissingComponentStatus, bindingFalseStatus)).To(Equal(true)) - }) - - It("returns true when the old SnapshotEnvironmentBinding has no AllComponentsDeployed status and the new one has true status", func() { - Expect(hasDeploymentFinished(bindingMissingComponentStatus, bindingTrueStatus)).To(Equal(true)) - }) - }) -}) diff --git a/loader/loader.go b/loader/loader.go index ee1c3d89..c86f3434 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -27,9 +27,6 @@ type ObjectLoader interface { GetApplication(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*applicationapiv1alpha1.Application, error) GetEnterpriseContractConfigMap(ctx context.Context, cli client.Client) (*corev1.ConfigMap, error) GetEnterpriseContractPolicy(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*ecapiv1alpha1.EnterpriseContractPolicy, error) - GetEnvironment(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.Environment, error) - GetManagedApplication(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*applicationapiv1alpha1.Application, error) - GetManagedApplicationComponents(ctx context.Context, cli client.Client, application *applicationapiv1alpha1.Application) ([]applicationapiv1alpha1.Component, error) GetMatchingReleasePlanAdmission(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*v1alpha1.ReleasePlanAdmission, error) GetMatchingReleasePlans(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*v1alpha1.ReleasePlanList, error) GetRelease(ctx context.Context, cli client.Client, name, namespace string) (*v1alpha1.Release, error) @@ -38,9 +35,6 @@ type ObjectLoader interface { GetReleasePlan(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*v1alpha1.ReleasePlan, error) GetReleaseServiceConfig(ctx context.Context, cli client.Client, name, namespace string) (*v1alpha1.ReleaseServiceConfig, error) GetSnapshot(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*applicationapiv1alpha1.Snapshot, error) - GetSnapshotEnvironmentBinding(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) - GetSnapshotEnvironmentBindingFromReleaseStatus(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) - GetDeploymentResources(ctx context.Context, cli client.Client, release *v1alpha1.Release, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*DeploymentResources, error) GetProcessingResources(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*ProcessingResources, error) } @@ -111,33 +105,6 @@ func (l *loader) GetEnterpriseContractConfigMap(ctx context.Context, cli client. } -// GetEnvironment returns the Environment referenced by the given ReleasePlanAdmission. If the Environment is not found -// or the Get operation fails, an error will be returned. -func (l *loader) GetEnvironment(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.Environment, error) { - environment := &applicationapiv1alpha1.Environment{} - return environment, toolkit.GetObject(releasePlanAdmission.Spec.Environment, releasePlanAdmission.Namespace, cli, ctx, environment) -} - -// GetManagedApplication returns the Application referenced by the ReleasePlanAdmission. If the Application is not found or -// the Get operation fails, an error will be returned. -func (l *loader) GetManagedApplication(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*applicationapiv1alpha1.Application, error) { - application := &applicationapiv1alpha1.Application{} - return application, toolkit.GetObject(releasePlan.Spec.Application, releasePlan.Spec.Target, cli, ctx, application) -} - -// GetManagedApplicationComponents returns a list of all the Components associated with the given Application. -func (l *loader) GetManagedApplicationComponents(ctx context.Context, cli client.Client, application *applicationapiv1alpha1.Application) ([]applicationapiv1alpha1.Component, error) { - applicationComponents := &applicationapiv1alpha1.ComponentList{} - err := cli.List(ctx, applicationComponents, - client.InNamespace(application.Namespace), - client.MatchingFields{"spec.application": application.Name}) - if err != nil { - return nil, err - } - - return applicationComponents.Items, nil -} - // GetMatchingReleasePlanAdmission returns the ReleasePlanAdmission targeted by the given ReleasePlan. // If a matching ReleasePlanAdmission is not found or the List operation fails, an error will be returned. // If more than one matching ReleasePlanAdmission objects are found, an error will be returned. @@ -268,92 +235,6 @@ func (l *loader) GetSnapshot(ctx context.Context, cli client.Client, release *v1 return snapshot, toolkit.GetObject(release.Spec.Snapshot, release.Namespace, cli, ctx, snapshot) } -// GetSnapshotEnvironmentBinding returns the SnapshotEnvironmentBinding associated with the given ReleasePlanAdmission. -// That association is defined by both the Environment and Application matching between the ReleasePlanAdmission and -// the SnapshotEnvironmentBinding. If the Get operation fails, an error will be returned. -func (l *loader) GetSnapshotEnvironmentBinding(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) { - bindingList := &applicationapiv1alpha1.SnapshotEnvironmentBindingList{} - err := cli.List(ctx, bindingList, - client.InNamespace(releasePlanAdmission.Namespace), - client.MatchingFields{"spec.environment": releasePlanAdmission.Spec.Environment}) - if err != nil { - return nil, err - } - - for _, binding := range bindingList.Items { - if slices.Contains(releasePlanAdmission.Spec.Applications, binding.Spec.Application) { - return &binding, nil - } - } - - return nil, nil -} - -// GetSnapshotEnvironmentBindingFromReleaseStatus returns the SnapshotEnvironmentBinding associated with the given Release. -// That association is defined by namespaced name stored in the Release's status. -func (l *loader) GetSnapshotEnvironmentBindingFromReleaseStatus(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) { - binding := &applicationapiv1alpha1.SnapshotEnvironmentBinding{} - bindingNamespacedName := strings.Split(release.Status.Deployment.SnapshotEnvironmentBinding, string(types.Separator)) - if len(bindingNamespacedName) != 2 { - return nil, fmt.Errorf("release doesn't contain a valid reference to an SnapshotEnvironmentBinding ('%s')", - release.Status.Deployment.SnapshotEnvironmentBinding) - } - - err := cli.Get(ctx, types.NamespacedName{ - Namespace: bindingNamespacedName[0], - Name: bindingNamespacedName[1], - }, binding) - - if err != nil { - return nil, err - } - - return binding, nil -} - -// Composite functions - -// DeploymentResources contains the required resources to trigger a deployment. -type DeploymentResources struct { - Application *applicationapiv1alpha1.Application - ApplicationComponents []applicationapiv1alpha1.Component - Environment *applicationapiv1alpha1.Environment - Snapshot *applicationapiv1alpha1.Snapshot -} - -// GetDeploymentResources returns all the resources required to trigger a deployment. If any of those resources cannot -// be retrieved from the cluster, an error will be returned. -func (l *loader) GetDeploymentResources(ctx context.Context, cli client.Client, release *v1alpha1.Release, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*DeploymentResources, error) { - resources := &DeploymentResources{} - - releasePlan, err := l.GetReleasePlan(ctx, cli, release) - if err != nil { - return resources, err - } - - resources.Application, err = l.GetManagedApplication(ctx, cli, releasePlan) - if err != nil { - return resources, err - } - - resources.ApplicationComponents, err = l.GetManagedApplicationComponents(ctx, cli, resources.Application) - if err != nil { - return resources, err - } - - resources.Environment, err = l.GetEnvironment(ctx, cli, releasePlanAdmission) - if err != nil { - return resources, err - } - - resources.Snapshot, err = l.GetSnapshot(ctx, cli, release) - if err != nil { - return resources, err - } - - return resources, nil -} - // ProcessingResources contains the required resources to process the Release. type ProcessingResources struct { EnterpriseContractConfigMap *corev1.ConfigMap diff --git a/loader/loader_mock.go b/loader/loader_mock.go index 09842210..652234bc 100644 --- a/loader/loader_mock.go +++ b/loader/loader_mock.go @@ -17,10 +17,8 @@ import ( const ( ApplicationComponentsContextKey toolkit.ContextKey = iota ApplicationContextKey - DeploymentResourcesContextKey EnterpriseContractConfigMapContextKey EnterpriseContractPolicyContextKey - EnvironmentContextKey MatchedReleasePlansContextKey MatchedReleasePlanAdmissionContextKey ProcessingResourcesContextKey @@ -31,7 +29,6 @@ const ( ReleaseServiceConfigContextKey RoleBindingContextKey SnapshotContextKey - SnapshotEnvironmentBindingContextKey ) type mockLoader struct { @@ -84,30 +81,6 @@ func (l *mockLoader) GetEnterpriseContractConfigMap(ctx context.Context, cli cli return toolkit.GetMockedResourceAndErrorFromContext(ctx, EnterpriseContractConfigMapContextKey, &corev1.ConfigMap{}) } -// GetEnvironment returns the resource and error passed as values of the context. -func (l *mockLoader) GetEnvironment(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.Environment, error) { - if ctx.Value(EnvironmentContextKey) == nil { - return l.loader.GetEnvironment(ctx, cli, releasePlanAdmission) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, EnvironmentContextKey, &applicationapiv1alpha1.Environment{}) -} - -// GetManagedApplication returns the resource and error passed as values of the context. -func (l *mockLoader) GetManagedApplication(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*applicationapiv1alpha1.Application, error) { - if ctx.Value(ApplicationContextKey) == nil { - return l.loader.GetManagedApplication(ctx, cli, releasePlan) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, ApplicationContextKey, &applicationapiv1alpha1.Application{}) -} - -// GetManagedApplicationComponents returns the resource and error passed as values of the context. -func (l *mockLoader) GetManagedApplicationComponents(ctx context.Context, cli client.Client, application *applicationapiv1alpha1.Application) ([]applicationapiv1alpha1.Component, error) { - if ctx.Value(ApplicationComponentsContextKey) == nil { - return l.loader.GetManagedApplicationComponents(ctx, cli, application) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, ApplicationComponentsContextKey, []applicationapiv1alpha1.Component{}) -} - // GetMatchingReleasePlanAdmission returns the resource and error passed as values of the context. func (l *mockLoader) GetMatchingReleasePlanAdmission(ctx context.Context, cli client.Client, releasePlan *v1alpha1.ReleasePlan) (*v1alpha1.ReleasePlanAdmission, error) { if ctx.Value(MatchedReleasePlanAdmissionContextKey) == nil { @@ -172,32 +145,8 @@ func (l *mockLoader) GetSnapshot(ctx context.Context, cli client.Client, release return toolkit.GetMockedResourceAndErrorFromContext(ctx, SnapshotContextKey, &applicationapiv1alpha1.Snapshot{}) } -// GetSnapshotEnvironmentBinding returns the resource and error passed as values of the context. -func (l *mockLoader) GetSnapshotEnvironmentBinding(ctx context.Context, cli client.Client, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) { - if ctx.Value(SnapshotEnvironmentBindingContextKey) == nil { - return l.loader.GetSnapshotEnvironmentBinding(ctx, cli, releasePlanAdmission) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, SnapshotEnvironmentBindingContextKey, &applicationapiv1alpha1.SnapshotEnvironmentBinding{}) -} - -// GetSnapshotEnvironmentBindingFromReleaseStatus returns the resource and error passed as values of the context. -func (l *mockLoader) GetSnapshotEnvironmentBindingFromReleaseStatus(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*applicationapiv1alpha1.SnapshotEnvironmentBinding, error) { - if ctx.Value(SnapshotEnvironmentBindingContextKey) == nil { - return l.loader.GetSnapshotEnvironmentBindingFromReleaseStatus(ctx, cli, release) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, SnapshotEnvironmentBindingContextKey, &applicationapiv1alpha1.SnapshotEnvironmentBinding{}) -} - // Composite functions -// GetDeploymentResources returns the resource and error passed as values of the context. -func (l *mockLoader) GetDeploymentResources(ctx context.Context, cli client.Client, release *v1alpha1.Release, releasePlanAdmission *v1alpha1.ReleasePlanAdmission) (*DeploymentResources, error) { - if ctx.Value(DeploymentResourcesContextKey) == nil { - return l.loader.GetDeploymentResources(ctx, cli, release, releasePlanAdmission) - } - return toolkit.GetMockedResourceAndErrorFromContext(ctx, DeploymentResourcesContextKey, &DeploymentResources{}) -} - // GetProcessingResources returns the resource and error passed as values of the context. func (l *mockLoader) GetProcessingResources(ctx context.Context, cli client.Client, release *v1alpha1.Release) (*ProcessingResources, error) { if ctx.Value(ProcessingResourcesContextKey) == nil { diff --git a/loader/loader_mock_test.go b/loader/loader_mock_test.go index 90b4b255..4ddf5d89 100644 --- a/loader/loader_mock_test.go +++ b/loader/loader_mock_test.go @@ -81,51 +81,6 @@ var _ = Describe("Release Adapter", Ordered, func() { }) }) - When("calling GetEnvironment", func() { - It("returns the resource and error from the context", func() { - environment := &applicationapiv1alpha1.Environment{} - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: EnvironmentContextKey, - Resource: environment, - }, - }) - resource, err := loader.GetEnvironment(mockContext, nil, nil) - Expect(resource).To(Equal(environment)) - Expect(err).To(BeNil()) - }) - }) - - When("calling GetManagedApplication", func() { - It("returns the resource and error from the context", func() { - application := &applicationapiv1alpha1.Application{} - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: ApplicationContextKey, - Resource: application, - }, - }) - resource, err := loader.GetManagedApplication(mockContext, nil, nil) - Expect(resource).To(Equal(application)) - Expect(err).To(BeNil()) - }) - }) - - When("calling GetManagedApplicationComponents", func() { - It("returns the resource and error from the context", func() { - var components []applicationapiv1alpha1.Component - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: ApplicationComponentsContextKey, - Resource: components, - }, - }) - resource, err := loader.GetManagedApplicationComponents(mockContext, nil, &applicationapiv1alpha1.Application{}) - Expect(resource).To(Equal(components)) - Expect(err).To(BeNil()) - }) - }) - When("calling GetMatchingReleasePlanAdmission", func() { It("returns the resource and error from the context", func() { releasePlanAdmission := &v1alpha1.ReleasePlanAdmission{} @@ -246,53 +201,8 @@ var _ = Describe("Release Adapter", Ordered, func() { }) }) - When("calling GetSnapshotEnvironmentBinding", func() { - It("returns the resource and error from the context", func() { - snapshotEnvironmentBinding := &applicationapiv1alpha1.SnapshotEnvironmentBinding{} - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: SnapshotEnvironmentBindingContextKey, - Resource: snapshotEnvironmentBinding, - }, - }) - resource, err := loader.GetSnapshotEnvironmentBinding(mockContext, nil, nil) - Expect(resource).To(Equal(snapshotEnvironmentBinding)) - Expect(err).To(BeNil()) - }) - }) - - When("calling GetSnapshotEnvironmentBindingFromReleaseStatus", func() { - It("returns the resource and error from the context", func() { - snapshotEnvironmentBinding := &applicationapiv1alpha1.SnapshotEnvironmentBinding{} - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: SnapshotEnvironmentBindingContextKey, - Resource: snapshotEnvironmentBinding, - }, - }) - resource, err := loader.GetSnapshotEnvironmentBindingFromReleaseStatus(mockContext, nil, nil) - Expect(resource).To(Equal(snapshotEnvironmentBinding)) - Expect(err).To(BeNil()) - }) - }) - // Composite functions - When("calling GetDeploymentResources", func() { - It("returns the resource and error from the context", func() { - deploymentResources := &DeploymentResources{} - mockContext := toolkit.GetMockedContext(ctx, []toolkit.MockData{ - { - ContextKey: DeploymentResourcesContextKey, - Resource: deploymentResources, - }, - }) - resource, err := loader.GetDeploymentResources(mockContext, nil, nil, nil) - Expect(resource).To(Equal(deploymentResources)) - Expect(err).To(BeNil()) - }) - }) - When("calling GetProcessingResources", func() { It("returns the resource and error from the context", func() { processingResources := &ProcessingResources{} diff --git a/loader/loader_test.go b/loader/loader_test.go index c76562d1..cde166b6 100644 --- a/loader/loader_test.go +++ b/loader/loader_test.go @@ -32,7 +32,6 @@ var _ = Describe("Release Adapter", Ordered, func() { component *applicationapiv1alpha1.Component enterpriseContractConfigMap *corev1.ConfigMap enterpriseContractPolicy *ecapiv1alpha1.EnterpriseContractPolicy - environment *applicationapiv1alpha1.Environment pipelineRun *tektonv1.PipelineRun release *v1alpha1.Release releasePlan *v1alpha1.ReleasePlan @@ -40,7 +39,6 @@ var _ = Describe("Release Adapter", Ordered, func() { releaseServiceConfig *v1alpha1.ReleaseServiceConfig roleBinding *rbac.RoleBinding snapshot *applicationapiv1alpha1.Snapshot - snapshotEnvironmentBinding *applicationapiv1alpha1.SnapshotEnvironmentBinding ) AfterAll(func() { @@ -135,33 +133,6 @@ var _ = Describe("Release Adapter", Ordered, func() { }) }) - When("calling GetEnvironment", func() { - It("returns the requested environment", func() { - returnedObject, err := loader.GetEnvironment(ctx, k8sClient, releasePlanAdmission) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObject).NotTo(Equal(&applicationapiv1alpha1.Environment{})) - Expect(returnedObject.Name).To(Equal(environment.Name)) - }) - }) - - When("calling GetManagedApplication", func() { - It("returns the requested application", func() { - returnedObject, err := loader.GetManagedApplication(ctx, k8sClient, releasePlan) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObject).NotTo(Equal(&applicationapiv1alpha1.Application{})) - Expect(returnedObject.Name).To(Equal(application.Name)) - }) - }) - - When("calling GetManagedApplicationComponents", func() { - It("returns the requested list of components", func() { - returnedObjects, err := loader.GetManagedApplicationComponents(ctx, k8sClient, application) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObjects).To(HaveLen(1)) - Expect(returnedObjects[0].Name).To(Equal(component.Name)) - }) - }) - When("calling GetMatchingReleasePlanAdmission", func() { It("returns a release plan admission", func() { returnedObject, err := loader.GetMatchingReleasePlanAdmission(ctx, k8sClient, releasePlan) @@ -349,73 +320,8 @@ var _ = Describe("Release Adapter", Ordered, func() { }) }) - When("calling GetSnapshotEnvironmentBinding", func() { - It("returns a snapshot environment binding if the environment field value matches the release plan admission one", func() { - returnedObject, err := loader.GetSnapshotEnvironmentBinding(ctx, k8sClient, releasePlanAdmission) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObject).NotTo(Equal(&applicationapiv1alpha1.SnapshotEnvironmentBinding{})) - Expect(returnedObject.Name).To(Equal(snapshotEnvironmentBinding.Name)) - }) - - It("fails to return a snapshot environment binding if the environment field value doesn't match the release plan admission one", func() { - modifiedReleasePlanAdmission := releasePlanAdmission.DeepCopy() - modifiedReleasePlanAdmission.Spec.Environment = "non-existing-environment" - - returnedObject, err := loader.GetSnapshotEnvironmentBinding(ctx, k8sClient, modifiedReleasePlanAdmission) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObject).To(BeNil()) - }) - }) - - When("calling GetSnapshotEnvironmentBindingFromReleaseStatus", func() { - It("fails to return a snapshot environment binding if the reference is not in the release", func() { - returnedObject, err := loader.GetSnapshotEnvironmentBindingFromReleaseStatus(ctx, k8sClient, release) - Expect(returnedObject).To(BeNil()) - Expect(err.Error()).To(ContainSubstring("release doesn't contain a valid reference to an SnapshotEnvironmentBinding")) - }) - - It("fails to return a snapshot environment binding if the environment field value doesn't match the release plan admission one", func() { - modifiedRelease := release.DeepCopy() - modifiedRelease.Status.Deployment.SnapshotEnvironmentBinding = fmt.Sprintf("%s%c%s", snapshotEnvironmentBinding.Namespace, - types.Separator, snapshotEnvironmentBinding.Name) - - returnedObject, err := loader.GetSnapshotEnvironmentBindingFromReleaseStatus(ctx, k8sClient, modifiedRelease) - Expect(err).NotTo(HaveOccurred()) - Expect(returnedObject).NotTo(Equal(&applicationapiv1alpha1.SnapshotEnvironmentBinding{})) - Expect(returnedObject.Name).To(Equal(snapshotEnvironmentBinding.Name)) - }) - }) - // Composite functions - When("calling GetDeploymentResources", func() { - It("returns all the relevant resources", func() { - resources, err := loader.GetDeploymentResources(ctx, k8sClient, release, releasePlanAdmission) - Expect(err).NotTo(HaveOccurred()) - Expect(*resources).To(MatchFields(IgnoreExtras, Fields{ - "Application": Not(BeNil()), - "ApplicationComponents": Not(BeNil()), - "Snapshot": Not(BeNil()), - })) - }) - - It("fails if any resource fails to be fetched", func() { - newReleasePlan := releasePlan.DeepCopy() - newReleasePlan.Name = "new-release-plan" - newReleasePlan.ResourceVersion = "" - newReleasePlan.Spec.Application = "non-existent-application" - Expect(k8sClient.Create(ctx, newReleasePlan)).To(Succeed()) - - modifiedRelease := release.DeepCopy() - modifiedRelease.Spec.ReleasePlan = newReleasePlan.Name - - _, err := loader.GetDeploymentResources(ctx, k8sClient, modifiedRelease, releasePlanAdmission) - Expect(err).To(HaveOccurred()) - - Expect(k8sClient.Delete(ctx, newReleasePlan)).To(Succeed()) - }) - }) - When("calling GetProcessingResources", func() { It("returns all the relevant resources", func() { os.Setenv("ENTERPRISE_CONTRACT_CONFIG_MAP", "default/ec-defaults") @@ -484,22 +390,6 @@ var _ = Describe("Release Adapter", Ordered, func() { } Expect(k8sClient.Create(ctx, enterpriseContractPolicy)).Should(Succeed()) - environment = &applicationapiv1alpha1.Environment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "environment", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.EnvironmentSpec{ - DeploymentStrategy: applicationapiv1alpha1.DeploymentStrategy_Manual, - DisplayName: "production", - Type: applicationapiv1alpha1.EnvironmentType_POC, - Configuration: applicationapiv1alpha1.EnvironmentConfiguration{ - Env: []applicationapiv1alpha1.EnvVarPair{}, - }, - }, - } - Expect(k8sClient.Create(ctx, environment)).Should(Succeed()) - releasePlan = &v1alpha1.ReleasePlan{ ObjectMeta: metav1.ObjectMeta{ Name: "release-plan", @@ -530,7 +420,6 @@ var _ = Describe("Release Adapter", Ordered, func() { }, Spec: v1alpha1.ReleasePlanAdmissionSpec{ Applications: []string{application.Name}, - Environment: environment.Name, Origin: "default", Pipeline: &tektonutils.Pipeline{ PipelineRef: tektonutils.PipelineRef{ @@ -571,20 +460,6 @@ var _ = Describe("Release Adapter", Ordered, func() { } Expect(k8sClient.Create(ctx, snapshot)).To(Succeed()) - snapshotEnvironmentBinding = &applicationapiv1alpha1.SnapshotEnvironmentBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "snapshot-environment-binding", - Namespace: "default", - }, - Spec: applicationapiv1alpha1.SnapshotEnvironmentBindingSpec{ - Application: application.Name, - Environment: environment.Name, - Snapshot: snapshot.Name, - Components: []applicationapiv1alpha1.BindingComponent{}, - }, - } - Expect(k8sClient.Create(ctx, snapshotEnvironmentBinding)).To(Succeed()) - release = &v1alpha1.Release{ ObjectMeta: metav1.ObjectMeta{ Name: "release", @@ -614,14 +489,12 @@ var _ = Describe("Release Adapter", Ordered, func() { Expect(k8sClient.Delete(ctx, application)).To(Succeed()) Expect(k8sClient.Delete(ctx, component)).To(Succeed()) Expect(k8sClient.Delete(ctx, enterpriseContractPolicy)).To(Succeed()) - Expect(k8sClient.Delete(ctx, environment)).To(Succeed()) Expect(k8sClient.Delete(ctx, pipelineRun)).To(Succeed()) Expect(k8sClient.Delete(ctx, release)).To(Succeed()) Expect(k8sClient.Delete(ctx, releasePlan)).To(Succeed()) Expect(k8sClient.Delete(ctx, releasePlanAdmission)).To(Succeed()) Expect(k8sClient.Delete(ctx, roleBinding)).To(Succeed()) Expect(k8sClient.Delete(ctx, snapshot)).To(Succeed()) - Expect(k8sClient.Delete(ctx, snapshotEnvironmentBinding)).To(Succeed()) } }) diff --git a/loader/suite_test.go b/loader/suite_test.go index 00e9e0a6..48c92f26 100644 --- a/loader/suite_test.go +++ b/loader/suite_test.go @@ -112,7 +112,6 @@ var _ = BeforeSuite(func() { Expect(cache.SetupComponentCache(mgr)).To(Succeed()) Expect(cache.SetupReleasePlanCache(mgr)).To(Succeed()) Expect(cache.SetupReleasePlanAdmissionCache(mgr)).To(Succeed()) - Expect(cache.SetupSnapshotEnvironmentBindingCache(mgr)).To(Succeed()) Expect(mgr.Start(ctx)).To(Succeed()) }() diff --git a/metrics/release.go b/metrics/release.go index f7a2c148..2ed7db6a 100644 --- a/metrics/release.go +++ b/metrics/release.go @@ -31,14 +31,6 @@ var ( []string{}, ) - ReleaseConcurrentDeploymentsTotal = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "release_concurrent_deployments_total", - Help: "Total number of concurrent release deployment attempts", - }, - []string{}, - ) - ReleaseConcurrentPostActionsExecutionsTotal = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "release_concurrent_post_actions_executions_total", @@ -55,21 +47,6 @@ var ( []string{}, ) - ReleaseDeploymentDurationSeconds = prometheus.NewHistogramVec( - releaseDeploymentDurationSecondsOpts, - releaseDeploymentDurationSecondsLabels, - ) - releaseDeploymentDurationSecondsLabels = []string{ - "environment", - "reason", - "target", - } - releaseDeploymentDurationSecondsOpts = prometheus.HistogramOpts{ - Name: "release_deployment_duration_seconds", - Help: "How long in seconds a Release deployment takes to complete", - Buckets: []float64{60, 150, 300, 450, 600, 750, 900, 1050, 1200, 1800, 3600}, - } - ReleasePreProcessingDurationSeconds = prometheus.NewHistogramVec( releasePreProcessingDurationSecondsOpts, releasePreProcessingDurationSecondsLabels, @@ -103,7 +80,6 @@ var ( releaseDurationSecondsLabels, ) releaseDurationSecondsLabels = []string{ - "deployment_reason", "post_actions_reason", "processing_reason", "release_reason", @@ -148,7 +124,6 @@ var ( releaseTotalLabels, ) releaseTotalLabels = []string{ - "deployment_reason", "post_actions_reason", "processing_reason", "release_reason", @@ -165,13 +140,12 @@ var ( // observation for the Release duration and increasing the total number of releases. If either the startTime or the // completionTime parameters are nil, no action will be taken. func RegisterCompletedRelease(startTime, completionTime *metav1.Time, - deploymentReason, postActionsReason, processingReason, releaseReason, target, validationReason string) { + postActionsReason, processingReason, releaseReason, target, validationReason string) { if startTime == nil || completionTime == nil { return } labels := prometheus.Labels{ - "deployment_reason": deploymentReason, "post_actions_reason": postActionsReason, "processing_reason": processingReason, "release_reason": releaseReason, @@ -185,24 +159,6 @@ func RegisterCompletedRelease(startTime, completionTime *metav1.Time, ReleaseTotal.With(labels).Inc() } -// RegisterCompletedReleaseDeployment registers a Release deployment as complete, adding a new observation for the -// Release deployment duration and decreasing the number of concurrent deployments. If either the startTime or the -// completionTime parameters are nil, no action will be taken. -func RegisterCompletedReleaseDeployment(startTime, completionTime *metav1.Time, environment, reason, target string) { - if startTime == nil || completionTime == nil { - return - } - - ReleaseDeploymentDurationSeconds. - With(prometheus.Labels{ - "environment": environment, - "reason": reason, - "target": target, - }). - Observe(completionTime.Sub(startTime.Time).Seconds()) - ReleaseConcurrentDeploymentsTotal.WithLabelValues().Dec() -} - // RegisterCompletedReleasePostActionsExecuted registers a Release post-actions execution as complete, adding a new // observation for the Release post-actions execution duration and decreasing the number of concurrent executions. // If either the startTime or the completionTime parameters are nil, no action will be taken. @@ -257,11 +213,6 @@ func RegisterNewRelease() { ReleaseConcurrentTotal.WithLabelValues().Inc() } -// RegisterNewReleaseDeployment register a new Release deployment, increasing the number of concurrent deployments. -func RegisterNewReleaseDeployment() { - ReleaseConcurrentDeploymentsTotal.WithLabelValues().Inc() -} - // RegisterNewReleaseProcessing registers a new Release processing, adding a new observation for the // Release start processing duration and increasing the number of concurrent processings. If either the // startTime or the processingStartTime are nil, no action will be taken. @@ -289,10 +240,8 @@ func RegisterNewReleasePostActionsExecution() { func init() { metrics.Registry.MustRegister( ReleaseConcurrentTotal, - ReleaseConcurrentDeploymentsTotal, ReleaseConcurrentProcessingsTotal, ReleaseConcurrentPostActionsExecutionsTotal, - ReleaseDeploymentDurationSeconds, ReleasePreProcessingDurationSeconds, ReleaseValidationDurationSeconds, ReleaseDurationSeconds, diff --git a/metrics/release_test.go b/metrics/release_test.go index 643e875e..c50ea3a6 100644 --- a/metrics/release_test.go +++ b/metrics/release_test.go @@ -43,19 +43,19 @@ var _ = Describe("Release metrics", Ordered, func() { It("does nothing if the start time is nil", func() { Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedRelease(nil, completionTime, "", "", "", "", "", "") + RegisterCompletedRelease(nil, completionTime, "", "", "", "", "") Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(0))) }) It("does nothing if the completion time is nil", func() { Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedRelease(startTime, nil, "", "", "", "", "", "") + RegisterCompletedRelease(startTime, nil, "", "", "", "", "") Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(0))) }) It("decrements ReleaseConcurrentTotal", func() { Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedRelease(startTime, completionTime, "", "", "", "", "", "") + RegisterCompletedRelease(startTime, completionTime, "", "", "", "", "") Expect(testutil.ToFloat64(ReleaseConcurrentTotal.WithLabelValues())).To(Equal(float64(-1))) }) @@ -66,7 +66,6 @@ var _ = Describe("Release metrics", Ordered, func() { releaseDurationSecondsLabels[2], releaseDurationSecondsLabels[3], releaseDurationSecondsLabels[4], - releaseDurationSecondsLabels[5], ) Expect(testutil.CollectAndCompare(ReleaseDurationSeconds, test.NewHistogramReader( @@ -83,7 +82,6 @@ var _ = Describe("Release metrics", Ordered, func() { releaseTotalLabels[2], releaseTotalLabels[3], releaseTotalLabels[4], - releaseTotalLabels[5], ) Expect(testutil.CollectAndCompare(ReleaseTotal, test.NewCounterReader( @@ -93,49 +91,6 @@ var _ = Describe("Release metrics", Ordered, func() { }) }) - When("RegisterCompletedReleaseDeployment is called", func() { - var completionTime, startTime *metav1.Time - - BeforeEach(func() { - initializeMetrics() - - completionTime = &metav1.Time{} - startTime = &metav1.Time{Time: completionTime.Add(-60 * time.Second)} - }) - - It("does nothing if the start time is nil", func() { - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedReleaseDeployment(nil, completionTime, "", "", "") - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - }) - - It("does nothing if the completion time is nil", func() { - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedReleaseDeployment(startTime, nil, "", "", "") - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - }) - - It("decrements ReleaseConcurrentDeploymentsTotal", func() { - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterCompletedReleaseDeployment(startTime, completionTime, "", "", "") - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(-1))) - }) - - It("adds an observation to ReleaseDeploymentDurationSeconds", func() { - RegisterCompletedReleaseDeployment(startTime, completionTime, - releaseDeploymentDurationSecondsLabels[0], - releaseDeploymentDurationSecondsLabels[1], - releaseDeploymentDurationSecondsLabels[2], - ) - Expect(testutil.CollectAndCompare(ReleaseDeploymentDurationSeconds, - test.NewHistogramReader( - releaseDeploymentDurationSecondsOpts, - releaseDeploymentDurationSecondsLabels, - startTime, completionTime, - ))).To(Succeed()) - }) - }) - When("RegisterCompletedReleasePostActionsExecuted is called", func() { var completionTime, startTime *metav1.Time @@ -263,18 +218,6 @@ var _ = Describe("Release metrics", Ordered, func() { }) }) - When("RegisterNewReleaseDeployment is called", func() { - BeforeEach(func() { - initializeMetrics() - }) - - It("increments ReleaseConcurrentDeploymentsTotal", func() { - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(0))) - RegisterNewReleaseDeployment() - Expect(testutil.ToFloat64(ReleaseConcurrentDeploymentsTotal.WithLabelValues())).To(Equal(float64(1))) - }) - }) - When("RegisterNewReleaseProcessing is called", func() { var processingStartTime, startTime *metav1.Time @@ -334,10 +277,8 @@ var _ = Describe("Release metrics", Ordered, func() { initializeMetrics = func() { ReleaseConcurrentTotal.Reset() - ReleaseConcurrentDeploymentsTotal.Reset() ReleaseConcurrentProcessingsTotal.Reset() ReleaseConcurrentPostActionsExecutionsTotal.Reset() - ReleaseDeploymentDurationSeconds.Reset() ReleaseValidationDurationSeconds.Reset() ReleasePreProcessingDurationSeconds.Reset() ReleaseDurationSeconds.Reset()