diff --git a/pkg/controllers/ippool/ippool_controller.go b/pkg/controllers/ippool/ippool_controller.go index 35d131c58..71cb407f6 100644 --- a/pkg/controllers/ippool/ippool_controller.go +++ b/pkg/controllers/ippool/ippool_controller.go @@ -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" @@ -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, @@ -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 @@ -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 diff --git a/pkg/controllers/ippool/ippool_controller_test.go b/pkg/controllers/ippool/ippool_controller_test.go index 6d7f804a6..7b13df360 100644 --- a/pkg/controllers/ippool/ippool_controller_test.go +++ b/pkg/controllers/ippool/ippool_controller_test.go @@ -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") diff --git a/pkg/controllers/securitypolicy/securitypolicy_controller.go b/pkg/controllers/securitypolicy/securitypolicy_controller.go index 1090249e0..c1e654cd1 100644 --- a/pkg/controllers/securitypolicy/securitypolicy_controller.go +++ b/pkg/controllers/securitypolicy/securitypolicy_controller.go @@ -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" @@ -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) } @@ -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) } @@ -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, @@ -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) @@ -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 } diff --git a/pkg/controllers/staticroute/staticroute_controller.go b/pkg/controllers/staticroute/staticroute_controller.go index 46c75f741..de2cfded0 100644 --- a/pkg/controllers/staticroute/staticroute_controller.go +++ b/pkg/controllers/staticroute/staticroute_controller.go @@ -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" @@ -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) } @@ -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) @@ -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 } diff --git a/pkg/controllers/subnet/subnet_controller.go b/pkg/controllers/subnet/subnet_controller.go index 95b32cfc4..6e0a644d2 100644 --- a/pkg/controllers/subnet/subnet_controller.go +++ b/pkg/controllers/subnet/subnet_controller.go @@ -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" @@ -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 != "" { @@ -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) + } } } @@ -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) } diff --git a/pkg/controllers/subnetport/subnetport_controller.go b/pkg/controllers/subnetport/subnetport_controller.go index 3558f68dc..03b1da994 100644 --- a/pkg/controllers/subnetport/subnetport_controller.go +++ b/pkg/controllers/subnetport/subnetport_controller.go @@ -15,6 +15,7 @@ import ( vmv1alpha1 "github.com/vmware-tanzu/vm-operator/api/v1alpha1" 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" @@ -259,19 +260,20 @@ func (r *SubnetPortReconciler) GarbageCollector(cancel chan bool, timeout time.D } } -func (r *SubnetPortReconciler) setSubnetPortReadyStatusTrue(ctx *context.Context, subnetPort *v1alpha1.SubnetPort) { +func (r *SubnetPortReconciler) setSubnetPortReadyStatusTrue(ctx *context.Context, subnetPort *v1alpha1.SubnetPort, transitionTime metav1.Time) { newConditions := []v1alpha1.Condition{ { - Type: v1alpha1.Ready, - Status: v1.ConditionTrue, - Message: "NSX subnet port has been successfully created/updated", - Reason: "NSX API returned 200 response code for PATCH", + Type: v1alpha1.Ready, + Status: v1.ConditionTrue, + Message: "NSX subnet port has been successfully created/updated", + Reason: "NSX API returned 200 response code for PATCH", + LastTransitionTime: transitionTime, }, } r.UpdateSubnetPortStatusConditions(ctx, subnetPort, newConditions) } -func (r *SubnetPortReconciler) setSubnetPortReadyStatusFalse(ctx *context.Context, subnetPort *v1alpha1.SubnetPort, err *error) { +func (r *SubnetPortReconciler) setSubnetPortReadyStatusFalse(ctx *context.Context, subnetPort *v1alpha1.SubnetPort, transitionTime metav1.Time, err *error) { newConditions := []v1alpha1.Condition{ { Type: v1alpha1.Ready, @@ -281,6 +283,7 @@ func (r *SubnetPortReconciler) setSubnetPortReadyStatusFalse(ctx *context.Contex "error occurred while processing the SubnetPort CR. Error: %v", *err, ), + LastTransitionTime: transitionTime, }, } r.UpdateSubnetPortStatusConditions(ctx, subnetPort, newConditions) @@ -328,17 +331,17 @@ func getExistingConditionOfType(conditionType v1alpha1.ConditionType, existingCo } func updateFail(r *SubnetPortReconciler, c *context.Context, o *v1alpha1.SubnetPort, e *error) { - r.setSubnetPortReadyStatusFalse(c, o, e) + r.setSubnetPortReadyStatusFalse(c, o, metav1.Now(), e) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResTypeSubnetPort) } func deleteFail(r *SubnetPortReconciler, c *context.Context, o *v1alpha1.SubnetPort, e *error) { - r.setSubnetPortReadyStatusFalse(c, o, e) + r.setSubnetPortReadyStatusFalse(c, o, metav1.Now(), e) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, MetricResTypeSubnetPort) } func updateSuccess(r *SubnetPortReconciler, c *context.Context, o *v1alpha1.SubnetPort) { - r.setSubnetPortReadyStatusTrue(c, o) + r.setSubnetPortReadyStatusTrue(c, o, metav1.Now()) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, MetricResTypeSubnetPort) } diff --git a/pkg/controllers/subnetset/subnetset_controller.go b/pkg/controllers/subnetset/subnetset_controller.go index 34920b7b4..4d60ba33e 100644 --- a/pkg/controllers/subnetset/subnetset_controller.go +++ b/pkg/controllers/subnetset/subnetset_controller.go @@ -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/util/sets" ctrl "sigs.k8s.io/controller-runtime" @@ -127,17 +128,17 @@ func (r *SubnetSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } func updateFail(r *SubnetSetReconciler, c *context.Context, o *v1alpha1.SubnetSet, m string) { - r.setSubnetSetReadyStatusFalse(c, o, m) + r.setSubnetSetReadyStatusFalse(c, o, metav1.Now(), m) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateFailTotal, MetricResTypeSubnetSet) } func deleteFail(r *SubnetSetReconciler, c *context.Context, o *v1alpha1.SubnetSet, m string) { - r.setSubnetSetReadyStatusFalse(c, o, m) + r.setSubnetSetReadyStatusFalse(c, o, metav1.Now(), m) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteFailTotal, MetricResTypeSubnetSet) } func updateSuccess(r *SubnetSetReconciler, c *context.Context, o *v1alpha1.SubnetSet) { - r.setSubnetSetReadyStatusTrue(c, o) + r.setSubnetSetReadyStatusTrue(c, o, metav1.Now()) metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerUpdateSuccessTotal, MetricResTypeSubnetSet) } @@ -145,25 +146,27 @@ func deleteSuccess(r *SubnetSetReconciler, _ *context.Context, _ *v1alpha1.Subne metrics.CounterInc(r.Service.NSXConfig, metrics.ControllerDeleteSuccessTotal, MetricResTypeSubnetSet) } -func (r *SubnetSetReconciler) setSubnetSetReadyStatusTrue(ctx *context.Context, subnetset *v1alpha1.SubnetSet) { +func (r *SubnetSetReconciler) setSubnetSetReadyStatusTrue(ctx *context.Context, subnetset *v1alpha1.SubnetSet, transitionTime metav1.Time) { newConditions := []v1alpha1.Condition{ { - Type: v1alpha1.Ready, - Status: v1.ConditionTrue, - Message: "NSX SubnetSet has been successfully created/updated", - Reason: "SubnetsReady", + Type: v1alpha1.Ready, + Status: v1.ConditionTrue, + Message: "NSX SubnetSet has been successfully created/updated", + Reason: "SubnetsReady", + LastTransitionTime: transitionTime, }, } r.updateSubnetSetStatusConditions(ctx, subnetset, newConditions) } -func (r *SubnetSetReconciler) setSubnetSetReadyStatusFalse(ctx *context.Context, subnetset *v1alpha1.SubnetSet, m string) { +func (r *SubnetSetReconciler) setSubnetSetReadyStatusFalse(ctx *context.Context, subnetset *v1alpha1.SubnetSet, transitionTime metav1.Time, m string) { newConditions := []v1alpha1.Condition{ { - Type: v1alpha1.Ready, - Status: v1.ConditionFalse, - Message: "NSX SubnetSet could not be created/updated", - Reason: "SubnetNotReady", + Type: v1alpha1.Ready, + Status: v1.ConditionFalse, + Message: "NSX SubnetSet could not be created/updated", + Reason: "SubnetNotReady", + LastTransitionTime: transitionTime, }, } if m != "" { @@ -180,9 +183,11 @@ func (r *SubnetSetReconciler) updateSubnetSetStatusConditions(ctx *context.Conte } } if conditionsUpdated { - r.Client.Status().Update(*ctx, subnetset) - log.V(1).Info("updated Subnet", "Name", subnetset.Name, "Namespace", subnetset.Namespace, - "New Conditions", newConditions) + if err := r.Client.Status().Update(*ctx, subnetset); err != nil { + log.Error(err, "failed to update status", "Name", subnetset.Name, "Namespace", subnetset.Namespace) + } else { + log.Info("updated SubnetSet", "Name", subnetset.Name, "Namespace", subnetset.Namespace, "New Conditions", newConditions) + } } } diff --git a/pkg/controllers/vpc/vpc_utils.go b/pkg/controllers/vpc/vpc_utils.go index 3732ca275..0e633217b 100644 --- a/pkg/controllers/vpc/vpc_utils.go +++ b/pkg/controllers/vpc/vpc_utils.go @@ -9,6 +9,7 @@ import ( "strings" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/vmware-tanzu/nsx-operator/pkg/apis/v1alpha1" @@ -21,10 +22,11 @@ import ( func setVPCReadyStatusFalse(ctx *context.Context, vpc *v1alpha1.VPC, err *error, client client.Client) { newConditions := []v1alpha1.Condition{ { - Type: v1alpha1.Ready, - Status: v1.ConditionFalse, - Message: "NSX VPC could not be created/updated", - Reason: fmt.Sprintf("Error occurred while processing the VPC CR. Please check the config and try again. Error: %v", *err), + Type: v1alpha1.Ready, + Status: v1.ConditionFalse, + Message: "NSX VPC could not be created/updated", + Reason: fmt.Sprintf("Error occurred while processing the VPC CR. Please check the config and try again. Error: %v", *err), + LastTransitionTime: metav1.Now(), }, } updateVPCStatusConditions(ctx, vpc, newConditions, client, "", "", "", "", []string{}) @@ -78,10 +80,11 @@ func deleteSuccess(nsxConfig *config.NSXOperatorConfig, _ *context.Context, _ *v func setVPCReadyStatusTrue(ctx *context.Context, vpc *v1alpha1.VPC, client client.Client, path, snatIP, subnetPath, cidr string, privateCidrs []string) { newConditions := []v1alpha1.Condition{ { - Type: v1alpha1.Ready, - Status: v1.ConditionTrue, - Message: "NSX VPC has been successfully created/updated", - Reason: "NSX API returned 200 response code for PATCH", + Type: v1alpha1.Ready, + Status: v1.ConditionTrue, + Message: "NSX VPC has been successfully created/updated", + Reason: "NSX API returned 200 response code for PATCH", + LastTransitionTime: metav1.Now(), }, } updateVPCStatusConditions(ctx, vpc, newConditions, client, path, snatIP, subnetPath, cidr, privateCidrs)