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 b6cd305
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 67 deletions.
87 changes: 42 additions & 45 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,64 +166,61 @@ 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
} else {
// Spec.production not nil, if production value is true promote to production, in all other cases skip.
if *proxyConfigPromote.Spec.Production {
// 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, productIDStr, 0, 0, err)
return statusReconciler, err
}

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

// If wanting to promote to Production.
if *proxyConfigPromote.Spec.Production {
// 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)
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)
return statusReconciler, err
}
latestStagingVersion = stageElement.ProxyConfig.Version

// Retrieving latest production version
productionElement, err := threescaleAPIClient.GetLatestProxyConfig(productIDStr, "production")
if err != nil {
reqLogger.Info("Error while finding production version")
if !threescaleapi.IsNotFound(err) {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, "Failed", productIDStr, 0, latestStagingVersion, 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, productIDStr, 0, 0, err)
return statusReconciler, err
}
}
latestProductionVersion = productionElement.ProxyConfig.Version
latestStagingVersion = stageElement.ProxyConfig.Version

// Retrieving latest production version
productionElement, err := threescaleAPIClient.GetLatestProxyConfig(productIDStr, "production")
if err != nil {
reqLogger.Info("Error while finding production version")
if !threescaleapi.IsNotFound(err) {
statusReconciler := NewProxyConfigPromoteStatusReconciler(r.BaseReconciler, proxyConfigPromote, productIDStr, 0, latestStagingVersion, err)
return statusReconciler, err
}
}
latestProductionVersion = productionElement.ProxyConfig.Version

// Promoting staging latest to production
_, 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"))
return statusReconciler, err
} else {
latestProductionVersion = latestStagingVersion
// Promoting staging latest to production
_, 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, 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 b6cd305

Please sign in to comment.