Skip to content

Commit d8d4809

Browse files
authored
YDBOPS-9679 dynconfig CMS ReplaceConfig (#214)
1 parent 56e6f09 commit d8d4809

File tree

16 files changed

+858
-75
lines changed

16 files changed

+858
-75
lines changed

.gitignore

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,15 @@
55
*.dylib
66
*.test
77
*.out
8-
.idea/**/workspace.xml
9-
.idea/**/tasks.xml
10-
.idea/**/usage.statistics.xml
11-
.idea/**/dictionaries
12-
.idea/**/shelf
13-
.idea/**/contentModel.xml
14-
.idea/**/dataSources/
15-
.idea/**/dataSources.ids
16-
.idea/**/dataSources.local.xml
17-
.idea/**/sqlDataSources.xml
18-
.idea/**/dynamic.xml
19-
.idea/**/uiDesigner.xml
20-
.idea/**/dbnavigator.xml
21-
.idea/**/gradle.xml
22-
.idea/**/libraries
23-
cmake-build-*/
24-
.idea/**/mongoSettings.xml
258
*.iws
269
out/
10+
.idea/*
2711
.idea_modules/
2812
atlassian-ide-plugin.xml
29-
.idea/replstate.xml
3013
com_crashlytics_export_strings.xml
3114
crashlytics.properties
3215
crashlytics-build.properties
3316
fabric.properties
34-
.idea/httpRequests
35-
.idea/caches/build_file_checksums.ser
3617

3718
bin/
3819
config/

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ kind-load:
7777
docker tag cr.yandex/yc/ydb-operator:latest kind/ydb-operator:current
7878
kind load docker-image kind/ydb-operator:current --name kind-ydb-operator
7979

80+
opts ?= ''
81+
8082
.PHONY: unit-test
8183
unit-test: manifests generate fmt vet envtest ## Run unit tests
82-
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use --arch=amd64 $(ENVTEST_K8S_VERSION) -p path)" go test -v -timeout 900s -p 1 ./internal/... -ginkgo.v -coverprofile cover.out
84+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use --arch=amd64 $(ENVTEST_K8S_VERSION) -p path)" go test -v -timeout 900s -p 1 ./internal/... -ginkgo.v -coverprofile cover.out $(opts)
8385

8486
.PHONY: e2e-test
8587
e2e-test: manifests generate fmt vet docker-build kind-init kind-load ## Run e2e tests
86-
go test -v -timeout 3600s -p 1 ./e2e/... -ginkgo.v
88+
go test -v -timeout 3600s -p 1 ./e2e/... -ginkgo.v $(opts)
8789

8890
.PHONY: test
8991
test: unit-test e2e-test ## Run all tests

api/v1alpha1/configuration.go

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package v1alpha1
22

33
import (
44
"bytes"
5+
"errors"
56
"fmt"
67
"strconv"
78

@@ -60,19 +61,22 @@ func BuildConfiguration(cr *Storage, crDB *Database) ([]byte, error) {
6061
rawYamlConfiguration = cr.Spec.Configuration
6162
}
6263

63-
dynconfig, err := ParseDynconfig(rawYamlConfiguration)
64-
if err == nil {
65-
if dynconfig.Config["hosts"] == nil {
64+
success, dynConfig, err := ParseDynConfig(rawYamlConfiguration)
65+
if success {
66+
if err != nil {
67+
return nil, fmt.Errorf("failed to parse dynconfig, error: %w", err)
68+
}
69+
if dynConfig.Config["hosts"] == nil {
6670
hosts := generateHosts(cr)
67-
dynconfig.Config["hosts"] = hosts
71+
dynConfig.Config["hosts"] = hosts
6872
}
6973

70-
return yaml.Marshal(dynconfig)
74+
return yaml.Marshal(dynConfig)
7175
}
7276

7377
err = yaml.Unmarshal([]byte(rawYamlConfiguration), &config)
7478
if err != nil {
75-
return nil, err
79+
return nil, fmt.Errorf("failed to serialize YAML config, error: %w", err)
7680
}
7781

7882
if config["hosts"] == nil {
@@ -84,28 +88,62 @@ func BuildConfiguration(cr *Storage, crDB *Database) ([]byte, error) {
8488
}
8589

8690
func ParseConfiguration(rawYamlConfiguration string) (schema.Configuration, error) {
87-
configuration := schema.Configuration{}
88-
89-
dynconfig, err := ParseDynconfig(rawYamlConfiguration)
90-
if err == nil {
91-
config, err := yaml.Marshal(dynconfig.Config)
92-
if err != nil {
93-
return configuration, err
94-
}
95-
rawYamlConfiguration = string(config)
96-
}
97-
9891
dec := yaml.NewDecoder(bytes.NewReader([]byte(rawYamlConfiguration)))
9992
dec.KnownFields(false)
100-
err = dec.Decode(&configuration)
10193

102-
return configuration, err
94+
var configuration schema.Configuration
95+
err := dec.Decode(&configuration)
96+
if err != nil {
97+
return schema.Configuration{}, nil
98+
}
99+
100+
return configuration, nil
103101
}
104102

105-
func ParseDynconfig(rawYamlConfiguration string) (schema.Dynconfig, error) {
106-
dynconfig := schema.Dynconfig{}
103+
func ParseDynConfig(rawYamlConfiguration string) (bool, schema.DynConfig, error) {
107104
dec := yaml.NewDecoder(bytes.NewReader([]byte(rawYamlConfiguration)))
108105
dec.KnownFields(true)
109-
err := dec.Decode(&dynconfig)
110-
return dynconfig, err
106+
107+
var dynConfig schema.DynConfig
108+
err := dec.Decode(&dynConfig)
109+
if err != nil {
110+
return false, schema.DynConfig{}, fmt.Errorf("error unmarshal yaml to dynconfig: %w", err)
111+
}
112+
113+
err = validateDynConfig(dynConfig)
114+
if err != nil {
115+
return true, dynConfig, fmt.Errorf("error validate dynconfig: %w", err)
116+
}
117+
118+
return true, dynConfig, err
119+
}
120+
121+
func validateDynConfig(dynConfig schema.DynConfig) error {
122+
if _, exist := dynConfig.Config["yaml_config_enabled"]; !exist {
123+
return errors.New("failed to find mandatory `yaml_config_enabled` field inside config")
124+
}
125+
126+
if _, exist := dynConfig.Config["static_erasure"]; !exist {
127+
return errors.New("failed to find mandatory `static_erasure` field inside config")
128+
}
129+
130+
if _, exist := dynConfig.Config["host_configs"]; !exist {
131+
return errors.New("failed to find mandatory `host_configs` field inside config")
132+
}
133+
134+
if _, exist := dynConfig.Config["blob_storage_config"]; !exist {
135+
return errors.New("failed to find mandatory `blob_storage_config` field inside config")
136+
}
137+
138+
return nil
139+
}
140+
141+
func GetConfigForCMS(dynConfig schema.DynConfig) ([]byte, error) {
142+
delete(dynConfig.Config, "static_erasure")
143+
delete(dynConfig.Config, "host_configs")
144+
delete(dynConfig.Config, "nameservice_config")
145+
delete(dynConfig.Config, "blob_storage_config")
146+
delete(dynConfig.Config, "hosts")
147+
148+
return yaml.Marshal(dynConfig)
111149
}

api/v1alpha1/storage_webhook.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/golang-jwt/jwt/v4"
99
"github.com/google/go-cmp/cmp"
1010
"github.com/google/go-cmp/cmp/cmpopts"
11+
"gopkg.in/yaml.v3"
1112
corev1 "k8s.io/api/core/v1"
1213
"k8s.io/apimachinery/pkg/runtime"
1314
"k8s.io/utils/strings/slices"
@@ -195,7 +196,23 @@ func isSignAlgorithmSupported(alg string) bool {
195196
func (r *Storage) ValidateCreate() error {
196197
storagelog.Info("validate create", "name", r.Name)
197198

198-
configuration, err := ParseConfiguration(r.Spec.Configuration)
199+
var rawYamlConfiguration string
200+
success, dynConfig, err := ParseDynConfig(r.Spec.Configuration)
201+
if success {
202+
if err != nil {
203+
return fmt.Errorf("failed to parse dynconfig, error: %w", err)
204+
}
205+
config, err := yaml.Marshal(dynConfig.Config)
206+
if err != nil {
207+
return fmt.Errorf("failed to serialize YAML config, error: %w", err)
208+
}
209+
rawYamlConfiguration = string(config)
210+
} else {
211+
rawYamlConfiguration = r.Spec.Configuration
212+
}
213+
214+
var configuration schema.Configuration
215+
configuration, err = ParseConfiguration(rawYamlConfiguration)
199216
if err != nil {
200217
return fmt.Errorf("failed to parse configuration, error: %w", err)
201218
}
@@ -293,7 +310,23 @@ func hasUpdatesBesidesFrozen(oldStorage, newStorage *Storage) (bool, string) {
293310
func (r *Storage) ValidateUpdate(old runtime.Object) error {
294311
storagelog.Info("validate update", "name", r.Name)
295312

296-
configuration, err := ParseConfiguration(r.Spec.Configuration)
313+
var rawYamlConfiguration string
314+
success, dynConfig, err := ParseDynConfig(r.Spec.Configuration)
315+
if success {
316+
if err != nil {
317+
return fmt.Errorf("failed to parse dynconfig, error: %w", err)
318+
}
319+
config, err := yaml.Marshal(dynConfig.Config)
320+
if err != nil {
321+
return fmt.Errorf("failed to serialize YAML config, error: %w", err)
322+
}
323+
rawYamlConfiguration = string(config)
324+
} else {
325+
rawYamlConfiguration = r.Spec.Configuration
326+
}
327+
328+
var configuration schema.Configuration
329+
configuration, err = ParseConfiguration(rawYamlConfiguration)
297330
if err != nil {
298331
return fmt.Errorf("failed to parse configuration, error: %w", err)
299332
}

deploy/ydb-operator/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 0.5.25
18+
version: 0.5.26
1919

2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to
2222
# follow Semantic Versioning. They should reflect the version the application is using.
2323
# It is recommended to use it with quotes.
24-
appVersion: "0.5.25"
24+
appVersion: "0.5.26"
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
metadata:
2+
kind: MainConfig
3+
cluster: ""
4+
version: 0
5+
allowed_labels: {}
6+
selector_config: []
7+
config:
8+
yaml_config_enabled: true
9+
static_erasure: block-4-2
10+
host_configs:
11+
- drive:
12+
- path: SectorMap:1:1
13+
type: SSD
14+
host_config_id: 1
15+
domains_config:
16+
domain:
17+
- name: Root
18+
storage_pool_types:
19+
- kind: ssd
20+
pool_config:
21+
box_id: 1
22+
erasure_species: block-4-2
23+
kind: ssd
24+
pdisk_filter:
25+
- property:
26+
- type: SSD
27+
vdisk_kind: Default
28+
state_storage:
29+
- ring:
30+
node: [1, 2, 3, 4, 5, 6, 7, 8]
31+
nto_select: 5
32+
ssid: 1
33+
table_service_config:
34+
sql_version: 1
35+
actor_system_config:
36+
executor:
37+
- name: System
38+
threads: 1
39+
type: BASIC
40+
- name: User
41+
threads: 1
42+
type: BASIC
43+
- name: Batch
44+
threads: 1
45+
type: BASIC
46+
- name: IO
47+
threads: 1
48+
time_per_mailbox_micro_secs: 100
49+
type: IO
50+
- name: IC
51+
spin_threshold: 10
52+
threads: 4
53+
time_per_mailbox_micro_secs: 100
54+
type: BASIC
55+
scheduler:
56+
progress_threshold: 10000
57+
resolution: 256
58+
spin_threshold: 0
59+
blob_storage_config:
60+
service_set:
61+
groups:
62+
- erasure_species: block-4-2
63+
rings:
64+
- fail_domains:
65+
- vdisk_locations:
66+
- node_id: storage-0
67+
pdisk_category: SSD
68+
path: SectorMap:1:1
69+
- vdisk_locations:
70+
- node_id: storage-1
71+
pdisk_category: SSD
72+
path: SectorMap:1:1
73+
- vdisk_locations:
74+
- node_id: storage-2
75+
pdisk_category: SSD
76+
path: SectorMap:1:1
77+
- vdisk_locations:
78+
- node_id: storage-3
79+
pdisk_category: SSD
80+
path: SectorMap:1:1
81+
- vdisk_locations:
82+
- node_id: storage-4
83+
pdisk_category: SSD
84+
path: SectorMap:1:1
85+
- vdisk_locations:
86+
- node_id: storage-5
87+
pdisk_category: SSD
88+
path: SectorMap:1:1
89+
- vdisk_locations:
90+
- node_id: storage-6
91+
pdisk_category: SSD
92+
path: SectorMap:1:1
93+
- vdisk_locations:
94+
- node_id: storage-7
95+
pdisk_category: SSD
96+
path: SectorMap:1:1
97+
channel_profile_config:
98+
profile:
99+
- channel:
100+
- erasure_species: block-4-2
101+
pdisk_category: 1
102+
storage_pool_kind: ssd
103+
- erasure_species: block-4-2
104+
pdisk_category: 1
105+
storage_pool_kind: ssd
106+
- erasure_species: block-4-2
107+
pdisk_category: 1
108+
storage_pool_kind: ssd
109+
profile_id: 0
110+
grpc_config:
111+
port: 2135

0 commit comments

Comments
 (0)