Skip to content

Commit

Permalink
THREESCALE-10092 improve states to be in line whats done in other con…
Browse files Browse the repository at this point in the history
…trollers
  • Loading branch information
MStokluska committed Sep 6, 2023
1 parent 7d72e71 commit 7bae410
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 36 deletions.
25 changes: 11 additions & 14 deletions controllers/capabilities/proxyconfigpromote_controller.go
Expand Up @@ -71,7 +71,7 @@ func (r *ProxyConfigPromoteReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
// If the product CR is not found, update status and requeue
if errors.IsNotFound(err) {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", "product not found", 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "product not found", 0, 0, err)
reqLogger.Info("product not found. Ignoring since object must have been deleted")
statusResult, statusErr := statusReconciler.Reconcile()
// Reconcile status first as the reconcilerError might need to be updated to the status section of the CR before requeueing
Expand Down Expand Up @@ -150,14 +150,14 @@ func (r *ProxyConfigPromoteReconciler) proxyConfigPromoteReconciler(proxyConfigP
// Promote to stage
_, err := threescaleAPIClient.DeployProductProxy(*productID)
if err != nil {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, 0, err)
return statusReconciler, err
}

// Retrieve latest stage version
stageElement, err := threescaleAPIClient.GetLatestProxyConfig(productIDStr, "sandbox")
if err != nil {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, 0, err)
return statusReconciler, err
}
latestStagingVersion = stageElement.ProxyConfig.Version
Expand All @@ -166,31 +166,28 @@ func (r *ProxyConfigPromoteReconciler) proxyConfigPromoteReconciler(proxyConfigP
productionElement, err := threescaleAPIClient.GetLatestProxyConfig(productIDStr, "production")
if err != nil {
if !threescaleapi.IsNotFound(err) {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, latestStagingVersion, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, latestStagingVersion, err)
return statusReconciler, err
}
}
latestProductionVersion = productionElement.ProxyConfig.Version

statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Completed", productIDStr, latestProductionVersion, latestStagingVersion, err)
return statusReconciler, nil
}

// If wanting to promote to Production.
if *proxyConfigPromote.Spec.Production {
if proxyConfigPromote.Spec.Production != nil {
// Before promoting to Production we want to update latest changes to staging first
_, err := threescaleAPIClient.DeployProductProxy(*product.Status.ID)
if err != nil {
reqLogger.Info("Error", "Config version already exists in stage, skipping promotion to stage ", err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, 0, err)
return statusReconciler, err
}

// Retrieving latest stage version
stageElement, err := threescaleAPIClient.GetLatestProxyConfig(productIDStr, "sandbox")
if err != nil {
reqLogger.Info("Error while finding sandbox version")
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, 0, err)
return statusReconciler, err
}
latestStagingVersion = stageElement.ProxyConfig.Version
Expand All @@ -200,7 +197,7 @@ func (r *ProxyConfigPromoteReconciler) proxyConfigPromoteReconciler(proxyConfigP
if err != nil {
reqLogger.Info("Error while finding production version")
if !threescaleapi.IsNotFound(err) {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, latestStagingVersion, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, latestStagingVersion, err)
return statusReconciler, err
}
}
Expand All @@ -210,20 +207,20 @@ func (r *ProxyConfigPromoteReconciler) proxyConfigPromoteReconciler(proxyConfigP
_, err = threescaleAPIClient.PromoteProxyConfig(productIDStr, "sandbox", strconv.Itoa(stageElement.ProxyConfig.Version), "production")
if err != nil {
// The version can already be in the production meaning that it can't be updated again, the proxyPromote is not going to be deleted by the operator but instead, will notify the user of the issue
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, string(capabilitiesv1beta1.ProxyPromoteConfigFailedConditionType), productIDStr, latestProductionVersion, latestStagingVersion, fmt.Errorf("can't promote to production as no product changes detected, delete the proxyConfigPromote CR or introduce changes to stage env first to proceed"))
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, latestProductionVersion, latestStagingVersion, fmt.Errorf("can't promote to production as no product changes detected, delete the proxyConfigPromote CR or introduce changes to stage env first to proceed"))
return statusReconciler, err
} else {
latestProductionVersion = latestStagingVersion
}
}

statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Completed", productIDStr, latestProductionVersion, latestStagingVersion, nil)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, latestProductionVersion, latestStagingVersion, nil)
return statusReconciler, nil
} else {
// If product CR is not ready, update the status and requeue based on err.
reqLogger.Info("proudct CR is not ready")
err := fmt.Errorf("proudct CR is not ready")
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", "", 0, 0, err)
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "", 0, 0, err)
return statusReconciler, err
}
}
Expand Down
Expand Up @@ -327,7 +327,6 @@ func TestProxyConfigPromoteReconciler_proxyConfigPromoteReconciler(t *testing.T)
want: &ProxyConfigPromoteStatusReconciler{
BaseReconciler: getBaseReconciler(),
resource: getProxyConfigPromoteCRStaging(),
state: "Completed",
productID: "3",
latestProductionVersion: 0,
latestStagingVersion: 1,
Expand All @@ -350,7 +349,6 @@ func TestProxyConfigPromoteReconciler_proxyConfigPromoteReconciler(t *testing.T)
want: &ProxyConfigPromoteStatusReconciler{
BaseReconciler: getBaseReconciler(),
resource: getProxyConfigPromoteCRProduction(),
state: "Completed",
productID: "3",
latestProductionVersion: 1,
latestStagingVersion: 1,
Expand Down Expand Up @@ -383,9 +381,6 @@ func TestProxyConfigPromoteReconciler_proxyConfigPromoteReconciler(t *testing.T)
t.Logf("proxyConfigPromoteReconciler(), wantErr %v", tt.wantErr)
return
}
if !reflect.DeepEqual(got.state, tt.want.state) {
t.Errorf("proxyConfigPromoteReconciler() got.state = %v, want.state %v", got.state, tt.want.state)
}
if !reflect.DeepEqual(got.productID, tt.want.productID) {
t.Errorf("proxyConfigPromoteReconciler() got.productID = %v, want.productID %v", got.productID, tt.want.productID)
}
Expand Down
29 changes: 17 additions & 12 deletions controllers/capabilities/proxyconfigpromote_status_reconciler.go
Expand Up @@ -15,19 +15,17 @@ import (
type ProxyConfigPromoteStatusReconciler struct {
*reconcilers.BaseReconciler
resource *capabilitiesv1beta1.ProxyConfigPromote
state string
productID string
latestProductionVersion int
latestStagingVersion int
reconcileError error
logger logr.Logger
}

func NewProxyConfigPromoteStatusReconciler(b *reconcilers.BaseReconciler, resource *capabilitiesv1beta1.ProxyConfigPromote, state string, productID string, latestProductionVersion int, latestStagingVersion int, reconcileError error) *ProxyConfigPromoteStatusReconciler {
func NewProxyConfigPromoteStatusReconciler(b *reconcilers.BaseReconciler, resource *capabilitiesv1beta1.ProxyConfigPromote, productID string, latestProductionVersion int, latestStagingVersion int, reconcileError error) *ProxyConfigPromoteStatusReconciler {
return &ProxyConfigPromoteStatusReconciler{
BaseReconciler: b,
resource: resource,
state: state,
productID: productID,
latestProductionVersion: latestProductionVersion,
latestStagingVersion: latestStagingVersion,
Expand Down Expand Up @@ -74,27 +72,34 @@ func (s *ProxyConfigPromoteStatusReconciler) calculateStatus() (*capabilitiesv1b
newStatus.LatestStagingVersion = s.latestStagingVersion

newStatus.Conditions = s.resource.Status.Conditions.Copy()
newStatus.Conditions.SetCondition(s.establishCondition())
newStatus.Conditions.SetCondition(s.readyCondition())
newStatus.Conditions.SetCondition(s.failedCondition())

return newStatus, nil
}

func (s *ProxyConfigPromoteStatusReconciler) establishCondition() common.Condition {
func (s *ProxyConfigPromoteStatusReconciler) readyCondition() common.Condition {
condition := common.Condition{
Status: corev1.ConditionFalse,
Type: capabilitiesv1beta1.ProxyPromoteConfigInProgressConditionType,
Message: "in progress",
Type: capabilitiesv1beta1.ProxyPromoteConfigReadyConditionType,
Status: corev1.ConditionFalse,
}

if s.state == "Completed" {
if s.reconcileError == nil {
condition.Status = corev1.ConditionTrue
condition.Type = capabilitiesv1beta1.ProxyPromoteConfigReadyConditionType
condition.Message = "3scale product has been successfully promoted, any further interactions with this CR (apart from deletion) won't be applied"
}

if s.state == "Failed" {
return condition
}

func (s *ProxyConfigPromoteStatusReconciler) failedCondition() common.Condition {
condition := common.Condition{
Type: capabilitiesv1beta1.ProxyPromoteConfigFailedConditionType,
Status: corev1.ConditionFalse,
}

if s.reconcileError != nil {
condition.Status = corev1.ConditionTrue
condition.Type = capabilitiesv1beta1.ProxyPromoteConfigFailedConditionType
condition.Message = s.reconcileError.Error()
}

Expand Down
Expand Up @@ -87,7 +87,6 @@ func TestProxyConfigPromoteStatusReconciler_calculateStatus(t *testing.T) {
type fields struct {
BaseReconciler *reconcilers.BaseReconciler
resource *capabilitiesv1beta1.ProxyConfigPromote
state string
productID string
latestProductionVersion int
latestStagingVersion int
Expand All @@ -105,7 +104,6 @@ func TestProxyConfigPromoteStatusReconciler_calculateStatus(t *testing.T) {
fields: fields{
BaseReconciler: getBaseReconciler(),
resource: getProxyConfigPromoteCR(),
state: "Completed",
productID: "3",
latestProductionVersion: 1,
latestStagingVersion: 1,
Expand All @@ -130,7 +128,6 @@ func TestProxyConfigPromoteStatusReconciler_calculateStatus(t *testing.T) {
fields: fields{
BaseReconciler: getBaseReconciler(),
resource: getProxyConfigPromoteCR(),
state: "Failed",
productID: "3",
latestProductionVersion: 1,
latestStagingVersion: 1,
Expand All @@ -156,7 +153,6 @@ func TestProxyConfigPromoteStatusReconciler_calculateStatus(t *testing.T) {
s := &ProxyConfigPromoteStatusReconciler{
BaseReconciler: tt.fields.BaseReconciler,
resource: tt.fields.resource,
state: tt.fields.state,
productID: tt.fields.productID,
latestProductionVersion: tt.fields.latestProductionVersion,
latestStagingVersion: tt.fields.latestStagingVersion,
Expand Down Expand Up @@ -227,7 +223,6 @@ func TestProxyConfigPromoteStatusReconciler_Reconcile(t *testing.T) {
s := &ProxyConfigPromoteStatusReconciler{
BaseReconciler: tt.fields.BaseReconciler,
resource: tt.fields.resource,
state: tt.fields.state,
productID: tt.fields.productID,
latestProductionVersion: tt.fields.latestProductionVersion,
latestStagingVersion: tt.fields.latestStagingVersion,
Expand Down

0 comments on commit 7bae410

Please sign in to comment.