Skip to content

Commit

Permalink
Merge pull request vmware-tanzu#481 from jwsui/add-transition-time
Browse files Browse the repository at this point in the history
Add LastTansitionTime in CR status
  • Loading branch information
jwsui authored Jan 22, 2024
2 parents 5b2b440 + 48338e4 commit 8b9d57e
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 103 deletions.
21 changes: 12 additions & 9 deletions pkg/controllers/ippool/ippool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -52,21 +53,21 @@ func deleteSuccess(r *IPPoolReconciler, _ *context.Context, _ *v1alpha2.IPPool)
}

func deleteFail(r *IPPoolReconciler, c *context.Context, o *v1alpha2.IPPool, e *error) {
r.setReadyStatusFalse(c, o, e)
r.setReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, MetricResType)
}

func updateSuccess(r *IPPoolReconciler, c *context.Context, o *v1alpha2.IPPool) {
r.setReadyStatusTrue(c, o)
r.setReadyStatusTrue(c, o, metav1.Now())
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, MetricResType)
}

func updateFail(r *IPPoolReconciler, c *context.Context, o *v1alpha2.IPPool, e *error) {
r.setReadyStatusFalse(c, o, e)
r.setReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResType)
}

func (r *IPPoolReconciler) setReadyStatusFalse(ctx *context.Context, ippool *v1alpha2.IPPool, err *error) {
func (r *IPPoolReconciler) setReadyStatusFalse(ctx *context.Context, ippool *v1alpha2.IPPool, transitionTime metav1.Time, err *error) {
conditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Expand All @@ -76,6 +77,7 @@ func (r *IPPoolReconciler) setReadyStatusFalse(ctx *context.Context, ippool *v1a
"error occurred while processing the IPPool CR. Error: %v",
*err,
),
LastTransitionTime: transitionTime,
},
}
ippool.Status.Conditions = conditions
Expand All @@ -88,13 +90,14 @@ func (r *IPPoolReconciler) setReadyStatusFalse(ctx *context.Context, ippool *v1a
}
}

func (r *IPPoolReconciler) setReadyStatusTrue(ctx *context.Context, ippool *v1alpha2.IPPool) {
func (r *IPPoolReconciler) setReadyStatusTrue(ctx *context.Context, ippool *v1alpha2.IPPool, transitionTime metav1.Time) {
conditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX IPPool has been successfully created/updated",
Reason: "",
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX IPPool has been successfully created/updated",
Reason: "",
LastTransitionTime: transitionTime,
},
}
ippool.Status.Conditions = conditions
Expand Down
12 changes: 7 additions & 5 deletions pkg/controllers/ippool/ippool_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,19 @@ func TestIPPoolController_setReadyStatusTrue(t *testing.T) {
r := NewFakeIPPoolReconciler()
ctx := context.TODO()
dummyIPPool := &v1alpha2.IPPool{}
transitionTime := metav1.Now()

// Case: Static Route CRD creation fails
newConditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX IPPool has been successfully created/updated",
Reason: "",
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX IPPool has been successfully created/updated",
Reason: "",
LastTransitionTime: transitionTime,
},
}
r.setReadyStatusTrue(&ctx, dummyIPPool)
r.setReadyStatusTrue(&ctx, dummyIPPool, transitionTime)

if !reflect.DeepEqual(dummyIPPool.Status.Conditions, newConditions) {
t.Fatalf("Failed to correctly update Status Conditions when conditions haven't changed")
Expand Down
39 changes: 21 additions & 18 deletions pkg/controllers/securitypolicy/securitypolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -52,7 +53,7 @@ type SecurityPolicyReconciler struct {
}

func updateFail(r *SecurityPolicyReconciler, c *context.Context, o *v1alpha1.SecurityPolicy, e *error) {
r.setSecurityPolicyReadyStatusFalse(c, o, e)
r.setSecurityPolicyReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResType)
}

Expand All @@ -65,12 +66,12 @@ func k8sClient(mgr ctrl.Manager) client.Client {
}

func deleteFail(r *SecurityPolicyReconciler, c *context.Context, o *v1alpha1.SecurityPolicy, e *error) {
r.setSecurityPolicyReadyStatusFalse(c, o, e)
r.setSecurityPolicyReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, MetricResType)
}

func updateSuccess(r *SecurityPolicyReconciler, c *context.Context, o *v1alpha1.SecurityPolicy) {
r.setSecurityPolicyReadyStatusTrue(c, o)
r.setSecurityPolicyReadyStatusTrue(c, o, metav1.Now())
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, MetricResType)
}

