Skip to content

Commit 153b61a

Browse files
pooknullCopilot
andauthored
K8SPS-567: automatic yaml generation (#1136)
* K8SPS-567: automatic cr.yaml generation https://perconadev.atlassian.net/browse/K8SPS-567 * Update cmd/example-gen/defaults/preset.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix commenting * small fixes * reduce size of `manual.go` * generation of backups and restores * fix shellcheck * fix shellcheck * fix shellcheck * fix shellcheck * fix shellcheck * check * Revert "check" This reverts commit ed6a0a0. * fix enableVolumeExpansion --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 0411074 commit 153b61a

31 files changed

+2323
-2350
lines changed

.github/workflows/reviewdog.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
with:
5353
github_token: ${{ secrets.github_token }}
5454
reporter: github-pr-check
55-
shellcheck_flags: -e SC2155
55+
shellcheck_flags: -e SC2155 --external-sources
5656
exclude: "./vendor/*"
5757

5858
misspell:

Makefile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,19 @@ kuttl-shfmt:
106106
e2e-test: kuttl-shfmt
107107
ROOT_REPO=$(ROOT_REPO) kubectl kuttl test --config e2e-tests/kuttl.yaml
108108

109-
manifests: kustomize generate ## Generate Kubernetes manifests (CRDs, RBAC, operator deployment)
109+
.PHONY: generate-cr-yaml
110+
generate-cr-yaml:
111+
./cmd/example-gen/scripts/generate.sh ps
112+
113+
.PHONY: generate-restore-yaml
114+
generate-restore-yaml:
115+
./cmd/example-gen/scripts/generate.sh ps-restore
116+
117+
.PHONY: generate-backup-yaml
118+
generate-backup-yaml:
119+
./cmd/example-gen/scripts/generate.sh ps-backup
120+
121+
manifests: kustomize generate generate-cr-yaml generate-restore-yaml generate-backup-yaml ## Generate Kubernetes manifests (CRDs, RBAC, operator deployment)
110122
$(KUSTOMIZE) build config/crd/ > $(DEPLOYDIR)/crd.yaml
111123
echo "---" >> $(DEPLOYDIR)/crd.yaml
112124

api/v1/perconaservermysql_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ type MySQLSpec struct {
147147

148148
VaultSecretName string `json:"vaultSecretName,omitempty"`
149149

150+
VolumeSpec *VolumeSpec `json:"volumeSpec,omitempty"`
151+
150152
PodSpec `json:",inline"`
151153
}
152154

@@ -194,7 +196,6 @@ type PodSpec struct {
194196
Size int32 `json:"size,omitempty"`
195197
Annotations map[string]string `json:"annotations,omitempty"`
196198
Labels map[string]string `json:"labels,omitempty"`
197-
VolumeSpec *VolumeSpec `json:"volumeSpec,omitempty"`
198199

199200
// Deprecated: not supported since v0.12.0. Use initContainer instead
200201
InitImage string `json:"initImage,omitempty"`
@@ -409,7 +410,6 @@ type BackupStorageS3Spec struct {
409410
CredentialsSecret string `json:"credentialsSecret"`
410411
Region string `json:"region,omitempty"`
411412
EndpointURL string `json:"endpointUrl,omitempty"`
412-
StorageClass string `json:"storageClass,omitempty"`
413413
}
414414

415415
// BucketAndPrefix returns bucket name and backup prefix from Bucket concatenated with Prefix.

api/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/run-backup.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ request_data() {
1818
"endpointUrl": "$(json_escape "${AWS_ENDPOINT}")",
1919
"accessKey": "$(json_escape "${AWS_ACCESS_KEY_ID}")",
2020
"secretKey": "$(json_escape "${AWS_SECRET_ACCESS_KEY}")",
21-
"region": "$(json_escape "${AWS_DEFAULT_REGION}")",
22-
"storageClass": "$(json_escape "${S3_STORAGE_CLASS}")"
21+
"region": "$(json_escape "${AWS_DEFAULT_REGION}")"
2322
}
2423
}
2524
EOF
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package fill
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
// ByType recursively fills zero or nil fields in the given pointer value `v`
9+
// using provided preset values matched by type. It modifies `v` in place.
10+
func ByType(v any, presets ...any) error {
11+
rv := reflect.ValueOf(v)
12+
if !rv.IsValid() {
13+
return fmt.Errorf("nil value")
14+
}
15+
if rv.Kind() != reflect.Pointer || rv.IsNil() {
16+
return fmt.Errorf("value must be a non-nil pointer")
17+
}
18+
fillValue(rv, buildRules(presets...))
19+
return nil
20+
}
21+
22+
type rules map[reflect.Type]reflect.Value
23+
24+
func buildRules(presets ...any) rules {
25+
r := make(rules, len(presets))
26+
for _, p := range presets {
27+
if p == nil {
28+
continue
29+
}
30+
v := reflect.ValueOf(p)
31+
r[v.Type()] = v
32+
}
33+
return r
34+
}
35+
36+
func fillValue(v reflect.Value, r rules) {
37+
for v.Kind() == reflect.Pointer {
38+
if v.IsNil() {
39+
if ok, def := lookup(v.Type(), r); ok {
40+
v.Set(def)
41+
} else {
42+
return
43+
}
44+
}
45+
v = v.Elem()
46+
}
47+
48+
switch v.Kind() {
49+
case reflect.Struct:
50+
t := v.Type()
51+
for i := 0; i < v.NumField(); i++ {
52+
sf := t.Field(i)
53+
if sf.PkgPath != "" { // not exported
54+
continue
55+
}
56+
fv := v.Field(i)
57+
58+
setIfZero(fv, r)
59+
60+
switch fv.Kind() {
61+
case reflect.Pointer, reflect.Struct, reflect.Slice, reflect.Map, reflect.Interface:
62+
fillValue(fv, r)
63+
}
64+
}
65+
66+
case reflect.Slice:
67+
for i := 0; i < v.Len(); i++ {
68+
fillValue(v.Index(i), r)
69+
}
70+
71+
case reflect.Map:
72+
iter := v.MapRange()
73+
for iter.Next() {
74+
k, val := iter.Key(), iter.Value()
75+
76+
elem := reflect.New(v.Type().Elem()).Elem()
77+
elem.Set(val)
78+
79+
setIfZero(elem, r)
80+
81+
switch elem.Kind() {
82+
case reflect.Pointer, reflect.Struct, reflect.Slice, reflect.Map, reflect.Interface:
83+
fillValue(elem, r)
84+
}
85+
v.SetMapIndex(k, elem)
86+
}
87+
88+
case reflect.Interface:
89+
if !v.IsNil() {
90+
cur := v.Elem()
91+
tmp := reflect.New(cur.Type()).Elem()
92+
tmp.Set(cur)
93+
fillValue(tmp, r)
94+
v.Set(tmp)
95+
}
96+
}
97+
}
98+
99+
func setIfZero(fv reflect.Value, r rules) {
100+
need := false
101+
switch fv.Kind() {
102+
case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Interface:
103+
need = fv.IsNil()
104+
default:
105+
need = fv.IsZero()
106+
}
107+
if !need {
108+
return
109+
}
110+
if ok, def := lookup(fv.Type(), r); ok {
111+
fv.Set(def)
112+
return
113+
}
114+
}
115+
116+
func lookup(t reflect.Type, r rules) (bool, reflect.Value) {
117+
if dv, ok := r[t]; ok {
118+
if dv.Type().AssignableTo(t) {
119+
return true, dv
120+
}
121+
if dv.Type().ConvertibleTo(t) {
122+
return true, dv.Convert(t)
123+
}
124+
}
125+
126+
if t.Kind() == reflect.Pointer {
127+
elem := t.Elem()
128+
if dv, ok := r[elem]; ok {
129+
ptr := reflect.New(elem)
130+
if dv.Type().AssignableTo(elem) {
131+
ptr.Elem().Set(dv)
132+
return true, ptr
133+
}
134+
if dv.Type().ConvertibleTo(elem) {
135+
ptr.Elem().Set(dv.Convert(elem))
136+
return true, ptr
137+
}
138+
}
139+
}
140+
141+
if t.Kind() != reflect.Interface {
142+
if dv, ok := r[reflect.PointerTo(t)]; ok && dv.Kind() == reflect.Pointer && !dv.IsNil() && dv.Type().Elem().AssignableTo(t) {
143+
return true, dv.Elem()
144+
}
145+
}
146+
return false, reflect.Value{}
147+
}

0 commit comments

Comments
 (0)