@@ -15,11 +15,14 @@ import (
1515 "github.com/ClickHouse/clickhouse-operator/internal/controller"
1616 "github.com/ClickHouse/clickhouse-operator/internal/controller/keeper"
1717 "github.com/ClickHouse/clickhouse-operator/internal/controllerutil"
18+ "github.com/ClickHouse/clickhouse-operator/internal/upgrade"
1819)
1920
2021var (
2122 //go:embed templates/base.yaml.tmpl
2223 baseConfigTemplateStr string
24+ //go:embed templates/named_collections.yaml.tmpl
25+ namedCollectionsTemplateStr string
2326 //go:embed templates/network.yaml.tmpl
2427 networkConfigTemplateStr string
2528 //go:embed templates/log_tables.yaml.tmpl
@@ -33,11 +36,41 @@ var (
3336)
3437
3538func init () {
39+ templateFuncs := template.FuncMap {
40+ "yaml" : func (v any ) (string , error ) {
41+ data , err := yaml .Marshal (v )
42+ return string (data ), err
43+ },
44+ "indent" : func (countRaw any , strRaw any ) (string , error ) {
45+ count , ok := countRaw .(int )
46+ if ! ok {
47+ return "" , fmt .Errorf ("indent: expected int for indentation value, got %T" , countRaw )
48+ }
49+
50+ str , ok := strRaw .(string )
51+ if ! ok {
52+ return "" , fmt .Errorf ("indent: expected string for content value, got %T" , strRaw )
53+ }
54+
55+ builder := strings.Builder {}
56+ indentation := strings .Repeat (" " , count )
57+
58+ for line := range strings .SplitSeq (str , "\n " ) {
59+ if _ , err := fmt .Fprintf (& builder , "%s%s\n " , indentation , line ); err != nil {
60+ return "" , fmt .Errorf ("failed to write indented line: %w" , err )
61+ }
62+ }
63+
64+ return builder .String (), nil
65+ },
66+ }
67+
3668 for _ , templateSpec := range []struct {
3769 Path string
3870 Filename string
3971 Raw string
4072 Generator configGeneratorFunc
73+ Enabled func (r * clickhouseReconciler ) bool
4174 }{{
4275 Path : ConfigPath ,
4376 Filename : ConfigFileName ,
@@ -53,6 +86,14 @@ func init() {
5386 Filename : "00-logs-tables.yaml" ,
5487 Raw : logTablesConfigTemplateStr ,
5588 Generator : logTablesConfigGenerator ,
89+ }, {
90+ Path : path .Join (ConfigPath , ConfigDPath ),
91+ Filename : "00-named-collections.yaml" ,
92+ Raw : namedCollectionsTemplateStr ,
93+ Generator : namedCollectionsConfigGenerator ,
94+ Enabled : func (r * clickhouseReconciler ) bool {
95+ return upgrade .VersionAtLeast (r .Cluster .Status .Version , minVersionNamedCollections )
96+ },
5697 }, {
5798 Path : ConfigPath ,
5899 Filename : UsersFileName ,
@@ -64,68 +105,35 @@ func init() {
64105 Raw : clientConfigTemplateStr ,
65106 Generator : clientConfigGenerator ,
66107 }} {
67- tmpl := template .New ("" ).Funcs (template.FuncMap {
68- "yaml" : func (v any ) (string , error ) {
69- data , err := yaml .Marshal (v )
70- return string (data ), err
71- },
72- "indent" : func (countRaw any , strRaw any ) (string , error ) {
73- count , ok := countRaw .(int )
74- if ! ok {
75- return "" , fmt .Errorf ("indent: expected int for indentation value, got %T" , countRaw )
76- }
77-
78- str , ok := strRaw .(string )
79- if ! ok {
80- return "" , fmt .Errorf ("indent: expected string for content value, got %T" , strRaw )
81- }
82-
83- builder := strings.Builder {}
84- indentation := strings .Repeat (" " , count )
85-
86- for line := range strings .SplitSeq (str , "\n " ) {
87- if _ , err := fmt .Fprintf (& builder , "%s%s\n " , indentation , line ); err != nil {
88- return "" , fmt .Errorf ("failed to write indented line: %w" , err )
89- }
90- }
91-
92- return builder .String (), nil
93- },
94- })
95- if _ , err := tmpl .Parse (templateSpec .Raw ); err != nil {
96- panic (fmt .Sprintf ("failed to parse template %s: %v" , templateSpec .Filename , err ))
97- }
108+ tmpl := template .Must (template .New ("" ).Funcs (templateFuncs ).Parse (templateSpec .Raw ))
98109
99110 generators = append (generators , & templateConfigGenerator {
100111 filename : templateSpec .Filename ,
101112 path : templateSpec .Path ,
102113 template : tmpl ,
103114 generator : templateSpec .Generator ,
115+ enabled : templateSpec .Enabled ,
104116 })
105117 }
106118
107119 generators = append (generators ,
108120 & extraConfigGenerator {
109121 Name : ExtraConfigFileName ,
110122 ConfigSubPath : ConfigDPath ,
111- Getter : func (r * clickhouseReconciler ) []byte {
112- return r .Cluster .Spec .Settings .ExtraConfig .Raw
113- },
123+ Getter : func (r * clickhouseReconciler ) []byte { return r .Cluster .Spec .Settings .ExtraConfig .Raw },
114124 },
115125 & extraConfigGenerator {
116126 Name : ExtraUsersConfigFileName ,
117127 ConfigSubPath : UsersDPath ,
118- Getter : func (r * clickhouseReconciler ) []byte {
119- return r .Cluster .Spec .Settings .ExtraUsersConfig .Raw
120- },
128+ Getter : func (r * clickhouseReconciler ) []byte { return r .Cluster .Spec .Settings .ExtraUsersConfig .Raw },
121129 })
122130}
123131
124132type configGenerator interface {
125133 Filename () string
126134 Path () string
127135 ConfigKey () string
128- Exists (r * clickhouseReconciler ) bool
136+ Enabled (r * clickhouseReconciler ) bool
129137 Generate (r * clickhouseReconciler , id v1.ClickHouseReplicaID ) (string , error )
130138}
131139
@@ -134,6 +142,7 @@ type templateConfigGenerator struct {
134142 path string
135143 template * template.Template
136144 generator configGeneratorFunc
145+ enabled func (r * clickhouseReconciler ) bool
137146}
138147
139148func (g * templateConfigGenerator ) Filename () string {
@@ -148,8 +157,8 @@ func (g *templateConfigGenerator) ConfigKey() string {
148157 return controllerutil .PathToName (path .Join (g .path , g .filename ))
149158}
150159
151- func (g * templateConfigGenerator ) Exists ( * clickhouseReconciler ) bool {
152- return true
160+ func (g * templateConfigGenerator ) Enabled ( r * clickhouseReconciler ) bool {
161+ return g . enabled == nil || g . enabled ( r )
153162}
154163
155164func (g * templateConfigGenerator ) Generate (r * clickhouseReconciler , id v1.ClickHouseReplicaID ) (string , error ) {
@@ -389,6 +398,25 @@ func clientConfigGenerator(tmpl *template.Template, r *clickhouseReconciler, _ v
389398 return builder .String (), nil
390399}
391400
401+ type namedCollectionsConfigParams struct {
402+ NamedCollectionsKeyEnv string
403+ NamedCollectionsPath string
404+ }
405+
406+ func namedCollectionsConfigGenerator (tmpl * template.Template , _ * clickhouseReconciler , _ v1.ClickHouseReplicaID ) (string , error ) {
407+ params := namedCollectionsConfigParams {
408+ NamedCollectionsKeyEnv : EnvNamedCollectionsKey ,
409+ NamedCollectionsPath : KeeperPathNamedCollections ,
410+ }
411+
412+ builder := strings.Builder {}
413+ if err := tmpl .Execute (& builder , params ); err != nil {
414+ return "" , fmt .Errorf ("template named collections config: %w" , err )
415+ }
416+
417+ return builder .String (), nil
418+ }
419+
392420type extraConfigGenerator struct {
393421 Name string
394422 ConfigSubPath string
@@ -407,12 +435,12 @@ func (g *extraConfigGenerator) ConfigKey() string {
407435 return g .Name
408436}
409437
410- func (g * extraConfigGenerator ) Exists (r * clickhouseReconciler ) bool {
438+ func (g * extraConfigGenerator ) Enabled (r * clickhouseReconciler ) bool {
411439 return len (g .Getter (r )) > 0
412440}
413441
414442func (g * extraConfigGenerator ) Generate (r * clickhouseReconciler , _ v1.ClickHouseReplicaID ) (string , error ) {
415- if ! g .Exists (r ) {
443+ if ! g .Enabled (r ) {
416444 return "" , errors .New ("extra config generator called, but no extra config provided" )
417445 }
418446
0 commit comments