@@ -2,12 +2,15 @@ package k8sutil
22
33import (
44 "bytes"
5+ "fmt"
56 "text/template"
67
78 marklogicv1 "github.com/marklogic/marklogic-operator-kubernetes/api/v1"
89)
910
10- type HAProxyTemplateData struct {
11+ type HAProxyTemplate struct {
12+ FrontendName string
13+ BackendName string
1114 TargetPortNumber int
1215 PortNumber int
1316 PortName string
@@ -21,13 +24,91 @@ type HAProxyTemplateData struct {
2124 sslEnabledServer bool
2225}
2326
27+ type HAProxyConfig struct {
28+ FrontEndConfigMap map [string ]FrontEndConfig
29+ BackendConfigMap map [string ][]BackendConfig
30+ }
31+
32+ type FrontEndConfig struct {
33+ FrontendName string
34+ PathBasedRouting bool
35+ Port int
36+ TargetPort int
37+ Path string
38+ BackendName string
39+ }
40+
41+ type BackendConfig struct {
42+ BackendName string
43+ GroupName string
44+ Port int
45+ TargetPort int
46+ Path string
47+ Replicas int
48+ }
49+
50+ func generateHAProxyConfig (cr * marklogicv1.MarklogicCluster ) * HAProxyConfig {
51+ config := & HAProxyConfig {}
52+ frontendMap := make (map [string ]FrontEndConfig )
53+ backendMap := make (map [string ][]BackendConfig )
54+ defaultAppServer := cr .Spec .HAProxy .AppServers
55+ groups := cr .Spec .MarkLogicGroups
56+ for _ , group := range groups {
57+ if group .HAProxy != nil && ! group .HAProxy .Enabled {
58+ continue
59+ }
60+ appServers := group .HAProxy .AppServers
61+ if len (appServers ) == 0 {
62+ appServers = defaultAppServer
63+ }
64+ for _ , appServer := range appServers {
65+ targetPort := int (appServer .TargetPort )
66+ if appServer .TargetPort == 0 {
67+ targetPort = int (appServer .Port )
68+ }
69+ var key string
70+ if int (appServer .Port ) == targetPort {
71+ key = fmt .Sprintf ("%d" , appServer .Port )
72+ } else {
73+ key = fmt .Sprintf ("%d-%d" , appServer .Port , targetPort )
74+ }
75+
76+ frontendName := "marklogic-" + key + "-frontend"
77+ backendName := "marklogic-" + key + "-backend"
78+
79+ if _ , exists := frontendMap [key ]; ! exists {
80+ frontend := FrontEndConfig {
81+ FrontendName : frontendName ,
82+ PathBasedRouting : * cr .Spec .HAProxy .PathBasedRouting ,
83+ Port : int (appServer .Port ),
84+ TargetPort : targetPort ,
85+ BackendName : backendName ,
86+ }
87+ frontendMap [key ] = frontend
88+ }
89+ backend := BackendConfig {
90+ BackendName : backendName ,
91+ GroupName : group .Name ,
92+ Port : int (appServer .Port ),
93+ TargetPort : targetPort ,
94+ Path : appServer .Path ,
95+ Replicas : int (* group .Replicas ),
96+ }
97+ backendMap [key ] = append (backendMap [key ], backend )
98+ }
99+ }
100+ config .FrontEndConfigMap = frontendMap
101+ config .BackendConfigMap = backendMap
102+ return config
103+ }
104+
24105// generates frontend config for HAProxy depending on pathBasedRouting flag
25106// if pathBasedRouting is disabled, it will generate a frontend for each appServer
26107// otherwise, it will generate a single frontend with path based routing
27- func generateFrontendConfig (cr * marklogicv1.MarklogicCluster ) string {
28-
108+ func generateFrontendConfig (cr * marklogicv1.MarklogicCluster , config * HAProxyConfig ) string {
109+ frontEndConfigs := config . FrontEndConfigMap
29110 var frontEndDef string
30- var data * HAProxyTemplateData
111+ var data * HAProxyTemplate
31112 var result string
32113 pathBasedRouting := cr .Spec .HAProxy .PathBasedRouting
33114 appServers := cr .Spec .HAProxy .AppServers
@@ -40,13 +121,13 @@ frontend marklogic-pathbased-frontend
40121 bind :{{ .PortNumber}} {{ .SslCert }}
41122 http-request set-header Host marklogic:{{ .PortNumber}}
42123 http-request set-header REFERER http://marklogic:{{ .PortNumber}}`
43- data = & HAProxyTemplateData {
124+ data = & HAProxyTemplate {
44125 PortNumber : int (cr .Spec .HAProxy .FrontendPort ),
45126 SslCert : getSSLConfig (cr .Spec .HAProxy .Tls ),
46127 }
47128 result = parseTemplateToString (frontEndDef , data )
48129 for _ , appServer := range appServers {
49- data = & HAProxyTemplateData {
130+ data = & HAProxyTemplate {
50131 PortNumber : int (appServer .Port ),
51132 TargetPortNumber : int (appServer .TargetPort ),
52133 Path : appServer .Path ,
@@ -56,16 +137,18 @@ frontend marklogic-pathbased-frontend
56137 } else {
57138 // front end configuration for non-path based routing
58139 frontEndDef = `
59- frontend marklogic- {{ .PortNumber }}
140+ frontend {{ .FrontendName }}
60141 mode http
61142 bind :{{ .PortNumber }} {{ .SslCert }}
62143 log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
63- default_backend marklogic-{{ .PortNumber}}-backend`
64-
65- for _ , appServer := range appServers {
66- data = & HAProxyTemplateData {
67- PortNumber : int (appServer .Port ),
68- SslCert : getSSLConfig (cr .Spec .HAProxy .Tls ),
144+ default_backend {{ .BackendName }}`
145+ for _ , frontend := range frontEndConfigs {
146+ data = & HAProxyTemplate {
147+ FrontendName : frontend .FrontendName ,
148+ BackendName : frontend .BackendName ,
149+ PortNumber : int (frontend .Port ),
150+ TargetPortNumber : int (frontend .TargetPort ),
151+ SslCert : getSSLConfig (cr .Spec .HAProxy .Tls ),
69152 }
70153 result += parseTemplateToString (frontEndDef , data ) + "\n "
71154 }
@@ -74,13 +157,13 @@ frontend marklogic-{{ .PortNumber}}
74157}
75158
76159// generates backend config for HAProxy depending on pathBasedRouting flag and appServers
77- func generateBackendConfig (cr * marklogicv1.MarklogicCluster ) string {
78-
160+ func generateBackendConfig (cr * marklogicv1.MarklogicCluster , config * HAProxyConfig ) string {
161+ backendConfigs := config . BackendConfigMap
79162 pathBasedRouting := cr .Spec .HAProxy .PathBasedRouting
80163 var result string
81164
82165 backendTemplate := `
83- backend marklogic- {{ .PortNumber}}-backend
166+ backend {{ .BackendName }}
84167 mode http
85168 balance leastconn
86169 option forwardfor
@@ -96,27 +179,21 @@ backend marklogic-{{ .PortNumber}}-backend
96179 backendTemplate += `
97180 http-request replace-path {{.Path}}(/)?(.*) /\2`
98181 }
99- groups := cr .Spec .MarkLogicGroups
100-
101- appServers := cr .Spec .HAProxy .AppServers
102-
103- for _ , appServer := range appServers {
104- data := & HAProxyTemplateData {
105- PortNumber : int (appServer .Port ),
106- Path : appServer .Path ,
182+ for _ , backends := range backendConfigs {
183+ data := & HAProxyTemplate {
184+ BackendName : backends [0 ].BackendName ,
185+ PortNumber : backends [0 ].Port ,
186+ Path : backends [0 ].Path ,
107187 }
108188 result += parseTemplateToString (backendTemplate , data )
109- for _ , group := range groups {
110- name := group .Name
111- groupReplicas := int (* group .Replicas )
112- if group .HAProxy != nil && ! group .HAProxy .Enabled {
113- continue
114- }
189+ for _ , backend := range backends {
190+ name := backend .GroupName
191+ groupReplicas := backend .Replicas
115192 for i := 0 ; i < groupReplicas ; i ++ {
116- data := & HAProxyTemplateData {
117- PortNumber : int ( appServer .Port ) ,
193+ data := & HAProxyTemplate {
194+ PortNumber : backend .Port ,
118195 PodName : name ,
119- Path : appServer .Path ,
196+ Path : backend .Path ,
120197 Index : i ,
121198 ServiceName : name ,
122199 NSName : cr .ObjectMeta .Namespace ,
@@ -132,7 +209,7 @@ backend marklogic-{{ .PortNumber}}-backend
132209 return result
133210}
134211
135- func getBackendServerConfigs (data * HAProxyTemplateData ) string {
212+ func getBackendServerConfigs (data * HAProxyTemplate ) string {
136213 backend := `
137214 server {{.PodName}}-{{.PortNumber}}-{{.Index}} {{.PodName}}-{{.Index}}.{{.ServiceName}}.{{.NSName}}.svc.{{.ClusterName}}:{{.PortNumber}} resolvers dns init-addr none cookie {{.PodName}}-{{.PortNumber}}-{{.Index}}`
138215 if data .sslEnabledServer {
@@ -142,7 +219,7 @@ func getBackendServerConfigs(data *HAProxyTemplateData) string {
142219 return parseTemplateToString (backend , data )
143220}
144221
145- func getFrontendForPathbased (data * HAProxyTemplateData ) string {
222+ func getFrontendForPathbased (data * HAProxyTemplate ) string {
146223 frontend := `
147224 use_backend marklogic-{{.PortNumber}}-backend if { path {{.Path}} } || { path_beg {{.Path}}/ }`
148225 if data .PortNumber == 8000 || data .TargetPortNumber == 8000 {
@@ -158,7 +235,7 @@ func getFrontendForPathbased(data *HAProxyTemplateData) string {
158235 return parseTemplateToString (frontend , data )
159236}
160237
161- func getBackendForTCP (data * HAProxyTemplateData ) string {
238+ func getBackendForTCP (data * HAProxyTemplate ) string {
162239 backend := `
163240server ml-{{.PodName}}-{{.PortNumber}}-{{.Index}} {{.PodName}}-{{.Index}}.{{.ServiceName}}.{{.NSName}}.svc.{{.ClusterName}}:{{.PortNumber}} check resolvers dns init-addr none`
164241 return parseTemplateToString (backend , data )
@@ -200,7 +277,7 @@ listen marklogic-TCP-{{.PortNumber}}
200277 bind :{{ .PortNumber }} {{ .SslCert }}
201278 mode tcp
202279 balance leastconn`
203- data := & HAProxyTemplateData {
280+ data := & HAProxyTemplate {
204281 PortNumber : int (tcpPort .Port ),
205282 SslCert : getSSLConfig (cr .Spec .HAProxy .Tls ),
206283 }
@@ -212,7 +289,7 @@ listen marklogic-TCP-{{.PortNumber}}
212289 continue
213290 }
214291 for i := 0 ; i < groupReplicas ; i ++ {
215- data := & HAProxyTemplateData {
292+ data := & HAProxyTemplate {
216293 PortNumber : int (tcpPort .Port ),
217294 PodName : name ,
218295 Index : i ,
@@ -248,4 +325,3 @@ func parseTemplateToString(templateStr string, data interface{}) string {
248325}
249326
250327type Servers []marklogicv1.AppServers
251-
0 commit comments