-
Notifications
You must be signed in to change notification settings - Fork 28
/
ratelimitpolicy_status.go
102 lines (83 loc) · 4.12 KB
/
ratelimitpolicy_status.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package controllers
import (
"context"
"errors"
"fmt"
"slices"
"github.com/go-logr/logr"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2"
"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
)
func (r *RateLimitPolicyReconciler) reconcileStatus(ctx context.Context, rlp *kuadrantv1beta2.RateLimitPolicy, specErr error) (ctrl.Result, error) {
logger, _ := logr.FromContext(ctx)
newStatus := r.calculateStatus(ctx, rlp, specErr)
equalStatus := rlp.Status.Equals(newStatus, logger)
logger.V(1).Info("Status", "status is different", !equalStatus)
logger.V(1).Info("Status", "generation is different", rlp.Generation != rlp.Status.ObservedGeneration)
if equalStatus && rlp.Generation == rlp.Status.ObservedGeneration {
// Steady state
logger.V(1).Info("Status was not updated")
return reconcile.Result{}, nil
}
// Save the generation number we acted on, otherwise we might wrongfully indicate
// that we've seen a spec update when we retry.
// TODO: This can clobber an update if we allow multiple agents to write to the
// same status.
newStatus.ObservedGeneration = rlp.Generation
logger.V(1).Info("Updating Status", "sequence no:", fmt.Sprintf("sequence No: %v->%v", rlp.Status.ObservedGeneration, newStatus.ObservedGeneration))
rlp.Status = *newStatus
updateErr := r.Client().Status().Update(ctx, rlp)
logger.V(1).Info("Updating Status", "err", updateErr)
if updateErr != nil {
// Ignore conflicts, resource might just be outdated.
if apierrors.IsConflict(updateErr) {
logger.Info("Failed to update status: resource might just be outdated")
return reconcile.Result{Requeue: true}, nil
}
return reconcile.Result{}, fmt.Errorf("failed to update status: %w", updateErr)
}
return ctrl.Result{}, nil
}
func (r *RateLimitPolicyReconciler) calculateStatus(ctx context.Context, rlp *kuadrantv1beta2.RateLimitPolicy, specErr error) *kuadrantv1beta2.RateLimitPolicyStatus {
newStatus := &kuadrantv1beta2.RateLimitPolicyStatus{
// Copy initial conditions. Otherwise, status will always be updated
Conditions: slices.Clone(rlp.Status.Conditions),
ObservedGeneration: rlp.Status.ObservedGeneration,
}
acceptedCond := kuadrant.AcceptedCondition(rlp, specErr)
meta.SetStatusCondition(&newStatus.Conditions, *acceptedCond)
// Do not set enforced condition if Accepted condition is false
if meta.IsStatusConditionFalse(newStatus.Conditions, string(gatewayapiv1alpha2.PolicyReasonAccepted)) {
meta.RemoveStatusCondition(&newStatus.Conditions, string(kuadrant.PolicyConditionEnforced))
return newStatus
}
enforcedCond := r.enforcedCondition(ctx, rlp)
meta.SetStatusCondition(&newStatus.Conditions, *enforcedCond)
return newStatus
}
func (r *RateLimitPolicyReconciler) enforcedCondition(ctx context.Context, policy *kuadrantv1beta2.RateLimitPolicy) *metav1.Condition {
logger, _ := logr.FromContext(ctx)
limitador, err := r.getLimitador(ctx, policy)
if err != nil {
logger.V(1).Error(err, "failed to get limitador")
return kuadrant.EnforcedCondition(policy, kuadrant.NewErrUnknown(policy.Kind(), err), false)
}
if meta.IsStatusConditionFalse(limitador.Status.Conditions, "Ready") {
logger.V(1).Info("Limitador is not ready")
return kuadrant.EnforcedCondition(policy, kuadrant.NewErrUnknown(policy.Kind(), errors.New("limitador is not ready")), false)
}
if r.AffectedPolicyMap.IsPolicyAffected(policy) {
if !r.AffectedPolicyMap.IsPolicyOverridden(policy) {
return kuadrant.EnforcedCondition(policy, kuadrant.NewErrUnknown(policy.Kind(), errors.New("no free routes to enforce policy")), false) // Maybe this should be a standard condition rather than an unknown condition
}
return kuadrant.EnforcedCondition(policy, kuadrant.NewErrOverridden(policy.Kind(), r.AffectedPolicyMap.PolicyAffectedBy(policy)), false)
}
logger.V(1).Info("RateLimitPolicy is enforced")
return kuadrant.EnforcedCondition(policy, nil, true)
}