Expand Down Expand Up @@ -157,19 +158,20 @@ func (r *SecurityPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ResultNormal, nil
}

func (r *SecurityPolicyReconciler) setSecurityPolicyReadyStatusTrue(ctx *context.Context, sec_policy *v1alpha1.SecurityPolicy) {
func (r *SecurityPolicyReconciler) setSecurityPolicyReadyStatusTrue(ctx *context.Context, secPolicy *v1alpha1.SecurityPolicy, transitionTime metav1.Time) {
newConditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Security Policy has been successfully created/updated",
Reason: "NSX API returned 200 response code for PATCH",
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Security Policy has been successfully created/updated",
Reason: "NSX API returned 200 response code for PATCH",
LastTransitionTime: transitionTime,
},
}
r.updateSecurityPolicyStatusConditions(ctx, sec_policy, newConditions)
r.updateSecurityPolicyStatusConditions(ctx, secPolicy, newConditions)
}

func (r *SecurityPolicyReconciler) setSecurityPolicyReadyStatusFalse(ctx *context.Context, sec_policy *v1alpha1.SecurityPolicy, err *error) {
func (r *SecurityPolicyReconciler) setSecurityPolicyReadyStatusFalse(ctx *context.Context, secPolicy *v1alpha1.SecurityPolicy, transitionTime metav1.Time, err *error) {
newConditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Expand All @@ -179,27 +181,28 @@ func (r *SecurityPolicyReconciler) setSecurityPolicyReadyStatusFalse(ctx *contex
"error occurred while processing the SecurityPolicy CR. Error: %v",
*err,
),
LastTransitionTime: transitionTime,
},
}
r.updateSecurityPolicyStatusConditions(ctx, sec_policy, newConditions)
r.updateSecurityPolicyStatusConditions(ctx, secPolicy, newConditions)
}

