Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/reviewdog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-check
shellcheck_flags: -e SC2155
shellcheck_flags: -e SC2155 --external-sources
exclude: "./vendor/*"

misspell:
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,19 @@ kuttl-shfmt:
e2e-test: kuttl-shfmt
ROOT_REPO=$(ROOT_REPO) kubectl kuttl test --config e2e-tests/kuttl.yaml

manifests: kustomize generate ## Generate Kubernetes manifests (CRDs, RBAC, operator deployment)
.PHONY: generate-cr-yaml
generate-cr-yaml:
./cmd/example-gen/scripts/generate.sh ps

.PHONY: generate-restore-yaml
generate-restore-yaml:
./cmd/example-gen/scripts/generate.sh ps-restore

.PHONY: generate-backup-yaml
generate-backup-yaml:
./cmd/example-gen/scripts/generate.sh ps-backup

manifests: kustomize generate generate-cr-yaml generate-restore-yaml generate-backup-yaml ## Generate Kubernetes manifests (CRDs, RBAC, operator deployment)
$(KUSTOMIZE) build config/crd/ > $(DEPLOYDIR)/crd.yaml
echo "---" >> $(DEPLOYDIR)/crd.yaml

Expand Down
4 changes: 2 additions & 2 deletions api/v1/perconaservermysql_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ type MySQLSpec struct {

VaultSecretName string `json:"vaultSecretName,omitempty"`

VolumeSpec *VolumeSpec `json:"volumeSpec,omitempty"`

PodSpec `json:",inline"`
}

Expand Down Expand Up @@ -194,7 +196,6 @@ type PodSpec struct {
Size int32 `json:"size,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
VolumeSpec *VolumeSpec `json:"volumeSpec,omitempty"`

// Deprecated: not supported since v0.12.0. Use initContainer instead
InitImage string `json:"initImage,omitempty"`
Expand Down Expand Up @@ -409,7 +410,6 @@ type BackupStorageS3Spec struct {
CredentialsSecret string `json:"credentialsSecret"`
Region string `json:"region,omitempty"`
EndpointURL string `json:"endpointUrl,omitempty"`
StorageClass string `json:"storageClass,omitempty"`
}

// BucketAndPrefix returns bucket name and backup prefix from Bucket concatenated with Prefix.
Expand Down
10 changes: 5 additions & 5 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions build/run-backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
"endpointUrl": "$(json_escape "${AWS_ENDPOINT}")",
"accessKey": "$(json_escape "${AWS_ACCESS_KEY_ID}")",
"secretKey": "$(json_escape "${AWS_SECRET_ACCESS_KEY}")",
"region": "$(json_escape "${AWS_DEFAULT_REGION}")",
"storageClass": "$(json_escape "${S3_STORAGE_CLASS}")"
"region": "$(json_escape "${AWS_DEFAULT_REGION}")"
}
}
EOF
Expand Down Expand Up @@ -63,7 +62,7 @@

# json_escape takes a string and replaces `\` to `\\` and `"` to `\"` to make it safe to insert provided argument into a json string
json_escape() {
escaped_backslash=${1//'\'/'\\'}

Check notice on line 65 in build/run-backup.sh

View workflow job for this annotation

GitHub Actions / shellcheck

[shellcheck] build/run-backup.sh#L65 <ShellCheck.SC1003>

Want to escape a single quote? echo 'This is how it'\''s done'.
Raw output
./build/run-backup.sh:65:26: info: Want to escape a single quote? echo 'This is how it'\''s done'. (ShellCheck.SC1003)

Check notice on line 65 in build/run-backup.sh

View workflow job for this annotation

GitHub Actions / shellcheck

[shellcheck] build/run-backup.sh#L65 <ShellCheck.SC1003>

Want to escape a single quote? echo 'This is how it'\''s done'.
Raw output
./build/run-backup.sh:65:31: info: Want to escape a single quote? echo 'This is how it'\''s done'. (ShellCheck.SC1003)
escaped_quotes=${escaped_backslash//'"'/'\"'}
echo -n "$escaped_quotes"
}
Expand Down
147 changes: 147 additions & 0 deletions cmd/example-gen/internal/fill/bytype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package fill

import (
"fmt"
"reflect"
)

// ByType recursively fills zero or nil fields in the given pointer value `v`
// using provided preset values matched by type. It modifies `v` in place.
func ByType(v any, presets ...any) error {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
return fmt.Errorf("nil value")
}
if rv.Kind() != reflect.Pointer || rv.IsNil() {
return fmt.Errorf("value must be a non-nil pointer")
}
fillValue(rv, buildRules(presets...))
return nil
}

type rules map[reflect.Type]reflect.Value

func buildRules(presets ...any) rules {
r := make(rules, len(presets))
for _, p := range presets {
if p == nil {
continue
}
v := reflect.ValueOf(p)
r[v.Type()] = v
}
return r
}

func fillValue(v reflect.Value, r rules) {
for v.Kind() == reflect.Pointer {
if v.IsNil() {
if ok, def := lookup(v.Type(), r); ok {
v.Set(def)
} else {
return
}
}
v = v.Elem()
}

switch v.Kind() {
case reflect.Struct:
t := v.Type()
for i := 0; i < v.NumField(); i++ {
sf := t.Field(i)
if sf.PkgPath != "" { // not exported
continue
}
fv := v.Field(i)

setIfZero(fv, r)

switch fv.Kind() {
case reflect.Pointer, reflect.Struct, reflect.Slice, reflect.Map, reflect.Interface:
fillValue(fv, r)
}
}

case reflect.Slice:
for i := 0; i < v.Len(); i++ {
fillValue(v.Index(i), r)
}

case reflect.Map:
iter := v.MapRange()
for iter.Next() {
k, val := iter.Key(), iter.Value()

elem := reflect.New(v.Type().Elem()).Elem()
elem.Set(val)

setIfZero(elem, r)

switch elem.Kind() {
case reflect.Pointer, reflect.Struct, reflect.Slice, reflect.Map, reflect.Interface:
fillValue(elem, r)
}
v.SetMapIndex(k, elem)
}

case reflect.Interface:
if !v.IsNil() {
cur := v.Elem()
tmp := reflect.New(cur.Type()).Elem()
tmp.Set(cur)
fillValue(tmp, r)
v.Set(tmp)
}
}
}

func setIfZero(fv reflect.Value, r rules) {
need := false
switch fv.Kind() {
case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Interface:
need = fv.IsNil()
default:
need = fv.IsZero()
}
if !need {
return
}
if ok, def := lookup(fv.Type(), r); ok {
fv.Set(def)
return
}
}

func lookup(t reflect.Type, r rules) (bool, reflect.Value) {
if dv, ok := r[t]; ok {
if dv.Type().AssignableTo(t) {
return true, dv
}
if dv.Type().ConvertibleTo(t) {
return true, dv.Convert(t)
}
}

if t.Kind() == reflect.Pointer {
elem := t.Elem()
if dv, ok := r[elem]; ok {
ptr := reflect.New(elem)
if dv.Type().AssignableTo(elem) {
ptr.Elem().Set(dv)
return true, ptr
}
if dv.Type().ConvertibleTo(elem) {
ptr.Elem().Set(dv.Convert(elem))
return true, ptr
}
}
}

if t.Kind() != reflect.Interface {
if dv, ok := r[reflect.PointerTo(t)]; ok && dv.Kind() == reflect.Pointer && !dv.IsNil() && dv.Type().Elem().AssignableTo(t) {
return true, dv.Elem()
}
}
return false, reflect.Value{}
}
Loading
Loading