Skip to content

Commit fee73d8

Browse files
committed
MEDIUM: write configuration and increase version only when there is a change
Also uses a client native option to add a _md5hash comment in the configuration
1 parent 7695a38 commit fee73d8

File tree

11 files changed

+41
-45
lines changed

11 files changed

+41
-45
lines changed
-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/bin/bash
2-
32
curl -X DELETE -H "Content-Type: application/yaml" --data-binary @configmap.yaml http://localhost:8081
43
curl -X DELETE -H "Content-Type: application/yaml" --data-binary @echo-app.yaml http://localhost:8081
54
curl -X DELETE -H "Content-Type: application/yaml" --data-binary @echo.endpointslices.yaml http://localhost:8081

pkg/haproxy/api/api.go

+41-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package api
22

33
import (
44
"context"
5+
//nolint:gosec
6+
"crypto/md5" // G501: Blocklisted import crypto/md5: weak cryptographic primitive
7+
"encoding/hex"
58
"encoding/json"
69

710
clientnative "github.com/haproxytech/client-native/v5"
@@ -133,11 +136,11 @@ type Backend struct { // use same names as in client native v6
133136
}
134137

135138
type clientNative struct {
136-
nativeAPI clientnative.HAProxyClient
137-
activeTransaction string
138-
activeTransactionHasChanges bool
139-
backends map[string]Backend
140-
previousBackends []byte
139+
nativeAPI clientnative.HAProxyClient
140+
activeTransaction string
141+
backends map[string]Backend
142+
previousBackends []byte
143+
configurationHashAtTransactionStart string
141144
}
142145

143146
func New(transactionDir, configFile, programPath, runtimeSocket string) (client HAProxyClient, err error) { //nolint:ireturn
@@ -155,6 +158,7 @@ func New(transactionDir, configFile, programPath, runtimeSocket string) (client
155158
cfgoptions.ConfigurationFile(configFile),
156159
cfgoptions.HAProxyBin(programPath),
157160
cfgoptions.UseModelsValidation,
161+
cfgoptions.UseMd5Hash,
158162
cfgoptions.TransactionsDir(transactionDir),
159163
)
160164
if err != nil {
@@ -193,16 +197,40 @@ func (c *clientNative) APIStartTransaction() error {
193197
}
194198
logger.WithField(utils.LogFieldTransactionID, transaction.ID)
195199
c.activeTransaction = transaction.ID
196-
c.activeTransactionHasChanges = false
200+
201+
hash, err := c.computeConfigurationHash(configuration)
202+
if err != nil {
203+
return err
204+
}
205+
c.configurationHashAtTransactionStart = hash
206+
197207
return nil
198208
}
199209

210+
func (c *clientNative) computeConfigurationHash(configuration configuration.Configuration) (string, error) {
211+
p, err := configuration.GetParser(c.activeTransaction)
212+
if err != nil {
213+
return "", err
214+
}
215+
// Note that p.String() does not include the hash!!!
216+
content := p.String()
217+
//nolint: gosec
218+
hash := md5.Sum([]byte(content))
219+
return hex.EncodeToString(hash[:]), err
220+
}
221+
200222
func (c *clientNative) APICommitTransaction() error {
201223
configuration, err := c.nativeAPI.Configuration()
202224
if err != nil {
203225
return err
204226
}
205-
if !c.activeTransactionHasChanges {
227+
228+
hash, err := c.computeConfigurationHash(configuration)
229+
if err != nil {
230+
return err
231+
}
232+
233+
if c.configurationHashAtTransactionStart == hash {
206234
if errDel := configuration.DeleteTransaction(c.activeTransaction); errDel != nil {
207235
return errDel
208236
}
@@ -235,7 +263,12 @@ func (c *clientNative) APIFinalCommitTransaction() error {
235263
c.backends[backendName] = backend
236264
}
237265

238-
if !c.activeTransactionHasChanges {
266+
hash, err := c.computeConfigurationHash(configuration)
267+
if err != nil {
268+
return err
269+
}
270+
271+
if c.configurationHashAtTransactionStart == hash {
239272
if errDel := configuration.DeleteTransaction(c.activeTransaction); errDel != nil {
240273
errs.Add(errDel)
241274
}
@@ -249,7 +282,6 @@ func (c *clientNative) APIFinalCommitTransaction() error {
249282
func (c *clientNative) APIDisposeTransaction() {
250283
logger.ResetFields()
251284
c.activeTransaction = ""
252-
c.activeTransactionHasChanges = false
253285
}
254286

255287
func (c *clientNative) SetAuxCfgFile(auxCfgFile string) {

pkg/haproxy/api/backend.go

-5
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ func (c *clientNative) BackendCreateOrUpdate(backend models.Backend) (diff map[s
5959

6060
diff = oldBackend.BackendBase.Diff(backend)
6161

62-
c.activeTransactionHasChanges = len(diff) > 0
63-
6462
oldBackend.BackendBase = backend
6563
oldBackend.Used = true
6664
c.backends[backend.Name] = oldBackend
@@ -83,7 +81,6 @@ func (c *clientNative) BackendCfgSnippetSet(backendName string, value []string)
8381
return fmt.Errorf("backend %s : %w", backendName, ErrNotFound)
8482
}
8583

86-
c.activeTransactionHasChanges = slices.Compare(backend.ConfigSnippets, value) != 0
8784
backend.ConfigSnippets = value
8885
c.backends[backendName] = backend
8986
return nil
@@ -117,7 +114,6 @@ func (c *clientNative) BackendRuleDeleteAll(backend string) {
117114
logger.Error(err)
118115
return
119116
}
120-
c.activeTransactionHasChanges = true
121117

122118
// Currently we are only using HTTPRequest rules on backend
123119
err = configuration.DeleteHTTPRequestRule(0, "backend", backend, c.activeTransaction, 0)
@@ -253,7 +249,6 @@ func (c *clientNative) BackendDeleteAllUnnecessary() ([]string, error) {
253249
return nil, err
254250
}
255251

256-
c.activeTransactionHasChanges = true
257252
var errs utils.Errors
258253
var backendDeleted []string //nolint:prealloc
259254
for _, backend := range c.backends {

pkg/haproxy/api/backend_switching_rule.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ func (c *clientNative) BackendSwitchingRuleCreate(frontend string, rule models.B
77
if err != nil {
88
return err
99
}
10-
c.activeTransactionHasChanges = true
1110
return configuration.CreateBackendSwitchingRule(frontend, &rule, c.activeTransaction, 0)
1211
}
1312

@@ -16,7 +15,6 @@ func (c *clientNative) BackendSwitchingRuleDeleteAll(frontend string) (err error
1615
if err != nil {
1716
return
1817
}
19-
c.activeTransactionHasChanges = true
2018
_, switchingRules, err := configuration.GetBackendSwitchingRules(frontend, c.activeTransaction)
2119
if err != nil {
2220
return

pkg/haproxy/api/capture.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ func (c *clientNative) CaptureCreate(frontend string, rule models.Capture) error
77
if err != nil {
88
return err
99
}
10-
c.activeTransactionHasChanges = true
1110
return configuration.CreateDeclareCapture(frontend, &rule, c.activeTransaction, 0)
1211
}
1312

@@ -16,7 +15,6 @@ func (c *clientNative) CaptureDeleteAll(frontend string) (err error) {
1615
if err != nil {
1716
return
1817
}
19-
c.activeTransactionHasChanges = true
2018
_, rules, err := configuration.GetDeclareCaptures(frontend, c.activeTransaction)
2119
if err != nil {
2220
return

pkg/haproxy/api/filters.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ func (c *clientNative) FilterCreate(parentType, parentName string, rule models.F
77
if err != nil {
88
return err
99
}
10-
c.activeTransactionHasChanges = true
1110
return configuration.CreateFilter(parentType, parentName, &rule, c.activeTransaction, 0)
1211
}
1312

@@ -16,7 +15,6 @@ func (c *clientNative) FilterDeleteAll(parentType, parentName string) (err error
1615
if err != nil {
1716
return
1817
}
19-
c.activeTransactionHasChanges = true
2018
_, rules, err := configuration.GetFilters(parentType, parentName, c.activeTransaction)
2119
if err != nil {
2220
return

pkg/haproxy/api/frontend.go

-15
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ func (c *clientNative) FrontendCfgSnippetSet(frontendName string, value []string
2222
} else {
2323
err = config.Set("frontend", frontendName, "config-snippet", types.StringSliceC{Value: value})
2424
}
25-
if err != nil {
26-
c.activeTransactionHasChanges = true
27-
}
2825
return err
2926
}
3027

@@ -33,7 +30,6 @@ func (c *clientNative) FrontendCreate(frontend models.Frontend) error {
3330
if err != nil {
3431
return err
3532
}
36-
c.activeTransactionHasChanges = true
3733
return configuration.CreateFrontend(&frontend, c.activeTransaction, 0)
3834
}
3935

@@ -42,7 +38,6 @@ func (c *clientNative) FrontendDelete(frontendName string) error {
4238
if err != nil {
4339
return err
4440
}
45-
c.activeTransactionHasChanges = true
4641
return configuration.DeleteFrontend(frontendName, c.activeTransaction, 0)
4742
}
4843

@@ -72,7 +67,6 @@ func (c *clientNative) FrontendEdit(frontend models.Frontend) error {
7267
if err != nil {
7368
return err
7469
}
75-
c.activeTransactionHasChanges = true
7670
return configuration.EditFrontend(frontend.Name, &frontend, c.activeTransaction, 0)
7771
}
7872

@@ -143,7 +137,6 @@ func (c *clientNative) FrontendBindCreate(frontend string, bind models.Bind) err
143137
if err != nil {
144138
return err
145139
}
146-
c.activeTransactionHasChanges = true
147140
return configuration.CreateBind("frontend", frontend, &bind, c.activeTransaction, 0)
148141
}
149142

@@ -152,7 +145,6 @@ func (c *clientNative) FrontendBindEdit(frontend string, bind models.Bind) error
152145
if err != nil {
153146
return err
154147
}
155-
c.activeTransactionHasChanges = true
156148
return configuration.EditBind(bind.Name, "frontend", frontend, &bind, c.activeTransaction, 0)
157149
}
158150

@@ -161,7 +153,6 @@ func (c *clientNative) FrontendBindDelete(frontend string, bind string) error {
161153
if err != nil {
162154
return err
163155
}
164-
c.activeTransactionHasChanges = true
165156
return configuration.DeleteBind(bind, "frontend", frontend, c.activeTransaction, 0)
166157
}
167158

@@ -170,7 +161,6 @@ func (c *clientNative) FrontendHTTPRequestRuleCreate(frontend string, rule model
170161
if err != nil {
171162
return err
172163
}
173-
c.activeTransactionHasChanges = true
174164
if ingressACL != "" {
175165
rule.Cond = "if"
176166
rule.CondTest = fmt.Sprintf("%s %s", ingressACL, rule.CondTest)
@@ -183,7 +173,6 @@ func (c *clientNative) FrontendHTTPResponseRuleCreate(frontend string, rule mode
183173
if err != nil {
184174
return err
185175
}
186-
c.activeTransactionHasChanges = true
187176
if ingressACL != "" {
188177
rule.Cond = "if"
189178
rule.CondTest = fmt.Sprintf("%s %s", ingressACL, rule.CondTest)
@@ -196,7 +185,6 @@ func (c *clientNative) FrontendTCPRequestRuleCreate(frontend string, rule models
196185
if err != nil {
197186
return err
198187
}
199-
c.activeTransactionHasChanges = true
200188
if ingressACL != "" {
201189
rule.Cond = "if"
202190
rule.CondTest = fmt.Sprintf("%s %s", ingressACL, rule.CondTest)
@@ -211,7 +199,6 @@ func (c *clientNative) FrontendRuleDeleteAll(frontend string) {
211199
logger.Error(err)
212200
return
213201
}
214-
c.activeTransactionHasChanges = true
215202

216203
for {
217204
err := configuration.DeleteHTTPRequestRule(0, "frontend", frontend, c.activeTransaction, 0)
@@ -239,7 +226,6 @@ func (c *clientNative) PeerEntryEdit(peerSection string, peerEntry models.PeerEn
239226
if err != nil {
240227
return err
241228
}
242-
c.activeTransactionHasChanges = true
243229
return configuration.EditPeerEntry(peerEntry.Name, peerSection, &peerEntry, c.activeTransaction, 0)
244230
}
245231

@@ -248,7 +234,6 @@ func (c *clientNative) PeerEntryCreateOrEdit(peerSection string, peerEntry model
248234
if err != nil {
249235
return err
250236
}
251-
c.activeTransactionHasChanges = true
252237
err = configuration.EditPeerEntry(peerEntry.Name, peerSection, &peerEntry, c.activeTransaction, 0)
253238
if err != nil {
254239
err = configuration.CreatePeerEntry(peerSection, &peerEntry, c.activeTransaction, 0)

pkg/haproxy/api/global.go

-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ func (c *clientNative) GlobalGetLogTargets() (lg models.LogTargets, err error) {
7878
if err != nil {
7979
return nil, err
8080
}
81-
c.activeTransactionHasChanges = true
8281
_, lg, err = configuration.GetLogTargets("global", parser.GlobalSectionName, c.activeTransaction)
8382
if err != nil {
8483
return lg, fmt.Errorf("unable to get HAProxy's global log targets: %w", err)
@@ -91,7 +90,6 @@ func (c *clientNative) GlobalPushLogTargets(logTargets models.LogTargets) error
9190
if err != nil {
9291
return err
9392
}
94-
c.activeTransactionHasChanges = true
9593
for {
9694
err = configuration.DeleteLogTarget(0, "global", parser.GlobalSectionName, c.activeTransaction, 0)
9795
if err != nil {

pkg/haproxy/api/log_target.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ func (c *clientNative) LogTargetCreate(parentType, parentName string, rule model
77
if err != nil {
88
return err
99
}
10-
c.activeTransactionHasChanges = true
1110
return configuration.CreateLogTarget(parentType, parentName, &rule, c.activeTransaction, 0)
1211
}
1312

@@ -16,7 +15,6 @@ func (c *clientNative) LogTargetDeleteAll(parentType, parentName string) (err er
1615
if err != nil {
1716
return
1817
}
19-
c.activeTransactionHasChanges = true
2018
_, rules, err := configuration.GetLogTargets(parentType, parentName, c.activeTransaction)
2119
if err != nil {
2220
return

pkg/haproxy/api/tcp_request_rule.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ func (c *clientNative) TCPRequestRuleCreate(parentType, parentName string, rule
77
if err != nil {
88
return err
99
}
10-
c.activeTransactionHasChanges = true
1110
return configuration.CreateTCPRequestRule(parentType, parentName, &rule, c.activeTransaction, 0)
1211
}
1312

@@ -16,7 +15,6 @@ func (c *clientNative) TCPRequestRuleDeleteAll(parentType, parentName string) (e
1615
if err != nil {
1716
return
1817
}
19-
c.activeTransactionHasChanges = true
2018
_, rules, err := configuration.GetTCPRequestRules(parentType, parentName, c.activeTransaction)
2119
if err != nil {
2220
return

pkg/haproxy/api/userlist.go

-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ func (c *clientNative) UserListExistsByGroup(group string) (exist bool, err erro
1010
if err != nil {
1111
return false, err
1212
}
13-
c.activeTransactionHasChanges = true
1413

1514
var p parser.Parser
1615
var sections []string
@@ -32,7 +31,6 @@ func (c *clientNative) UserListDeleteAll() (err error) {
3231
if err != nil {
3332
return err
3433
}
35-
c.activeTransactionHasChanges = true
3634

3735
var p parser.Parser
3836
if p, err = configuration.GetParser(c.activeTransaction); err != nil {
@@ -58,7 +56,6 @@ func (c *clientNative) UserListCreateByGroup(group string, userPasswordMap map[s
5856
if err != nil {
5957
return err
6058
}
61-
c.activeTransactionHasChanges = true
6259

6360
var p parser.Parser
6461
if p, err = configuration.GetParser(c.activeTransaction); err != nil {

0 commit comments

Comments
 (0)