func (r *SecurityPolicyReconciler) updateSecurityPolicyStatusConditions(ctx *context.Context, sec_policy *v1alpha1.SecurityPolicy, newConditions []v1alpha1.Condition) {
func (r *SecurityPolicyReconciler) updateSecurityPolicyStatusConditions(ctx *context.Context, secPolicy *v1alpha1.SecurityPolicy, newConditions []v1alpha1.Condition) {
conditionsUpdated := false
for i := range newConditions {
if r.mergeSecurityPolicyStatusCondition(ctx, sec_policy, &newConditions[i]) {
if r.mergeSecurityPolicyStatusCondition(ctx, secPolicy, &newConditions[i]) {
conditionsUpdated = true
}
}
if conditionsUpdated {
r.Client.Status().Update(*ctx, sec_policy)
log.V(1).Info("updated SecurityPolicy", "Name", sec_policy.Name, "Namespace", sec_policy.Namespace,
r.Client.Status().Update(*ctx, secPolicy)
log.V(1).Info("updated SecurityPolicy", "Name", secPolicy.Name, "Namespace", secPolicy.Namespace,
"New Conditions", newConditions)
}
}

func (r *SecurityPolicyReconciler) mergeSecurityPolicyStatusCondition(ctx *context.Context, sec_policy *v1alpha1.SecurityPolicy, newCondition *v1alpha1.Condition) bool {
matchedCondition := getExistingConditionOfType(newCondition.Type, sec_policy.Status.Conditions)
func (r *SecurityPolicyReconciler) mergeSecurityPolicyStatusCondition(ctx *context.Context, secPolicy *v1alpha1.SecurityPolicy, newCondition *v1alpha1.Condition) bool {
matchedCondition := getExistingConditionOfType(newCondition.Type, secPolicy.Status.Conditions)

if reflect.DeepEqual(matchedCondition, newCondition) {
log.V(2).Info("conditions already match", "New Condition", newCondition, "Existing Condition", matchedCondition)
Expand All @@ -211,7 +214,7 @@ func (r *SecurityPolicyReconciler) mergeSecurityPolicyStatusCondition(ctx *conte
matchedCondition.Message = newCondition.Message
matchedCondition.Status = newCondition.Status
} else {
sec_policy.Status.Conditions = append(sec_policy.Status.Conditions, *newCondition)
secPolicy.Status.Conditions = append(secPolicy.Status.Conditions, *newCondition)
}
return true
}
Expand Down
47 changes: 25 additions & 22 deletions pkg/controllers/staticroute/staticroute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -47,17 +48,17 @@ type StaticRouteReconciler struct {
}

func deleteFail(r *StaticRouteReconciler, c *context.Context, o *v1alpha1.StaticRoute, e *error) {
r.setStaticRouteReadyStatusFalse(c, o, e)
r.setStaticRouteReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, common.MetricResTypeStaticRoute)
}

func updateFail(r *StaticRouteReconciler, c *context.Context, o *v1alpha1.StaticRoute, e *error) {
r.setStaticRouteReadyStatusFalse(c, o, e)
r.setStaticRouteReadyStatusFalse(c, o, metav1.Now(), e)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResType)
}

func updateSuccess(r *StaticRouteReconciler, c *context.Context, o *v1alpha1.StaticRoute) {
r.setStaticRouteReadyStatusTrue(c, o)
r.setStaticRouteReadyStatusTrue(c, o, metav1.Now())
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, common.MetricResTypeStaticRoute)
}

Expand Down Expand Up @@ -118,45 +119,47 @@ func (r *StaticRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ResultNormal, nil
}

func (r *StaticRouteReconciler) setStaticRouteReadyStatusTrue(ctx *context.Context, static_route *v1alpha1.StaticRoute) {
func (r *StaticRouteReconciler) setStaticRouteReadyStatusTrue(ctx *context.Context, staticRoute *v1alpha1.StaticRoute, transitionTime metav1.Time) {
newConditions := []v1alpha1.StaticRouteCondition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Static Route has been successfully created/updated",
Reason: "NSX API returned 200 response code for PATCH",
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Static Route has been successfully created/updated",
Reason: "NSX API returned 200 response code for PATCH",
LastTransitionTime: transitionTime,
},
}
r.updateStaticRouteStatusConditions(ctx, static_route, newConditions)
r.updateStaticRouteStatusConditions(ctx, staticRoute, newConditions)
}

func (r *StaticRouteReconciler) setStaticRouteReadyStatusFalse(ctx *context.Context, static_route *v1alpha1.StaticRoute, err *error) {
func (r *StaticRouteReconciler) setStaticRouteReadyStatusFalse(ctx *context.Context, staticRoute *v1alpha1.StaticRoute, transitionTime metav1.Time, err *error) {
newConditions := []v1alpha1.StaticRouteCondition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionFalse,
Message: "NSX Static Route could not be created/updated/deleted",
Reason: fmt.Sprintf("Error occurred while processing the Static Route CR. Please check the config and try again. Error: %v", *err),
Type: v1alpha1.Ready,
Status: v1.ConditionFalse,
Message: "NSX Static Route could not be created/updated/deleted",
Reason: fmt.Sprintf("Error occurred while processing the Static Route CR. Please check the config and try again. Error: %v", *err),
LastTransitionTime: transitionTime,
},
}
r.updateStaticRouteStatusConditions(ctx, static_route, newConditions)
r.updateStaticRouteStatusConditions(ctx, staticRoute, newConditions)
}

