Skip to content

Commit 2dc07d9

Browse files
duckhawkNikolayDemchukastef
authored
Move to go hooks (#90)
Signed-off-by: Aleksandr Stefurishin <[email protected]> Signed-off-by: Nikolay Demchuk <[email protected]> Co-authored-by: Nikolay Demchuk <[email protected]> Co-authored-by: Aleksandr Stefurishin <[email protected]>
1 parent a584d5c commit 2dc07d9

File tree

11 files changed

+230
-160
lines changed

11 files changed

+230
-160
lines changed

hooks/generate_scheduler_extender_certs.py

Lines changed: 0 additions & 44 deletions
This file was deleted.

hooks/go/020-webhook-certs/webhook-certs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package hooks_common
1919
import (
2020
"fmt"
2121

22-
consts "github.com/deckhouse/csi-nfs/hooks/go/consts"
22+
"github.com/deckhouse/csi-nfs/hooks/go/consts"
2323
tlscertificate "github.com/deckhouse/module-sdk/common-hooks/tls-certificate"
2424
)
2525

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
package generatecerts
17+
18+
import (
19+
"fmt"
20+
21+
"github.com/deckhouse/csi-nfs/hooks/go/consts"
22+
tlscertificate "github.com/deckhouse/module-sdk/common-hooks/tls-certificate"
23+
)
24+
25+
var _ = tlscertificate.RegisterInternalTLSHookEM(tlscertificate.GenSelfSignedTLSHookConf{
26+
CommonCACanonicalName: fmt.Sprintf("%s-%s", consts.ModulePluralName, consts.SchedulerCertCn),
27+
CN: fmt.Sprintf("%s-%s", consts.ModulePluralName, consts.SchedulerCertCn),
28+
TLSSecretName: fmt.Sprintf("%s-https-certs", consts.SchedulerCertCn),
29+
Namespace: consts.ModuleNamespace,
30+
SANs: tlscertificate.DefaultSANs([]string{
31+
fmt.Sprintf("%s-%s", consts.ModulePluralName, consts.SchedulerCertCn),
32+
fmt.Sprintf("%s-%s.%s", consts.ModulePluralName, consts.SchedulerCertCn, consts.ModuleNamespace),
33+
fmt.Sprintf("%s-%s.%s.svc", consts.ModulePluralName, consts.SchedulerCertCn, consts.ModuleNamespace),
34+
// %CLUSTER_DOMAIN%:// is a special value to generate SAN like 'svc_name.svc_namespace.svc.cluster.local'
35+
fmt.Sprintf("%%CLUSTER_DOMAIN%%://%s-%s.%s.svc", consts.ModulePluralName, consts.SchedulerCertCn, consts.ModuleNamespace),
36+
}),
37+
FullValuesPathPrefix: fmt.Sprintf("%s.internal.customSchedulerExtenderCert", consts.ModuleName),
38+
})
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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 schedulerextenderenabler
18+
19+
import (
20+
"context"
21+
"encoding/base64"
22+
"encoding/json"
23+
"fmt"
24+
"time"
25+
26+
"github.com/deckhouse/csi-nfs/api/v1alpha1"
27+
"github.com/deckhouse/csi-nfs/hooks/go/consts"
28+
"github.com/deckhouse/module-sdk/pkg"
29+
"github.com/deckhouse/module-sdk/pkg/registry"
30+
)
31+
32+
const (
33+
NFSStorageClassSnapshotName = "nfs-storage-classes"
34+
)
35+
36+
var (
37+
_ = registry.RegisterFunc(
38+
&pkg.HookConfig{
39+
Kubernetes: []pkg.KubernetesConfig{
40+
{
41+
Name: NFSStorageClassSnapshotName,
42+
APIVersion: "storage.deckhouse.io/v1alpha1",
43+
Kind: "NFSStorageClass",
44+
ExecuteHookOnEvents: ptr(true),
45+
ExecuteHookOnSynchronization: ptr(true),
46+
JqFilter: ".spec.workloadNodes",
47+
AllowFailure: ptr(true),
48+
},
49+
},
50+
Settings: &pkg.HookConfigSettings{
51+
ExecutionMinInterval: time.Second * 3,
52+
ExecutionBurst: 1,
53+
},
54+
Queue: fmt.Sprintf("modules/%s", consts.ModuleName),
55+
},
56+
mainHook,
57+
)
58+
)
59+
60+
func mainHook(ctx context.Context, input *pkg.HookInput) error {
61+
fmt.Println("Scheduler extender enabler hook started")
62+
shouldEnable := false
63+
64+
// Get snapshots using the standard approach
65+
snapshots := input.Snapshots.Get(NFSStorageClassSnapshotName)
66+
if len(snapshots) == 0 {
67+
fmt.Println("No snapshots found")
68+
// Don't return early - we need to disable the scheduler extender
69+
} else {
70+
fmt.Printf("Found %d snapshots\n", len(snapshots))
71+
72+
for i, snapshot := range snapshots {
73+
fmt.Printf("Processing snapshot %d: %v\n", i, snapshot)
74+
75+
// Try to access the snapshot data as JSON
76+
// The JqFilter extracts .spec.workloadNodes, so we should get NFSStorageClassWorkloadNodes directly
77+
// If workloadNodes is not configured, the JqFilter returns null
78+
79+
// The snapshot contains a base64-encoded JSON string
80+
// First, marshal the snapshot to get the base64 string
81+
snapshotBytes, err := json.Marshal(snapshot)
82+
if err != nil {
83+
fmt.Printf("Error marshaling snapshot %d: %v\n", i, err)
84+
continue
85+
}
86+
87+
// Remove quotes from the JSON string to get the base64 string
88+
base64Str := string(snapshotBytes[1 : len(snapshotBytes)-1])
89+
fmt.Printf("Snapshot %d base64: %s\n", i, base64Str)
90+
91+
// Decode the base64 string
92+
jsonBytes, err := base64.StdEncoding.DecodeString(base64Str)
93+
if err != nil {
94+
fmt.Printf("Error decoding base64 for snapshot %d: %v\n", i, err)
95+
continue
96+
}
97+
fmt.Printf("Snapshot %d decoded JSON: %s\n", i, string(jsonBytes))
98+
99+
// Try to unmarshal as NFSStorageClassWorkloadNodes
100+
workloadNodes := new(v1alpha1.NFSStorageClassWorkloadNodes)
101+
err = json.Unmarshal(jsonBytes, workloadNodes)
102+
if err != nil {
103+
fmt.Printf("Error unmarshaling snapshot %d as NFSStorageClassWorkloadNodes: %v\n", i, err)
104+
continue
105+
}
106+
107+
fmt.Printf("Successfully unmarshaled workload nodes: %+v\n", workloadNodes)
108+
109+
// Check if NodeSelector is configured
110+
if workloadNodes.NodeSelector == nil {
111+
fmt.Println("nodeSelector is nil")
112+
continue
113+
}
114+
115+
// Check if NodeSelector has any actual selectors
116+
if workloadNodes.NodeSelector.MatchLabels == nil && workloadNodes.NodeSelector.MatchExpressions == nil {
117+
fmt.Println("nodeSelector has no matchLabels or matchExpressions")
118+
continue
119+
}
120+
121+
fmt.Printf("Found valid nodeSelector: %+v\n", workloadNodes.NodeSelector)
122+
fmt.Println("NodeSelector is not empty. Should enable scheduler extender")
123+
shouldEnable = true
124+
break
125+
}
126+
}
127+
128+
enableLabel := fmt.Sprintf("%v.internal.shedulerExtenderEnabled", consts.ModuleName)
129+
130+
if shouldEnable {
131+
fmt.Println("Enable scheduler extender")
132+
input.Values.Set(enableLabel, true)
133+
} else {
134+
fmt.Println("Disable scheduler extender")
135+
input.Values.Set(enableLabel, false)
136+
}
137+
138+
return nil
139+
}
140+
141+
func ptr[T any](a T) *T {
142+
return &a
143+
}

hooks/go/consts/consts.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ limitations under the License.
1717
package consts
1818

1919
const (
20-
ModuleName string = "csiNfs"
21-
ModuleNamespace string = "d8-csi-nfs"
22-
ModulePluralName string = "csi-nfs"
23-
WebhookCertCn string = "webhooks"
20+
ModuleName string = "csiNfs"
21+
ModuleNamespace string = "d8-csi-nfs"
22+
ModulePluralName string = "csi-nfs"
23+
WebhookCertCn string = "webhooks"
24+
SchedulerCertCn string = "scheduler-extender"
2425
)
2526

2627
var AllowedProvisioners = []string{

hooks/go/go.mod

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.24.6
44

55
require (
66
github.com/deckhouse/csi-nfs/api v0.0.0-20250314071217-91b1f5b52e17
7-
github.com/deckhouse/module-sdk v0.2.0
7+
github.com/deckhouse/module-sdk v0.2.2
88
github.com/deckhouse/sds-common-lib v0.0.0-20250331104837-4ed70c9f1a83
99
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0
1010
k8s.io/api v0.32.3
@@ -21,7 +21,7 @@ require (
2121
github.com/cloudflare/cfssl v1.6.5 // indirect
2222
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
2323
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
24-
github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250227202034-eda49647c2d9 // indirect
24+
github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250424095005-9ab587d01d7a // indirect
2525
github.com/docker/cli v28.0.1+incompatible // indirect
2626
github.com/docker/distribution v2.8.3+incompatible // indirect
2727
github.com/docker/docker-credential-helpers v0.8.2 // indirect
@@ -55,6 +55,8 @@ require (
5555
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5656
github.com/modern-go/reflect2 v1.0.2 // indirect
5757
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
58+
github.com/onsi/ginkgo/v2 v2.23.3 // indirect
59+
github.com/onsi/gomega v1.37.0 // indirect
5860
github.com/opencontainers/go-digest v1.0.0 // indirect
5961
github.com/opencontainers/image-spec v1.1.0 // indirect
6062
github.com/pelletier/go-toml v1.9.3 // indirect
@@ -76,14 +78,14 @@ require (
7678
github.com/x448/float16 v0.8.4 // indirect
7779
github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 // indirect
7880
github.com/zmap/zlint/v3 v3.5.0 // indirect
79-
golang.org/x/crypto v0.36.0 // indirect
80-
golang.org/x/net v0.38.0 // indirect
81+
golang.org/x/crypto v0.38.0 // indirect
82+
golang.org/x/net v0.40.0 // indirect
8183
golang.org/x/oauth2 v0.27.0 // indirect
82-
golang.org/x/sync v0.12.0 // indirect
83-
golang.org/x/sys v0.31.0 // indirect
84-
golang.org/x/term v0.30.0 // indirect
85-
golang.org/x/text v0.23.0 // indirect
86-
golang.org/x/time v0.10.0 // indirect
84+
golang.org/x/sync v0.14.0 // indirect
85+
golang.org/x/sys v0.33.0 // indirect
86+
golang.org/x/term v0.32.0 // indirect
87+
golang.org/x/text v0.25.0 // indirect
88+
golang.org/x/time v0.11.0 // indirect
8789
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
8890
google.golang.org/protobuf v1.36.5 // indirect
8991
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect

0 commit comments

Comments
 (0)