Skip to content

Commit e45dd7a

Browse files
committed
feat(subroutine): implement finalizer for Deployment subroutine
On-behalf-of: @SAP angel.kafazov@sap.com Signed-off-by: Angel Kafazov <akafazov@cst-bg.net>
1 parent 867ad56 commit e45dd7a

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

pkg/subroutines/deployment.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,38 @@ func (r *DeploymentSubroutine) GetName() string {
5050
return DeploymentSubroutineName
5151
}
5252

53-
func (r *DeploymentSubroutine) Finalize(_ context.Context, _ runtimeobject.RuntimeObject) (ctrl.Result, errors.OperatorError) {
53+
// DeploymentSubroutineFinalizer ensures cleanup of FluxCD resources managed by this subroutine.
54+
const DeploymentSubroutineFinalizer = "platform-mesh.core.platform-mesh.io/deployment-finalizer"
55+
56+
func (r *DeploymentSubroutine) Finalize(ctx context.Context, _ runtimeobject.RuntimeObject) (ctrl.Result, errors.OperatorError) {
57+
log := logger.LoadLoggerFromContext(ctx).ChildLogger("subroutine", r.GetName())
58+
59+
// Delete FluxCD Resource
60+
resource := &unstructured.Unstructured{}
61+
resource.SetGroupVersionKind(schema.GroupVersionKind{Group: "delivery.ocm.software", Version: "v1alpha1", Kind: "Resource"})
62+
resource.SetName("platform-mesh-operator-components")
63+
resource.SetNamespace("default")
64+
if err := r.client.Delete(ctx, resource); err != nil && !kerrors.IsNotFound(err) {
65+
log.Warn().Err(err).Msg("Failed to delete Resource during finalize")
66+
return ctrl.Result{}, errors.NewOperatorError(err, false, true)
67+
}
68+
69+
// Delete FluxCD HelmRelease
70+
release := &unstructured.Unstructured{}
71+
release.SetGroupVersionKind(schema.GroupVersionKind{Group: "helm.toolkit.fluxcd.io", Version: "v2", Kind: "HelmRelease"})
72+
release.SetName("platform-mesh-operator-components")
73+
release.SetNamespace("default")
74+
if err := r.client.Delete(ctx, release); err != nil && !kerrors.IsNotFound(err) {
75+
log.Warn().Err(err).Msg("Failed to delete HelmRelease during finalize")
76+
return ctrl.Result{}, errors.NewOperatorError(err, false, true)
77+
}
78+
79+
// If we reach here, both objects are deleted or did not exist. The controller will remove our finalizer.
5480
return ctrl.Result{}, nil
5581
}
5682

5783
func (r *DeploymentSubroutine) Finalizers() []string { // coverage-ignore
58-
return []string{}
84+
return []string{DeploymentSubroutineFinalizer}
5985
}
6086

6187
func (r *DeploymentSubroutine) Process(ctx context.Context, runtimeObj runtimeobject.RuntimeObject) (ctrl.Result, errors.OperatorError) {

pkg/subroutines/deployment_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"github.com/stretchr/testify/mock"
99
"github.com/stretchr/testify/suite"
1010
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
11+
kerrors "k8s.io/apimachinery/pkg/api/errors"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1213
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14+
"k8s.io/apimachinery/pkg/runtime/schema"
1315
"k8s.io/apimachinery/pkg/types"
1416
"sigs.k8s.io/controller-runtime/pkg/client"
1517

@@ -20,6 +22,7 @@ import (
2022

2123
"github.com/platform-mesh/platform-mesh-operator/api/v1alpha1"
2224
"github.com/platform-mesh/platform-mesh-operator/internal/config"
25+
ctrl "sigs.k8s.io/controller-runtime"
2326
)
2427

2528
type DeployTestSuite struct {
@@ -154,3 +157,37 @@ func (s *DeployTestSuite) Test_applyReleaseWithValues() {
154157
s.Assert().NoError(err, "ApplyReleaseWithValues should not return an error")
155158

156159
}
160+
161+
func (s *DeployTestSuite) Test_Finalize_DeletesFluxObjects() {
162+
ctx := context.TODO()
163+
164+
// mock deletions
165+
s.clientMock.EXPECT().Delete(mock.Anything, mock.MatchedBy(func(obj client.Object) bool {
166+
u := obj.(*unstructured.Unstructured)
167+
gvk := u.GroupVersionKind()
168+
return gvk.Group == "delivery.ocm.software" && gvk.Version == "v1alpha1" && gvk.Kind == "Resource" && u.GetName() == "platform-mesh-operator-components" && u.GetNamespace() == "default"
169+
})).Return(nil).Once()
170+
171+
s.clientMock.EXPECT().Delete(mock.Anything, mock.MatchedBy(func(obj client.Object) bool {
172+
u := obj.(*unstructured.Unstructured)
173+
gvk := u.GroupVersionKind()
174+
return gvk.Group == "helm.toolkit.fluxcd.io" && gvk.Version == "v2" && gvk.Kind == "HelmRelease" && u.GetName() == "platform-mesh-operator-components" && u.GetNamespace() == "default"
175+
})).Return(nil).Once()
176+
177+
// asserts
178+
res, opErr := s.testObj.Finalize(ctx, &v1alpha1.PlatformMesh{})
179+
s.Require().Nil(opErr)
180+
s.Require().Equal(ctrl.Result{}, res)
181+
}
182+
183+
func (s *DeployTestSuite) Test_Finalize_AlreadyDeleted() {
184+
ctx := context.TODO()
185+
186+
// mock deletions with NotFound errors
187+
s.clientMock.EXPECT().Delete(mock.Anything, mock.Anything).Return(kerrors.NewNotFound(schema.GroupResource{Group: "delivery.ocm.software", Resource: "Resource"}, "platform-mesh-operator-components")).Once()
188+
s.clientMock.EXPECT().Delete(mock.Anything, mock.Anything).Return(kerrors.NewNotFound(schema.GroupResource{Group: "helm.toolkit.fluxcd.io", Resource: "HelmRelease"}, "platform-mesh-operator-components")).Once()
189+
190+
res, opErr := s.testObj.Finalize(ctx, &v1alpha1.PlatformMesh{})
191+
s.Require().Nil(opErr)
192+
s.Require().Equal(ctrl.Result{}, res)
193+
}

0 commit comments

Comments
 (0)