func (r *StaticRouteReconciler) updateStaticRouteStatusConditions(ctx *context.Context, static_route *v1alpha1.StaticRoute, newConditions []v1alpha1.StaticRouteCondition) {
func (r *StaticRouteReconciler) updateStaticRouteStatusConditions(ctx *context.Context, staticRoute *v1alpha1.StaticRoute, newConditions []v1alpha1.StaticRouteCondition) {
conditionsUpdated := false
for i := range newConditions {
if r.mergeStaticRouteStatusCondition(static_route, &newConditions[i]) {
if r.mergeStaticRouteStatusCondition(staticRoute, &newConditions[i]) {
conditionsUpdated = true
}
}
if conditionsUpdated {
r.Client.Status().Update(*ctx, static_route)
log.V(1).Info("Updated Static Route CRD", "Name", static_route.Name, "Namespace", static_route.Namespace, "New Conditions", newConditions)
r.Client.Status().Update(*ctx, staticRoute)
log.V(1).Info("Updated Static Route CRD", "Name", staticRoute.Name, "Namespace", staticRoute.Namespace, "New Conditions", newConditions)
}
}

func (r *StaticRouteReconciler) mergeStaticRouteStatusCondition(static_route *v1alpha1.StaticRoute, newCondition *v1alpha1.StaticRouteCondition) bool {
matchedCondition := getExistingConditionOfType(v1alpha1.StaticRouteStatusCondition(newCondition.Type), static_route.Status.Conditions)
func (r *StaticRouteReconciler) mergeStaticRouteStatusCondition(staticRoute *v1alpha1.StaticRoute, newCondition *v1alpha1.StaticRouteCondition) bool {
matchedCondition := getExistingConditionOfType(v1alpha1.StaticRouteStatusCondition(newCondition.Type), staticRoute.Status.Conditions)

if reflect.DeepEqual(matchedCondition, newCondition) {
log.V(2).Info("Conditions already match", "New Condition", newCondition, "Existing Condition", matchedCondition)
Expand All @@ -168,7 +171,7 @@ func (r *StaticRouteReconciler) mergeStaticRouteStatusCondition(static_route *v1
matchedCondition.Message = newCondition.Message
matchedCondition.Status = newCondition.Status
} else {
static_route.Status.Conditions = append(static_route.Status.Conditions, *newCondition)
staticRoute.Status.Conditions = append(staticRoute.Status.Conditions, *newCondition)
}
return true
}
Expand Down
37 changes: 21 additions & 16 deletions pkg/controllers/subnet/subnet_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -177,25 +178,27 @@ func (r *SubnetReconciler) updateSubnetStatus(obj *v1alpha1.Subnet) error {
return nil
}

func (r *SubnetReconciler) setSubnetReadyStatusTrue(ctx *context.Context, subnet *v1alpha1.Subnet) {
func (r *SubnetReconciler) setSubnetReadyStatusTrue(ctx *context.Context, subnet *v1alpha1.Subnet, transitionTime metav1.Time) {
newConditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Subnet has been successfully created/updated",
Reason: "SubnetCreated",
Type: v1alpha1.Ready,
Status: v1.ConditionTrue,
Message: "NSX Subnet has been successfully created/updated",
Reason: "SubnetCreated",
LastTransitionTime: transitionTime,
},
}
r.updateSubnetStatusConditions(ctx, subnet, newConditions)
}

func (r *SubnetReconciler) setSubnetReadyStatusFalse(ctx *context.Context, subnet *v1alpha1.Subnet, msg string) {
func (r *SubnetReconciler) setSubnetReadyStatusFalse(ctx *context.Context, subnet *v1alpha1.Subnet, transitionTime metav1.Time, msg string) {
newConditions := []v1alpha1.Condition{
{
Type: v1alpha1.Ready,
Status: v1.ConditionFalse,
Message: "NSX Subnet could not be created/updated",
Reason: "SubnetNotReady",
Type: v1alpha1.Ready,
Status: v1.ConditionFalse,
Message: "NSX Subnet could not be created/updated",
Reason: "SubnetNotReady",
LastTransitionTime: transitionTime,
},
}
if msg != "" {
Expand All @@ -212,9 +215,11 @@ func (r *SubnetReconciler) updateSubnetStatusConditions(ctx *context.Context, su
}
}
if conditionsUpdated {
r.Client.Status().Update(*ctx, subnet)
log.V(1).Info("updated Subnet", "Name", subnet.Name, "Namespace", subnet.Namespace,
"New Conditions", newConditions)
if err := r.Client.Status().Update(*ctx, subnet); err != nil {
log.Error(err, "failed to update subnet status", "Name", subnet.Name, "Namespace", subnet.Namespace)
} else {
log.Info("updated Subnet", "Name", subnet.Name, "Namespace", subnet.Namespace, "New Conditions", newConditions)
}
}
}

Expand Down Expand Up @@ -246,17 +251,17 @@ func getExistingConditionOfType(conditionType v1alpha1.ConditionType, existingCo
}

func updateFail(r *SubnetReconciler, c *context.Context, o *v1alpha1.Subnet, m string) {
r.setSubnetReadyStatusFalse(c, o, m)
r.setSubnetReadyStatusFalse(c, o, metav1.Now(), m)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResTypeSubnet)
}

func deleteFail(r *SubnetReconciler, c *context.Context, o *v1alpha1.Subnet, m string) {
r.setSubnetReadyStatusFalse(c, o, m)
r.setSubnetReadyStatusFalse(c, o, metav1.Now(), m)
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, MetricResTypeSubnet)
}

func updateSuccess(r *SubnetReconciler, c *context.Context, o *v1alpha1.Subnet) {
r.setSubnetReadyStatusTrue(c, o)
r.setSubnetReadyStatusTrue(c, o, metav1.Now())
metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, MetricResTypeSubnet)
}

Expand Down
Loading

0 comments on commit 8b9d57e

Please sign in to comment.