Skip to content

Commit 4d8ebf0

Browse files
authored
chore: add remove-finalizers hook and update module-sdk to v0.7.0 (#44)
* chore: add 030-remove-finalizers-on-module-delete hook and update module-sdk to v0.7.0 - Add hook 030-remove-finalizers-on-module-delete - Hook logic: remove finalizers from Secrets, ConfigMaps, StorageClass (if controller creates), CRs from crd folder - Update module-sdk from v0.2.0 to v0.7.0 (where applicable) - Add CRGVKsForFinalizerRemoval and WebhookConfigurationsToDelete to consts * fix: add sds-common-lib and deps for remove-finalizers hook build - Add github.com/deckhouse/sds-common-lib v0.0.0-20250428090414-0c2938b30fa7 - Add github.com/kubernetes-csi/external-snapshotter/client/v8 - Add k8s.io/api, k8s.io/apiextensions-apiserver, k8s.io/client-go * chore: add gitleaks config with allowlist for false positives * chore: remove .gitleaks.toml (use centralized base config) * docs: replace UUID examples with gitleaks stopword * chore: add local .gitleaks.toml extending base config * chore: add gitleaks allowlist for images/*.patch files * chore: switch gitleaks to useDefault for GitHub Actions compatibility
1 parent 5f4d85a commit 4d8ebf0

File tree

8 files changed

+200
-8
lines changed

8 files changed

+200
-8
lines changed

.gitleaks.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Use default gitleaks rules + module allowlist
2+
[extend]
3+
useDefault = true
4+
5+
[allowlist]
6+
paths = [
7+
'''(?:^|/)images/.*\.patch$''',
8+
]

docs/USAGE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Spec:
3939
Persistent Volume Claim Name: my-first-snapshot
4040
Volume Snapshot Class Name: sds-replicated-volume
4141
Status:
42-
Bound Volume Snapshot Content Name: snapcontent-b6072ab7-6ddf-482b-a4e3-693088136d2c
42+
Bound Volume Snapshot Content Name: snapcontent-014df517-39d1-4453-b7b3-9930c563627c
4343
Creation Time: 2020-06-04T13:02:28Z
4444
Ready To Use: true
4545
Restore Size: 500Mi

docs/USAGE.ru.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Spec:
3939
Persistent Volume Claim Name: my-first-snapshot
4040
Volume Snapshot Class Name: sds-replicated-volume
4141
Status:
42-
Bound Volume Snapshot Content Name: snapcontent-b6072ab7-6ddf-482b-a4e3-693088136d2c
42+
Bound Volume Snapshot Content Name: snapcontent-014df517-39d1-4453-b7b3-9930c563627c
4343
Creation Time: 2020-06-04T13:02:28Z
4444
Ready To Use: true
4545
Restore Size: 500Mi
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
Copyright 2025 Flant JSC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package hooks_common
18+
19+
import (
20+
"context"
21+
"errors"
22+
"fmt"
23+
24+
snapv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
25+
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
26+
corev1 "k8s.io/api/core/v1"
27+
v1 "k8s.io/api/core/v1"
28+
storagev1 "k8s.io/api/storage/v1"
29+
sv1 "k8s.io/api/storage/v1"
30+
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
31+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
32+
"k8s.io/apimachinery/pkg/runtime/schema"
33+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
34+
"sigs.k8s.io/controller-runtime/pkg/client"
35+
36+
"github.com/deckhouse/snapshot-controller/hooks/go/consts"
37+
"github.com/deckhouse/module-sdk/pkg"
38+
"github.com/deckhouse/module-sdk/pkg/registry"
39+
"github.com/deckhouse/sds-common-lib/kubeclient"
40+
)
41+
42+
const hookName = "remove-finalizers-on-module-delete"
43+
44+
func removeFinalizersFromObject(ctx context.Context, cl client.Client, obj client.Object, logger pkg.Logger) error {
45+
logger.Info(fmt.Sprintf("[%s]: Removing finalizers from %s %s", hookName, obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName()))
46+
47+
patch := client.MergeFrom(obj.DeepCopyObject().(client.Object))
48+
obj.SetFinalizers(nil)
49+
50+
if err := cl.Patch(ctx, obj, patch); err != nil {
51+
return fmt.Errorf("failed to patch %s %s: %w", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName(), err)
52+
}
53+
return nil
54+
}
55+
56+
var _ = registry.RegisterFunc(configRemoveFinalizersOnModuleDelete, handlerRemoveFinalizersOnModuleDelete)
57+
58+
var configRemoveFinalizersOnModuleDelete = &pkg.HookConfig{
59+
OnAfterDeleteHelm: &pkg.OrderedConfig{Order: 10},
60+
}
61+
62+
func handlerRemoveFinalizersOnModuleDelete(ctx context.Context, input *pkg.HookInput) error {
63+
input.Logger.Info(fmt.Sprintf("[%s]: Started removing finalizers on module delete", hookName))
64+
var resultErr error
65+
66+
cl, err := kubeclient.New(
67+
admissionregistrationv1.AddToScheme,
68+
clientgoscheme.AddToScheme,
69+
extv1.AddToScheme,
70+
v1.AddToScheme,
71+
sv1.AddToScheme,
72+
snapv1.AddToScheme)
73+
if err != nil {
74+
return fmt.Errorf("failed to initialize kube client: %w", err)
75+
}
76+
77+
// Remove finalizers from Secrets in module namespace
78+
secretList := &corev1.SecretList{}
79+
if err := cl.List(ctx, secretList, client.InNamespace(consts.ModuleNamespace)); err != nil {
80+
resultErr = errors.Join(resultErr, fmt.Errorf("[%s]: failed to list secrets: %w", hookName, err))
81+
} else {
82+
for i := range secretList.Items {
83+
if err := removeFinalizersFromObject(ctx, cl, &secretList.Items[i], input.Logger); err != nil {
84+
resultErr = errors.Join(resultErr, err)
85+
}
86+
}
87+
}
88+
89+
// Remove finalizers from ConfigMaps in module namespace
90+
configMapList := &corev1.ConfigMapList{}
91+
if err := cl.List(ctx, configMapList, client.InNamespace(consts.ModuleNamespace)); err != nil {
92+
resultErr = errors.Join(resultErr, fmt.Errorf("[%s]: failed to list configmaps: %w", hookName, err))
93+
} else {
94+
for i := range configMapList.Items {
95+
if err := removeFinalizersFromObject(ctx, cl, &configMapList.Items[i], input.Logger); err != nil {
96+
resultErr = errors.Join(resultErr, err)
97+
}
98+
}
99+
}
100+
101+
// Delete ValidatingWebhookConfigurations if configured
102+
for _, name := range consts.WebhookConfigurationsToDelete {
103+
vwc := &admissionregistrationv1.ValidatingWebhookConfiguration{}
104+
if err := cl.Get(ctx, client.ObjectKey{Name: name}, vwc); err == nil {
105+
input.Logger.Info(fmt.Sprintf("[%s]: Deleting ValidatingWebhookConfiguration %s", hookName, name))
106+
if err := cl.Delete(ctx, vwc); err != nil {
107+
resultErr = errors.Join(resultErr, fmt.Errorf("[%s]: failed to delete ValidatingWebhookConfiguration %s: %w", hookName, name, err))
108+
}
109+
}
110+
}
111+
112+
// Remove finalizers from StorageClass if controller creates them
113+
for _, provisioner := range consts.AllowedProvisioners {
114+
scList := &storagev1.StorageClassList{}
115+
if err := cl.List(ctx, scList); err != nil {
116+
resultErr = errors.Join(resultErr, fmt.Errorf("[%s]: failed to list storage classes: %w", hookName, err))
117+
break
118+
}
119+
for i := range scList.Items {
120+
if scList.Items[i].Provisioner != provisioner {
121+
continue
122+
}
123+
if err := removeFinalizersFromObject(ctx, cl, &scList.Items[i], input.Logger); err != nil {
124+
resultErr = errors.Join(resultErr, err)
125+
}
126+
}
127+
}
128+
129+
// Remove finalizers from CRs from module's crd folder
130+
for _, crgvk := range consts.CRGVKsForFinalizerRemoval {
131+
ns := ""
132+
if crgvk.Namespaced {
133+
ns = consts.ModuleNamespace
134+
}
135+
crList := &unstructured.UnstructuredList{}
136+
crList.SetGroupVersionKind(schema.GroupVersionKind{
137+
Group: crgvk.Group,
138+
Version: crgvk.Version,
139+
Kind: crgvk.Kind + "List",
140+
})
141+
if err := cl.List(ctx, crList, client.InNamespace(ns)); err != nil {
142+
input.Logger.Info(fmt.Sprintf("[%s]: skipping CR %s (may not exist): %v", hookName, crgvk.Kind, err))
143+
continue
144+
}
145+
for i := range crList.Items {
146+
cr := &crList.Items[i]
147+
if len(cr.GetFinalizers()) == 0 {
148+
continue
149+
}
150+
if err := removeFinalizersFromObject(ctx, cl, cr, input.Logger); err != nil {
151+
resultErr = errors.Join(resultErr, err)
152+
}
153+
}
154+
}
155+
156+
input.Logger.Info(fmt.Sprintf("[%s]: Finished removing finalizers on module delete", hookName))
157+
return resultErr
158+
}

hooks/go/consts/consts.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,20 @@ const (
2323
ValidatingWebhookCertCn string = "snapshot-validation-webhook"
2424
WebhookCertCn string = "webhooks"
2525
)
26+
27+
var AllowedProvisioners = []string{}
28+
29+
var WebhookConfigurationsToDelete = []string{}
30+
31+
var CRGVKsForFinalizerRemoval = []CRGVK{
32+
{Group: "snapshot.storage.k8s.io", Version: "v1", Kind: "VolumeSnapshot", Namespaced: true},
33+
{Group: "snapshot.storage.k8s.io", Version: "v1", Kind: "VolumeSnapshotContent", Namespaced: false},
34+
{Group: "snapshot.storage.k8s.io", Version: "v1", Kind: "VolumeSnapshotClass", Namespaced: false},
35+
}
36+
37+
type CRGVK struct {
38+
Group string
39+
Version string
40+
Kind string
41+
Namespaced bool
42+
}

hooks/go/go.mod

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ module github.com/deckhouse/snapshot-controller/hooks/go
22

33
go 1.25.7
44

5-
require github.com/deckhouse/module-sdk v0.7.0
5+
require (
6+
github.com/deckhouse/module-sdk v0.7.0
7+
github.com/deckhouse/sds-common-lib v0.0.0-20250428090414-0c2938b30fa7
8+
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0
9+
k8s.io/api v0.32.10
10+
k8s.io/apiextensions-apiserver v0.32.10
11+
k8s.io/apimachinery v0.32.10
12+
k8s.io/client-go v0.32.10
13+
sigs.k8s.io/controller-runtime v0.20.4
14+
)
615

716
require (
817
github.com/DataDog/gostackparse v0.7.0 // indirect
@@ -80,14 +89,9 @@ require (
8089
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
8190
gopkg.in/inf.v0 v0.9.1 // indirect
8291
gopkg.in/yaml.v3 v3.0.1 // indirect
83-
k8s.io/api v0.32.10 // indirect
84-
k8s.io/apiextensions-apiserver v0.32.10 // indirect
85-
k8s.io/apimachinery v0.32.10 // indirect
86-
k8s.io/client-go v0.32.10 // indirect
8792
k8s.io/klog/v2 v2.130.1 // indirect
8893
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
8994
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
90-
sigs.k8s.io/controller-runtime v0.20.4 // indirect
9195
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
9296
sigs.k8s.io/randfill v1.0.0 // indirect
9397
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect

hooks/go/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250814094423-e9f108b41a1a h1:An8
1919
github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250814094423-e9f108b41a1a/go.mod h1:pbAxTSDcPmwyl3wwKDcEB3qdxHnRxqTV+J0K+sha8bw=
2020
github.com/deckhouse/module-sdk v0.7.0 h1:zS7QjgLqaSqjDTeH6B4k7Fl0z8biuKACL9A6GtpIGeo=
2121
github.com/deckhouse/module-sdk v0.7.0/go.mod h1:+EbBnP8z+poIihgL4l1oxHng5ePqDUK44c39u7sEBss=
22+
github.com/deckhouse/sds-common-lib v0.0.0-20250428090414-0c2938b30fa7 h1:rudy3ychoDH7j8ft9feuF+2lt4PFjkBZOzvzgsT+mQU=
23+
github.com/deckhouse/sds-common-lib v0.0.0-20250428090414-0c2938b30fa7/go.mod h1:tAZI7ZaVeJi5/Fe5Mebw3d6NC4nTHUOOTwZFnHHzxFU=
2224
github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=
2325
github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
2426
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
@@ -103,6 +105,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
103105
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
104106
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
105107
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
108+
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 h1:Q3jQ1NkFqv5o+F8dMmHd8SfEmlcwNeo1immFApntEwE=
109+
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y=
106110
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
107111
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
108112
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

hooks/go/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package main
1919
import (
2020
"github.com/deckhouse/module-sdk/pkg/app"
2121
_ "github.com/deckhouse/snapshot-controller/hooks/go/020-webhook-certs"
22+
_ "github.com/deckhouse/snapshot-controller/hooks/go/030-remove-finalizers-on-module-delete"
2223
_ "github.com/deckhouse/snapshot-controller/hooks/go/030-snapshot-validation-webhook-certs"
2324
)
2425

0 commit comments

Comments
 (0)