Skip to content

Commit fb848fd

Browse files
committed
MEDIUM: Remove state and data from dataplaneapi configuration file
1 parent f956754 commit fb848fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3523
-326
lines changed

.gitlab-ci.yml

+16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
stages:
22
- lint
33
- build
4+
- test
45
- e2e
56
variables:
67
DOCKER_HOST: tcp://docker:2375
@@ -101,6 +102,21 @@ build:
101102
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
102103
- if: $CI_PIPELINE_SOURCE == 'push'
103104

105+
test:
106+
stage: test
107+
image:
108+
name: $CI_REGISTRY_GO/golang:$GO_VERSION
109+
entrypoint: [ "" ]
110+
tags:
111+
- go
112+
before_script:
113+
- go env -w "GONOSUMDB=gitlab.int.haproxy.com/*" "GOPROXY=http://goproxy.int.haproxy.com"
114+
script:
115+
- go test ./...
116+
rules:
117+
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
118+
- if: "$CI_PROJECT_NAMESPACE == 'haproxy-controller' && $CI_PIPELINE_SOURCE == 'push'"
119+
104120
.e2e:
105121
stage: e2e
106122
artifacts:

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ generate:
6161
generate-native:
6262
generate/swagger/script.sh
6363
generate/post_swagger.sh
64+
65+
.PHONY: test
66+
test:
67+
go test ./...

cmd/dataplaneapi/main.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121
"os"
2222
"path"
23+
"path/filepath"
2324
"syscall"
2425

2526
loads "github.com/go-openapi/loads"
@@ -78,7 +79,7 @@ func startRuntimeDebugServer() context.CancelFunc {
7879
return cancelDebugServer
7980
}
8081

81-
func startServer(cfg *configuration.Configuration, cancelDebugServer context.CancelFunc) (reload configuration.AtomicBool) {
82+
func startServer(cfg *configuration.Configuration, cancelDebugServer context.CancelFunc) (reload configuration.AtomicBool) { //nolint: maintidx
8283
swaggerSpec, err := loads.Embedded(dataplaneapi.SwaggerJSON, dataplaneapi.FlatSwaggerJSON)
8384
if err != nil {
8485
fmt.Println(err)
@@ -128,7 +129,8 @@ func startServer(cfg *configuration.Configuration, cancelDebugServer context.Can
128129
return
129130
}
130131

131-
err = cfg.Load()
132+
var loadMsg []string
133+
_, err = cfg.Load()
132134
if err != nil {
133135
fmt.Println("configuration error:", err)
134136
os.Exit(1)
@@ -148,6 +150,13 @@ func startServer(cfg *configuration.Configuration, cancelDebugServer context.Can
148150
}
149151
}
150152

153+
loadMsg, err = cfg.LoadDataplaneStorageConfig()
154+
if err != nil {
155+
fmt.Println("configuration error:", err)
156+
os.Exit(1)
157+
}
158+
cfg.FlagLoadDapiStorageData = true
159+
151160
// incorporate changes from file to global settings
152161
dataplaneapi.SyncWithFileSettings(server, cfg)
153162
err = cfg.LoadRuntimeVars(dataplaneapi.SwaggerJSON, server.Host, server.Port)
@@ -173,6 +182,7 @@ func startServer(cfg *configuration.Configuration, cancelDebugServer context.Can
173182
cfg.HAProxy.MapsDir = path.Join(storageDir, string(storage.MapsType))
174183
cfg.HAProxy.SSLCertsDir = path.Join(storageDir, string(storage.SSLType))
175184
cfg.HAProxy.GeneralStorageDir = path.Join(storageDir, string(storage.GeneralType))
185+
cfg.HAProxy.DataplaneStorageDir = filepath.Clean(path.Join(storageDir, "dataplane"))
176186
cfg.HAProxy.SpoeDir = path.Join(storageDir, string(storage.SpoeType))
177187
cfg.HAProxy.SpoeTransactionDir = path.Join(storageDir, string(storage.SpoeTransactionsType))
178188
cfg.HAProxy.BackupsDir = path.Join(storageDir, string(storage.BackupsType))
@@ -199,6 +209,13 @@ func startServer(cfg *configuration.Configuration, cancelDebugServer context.Can
199209
log.Infof("Build date: %s", BuildTime)
200210
log.Infof("Reload strategy: %s", cfg.HAProxy.ReloadStrategy)
201211

212+
// log deprecation message
213+
if len(loadMsg) > 0 {
214+
for _, msg := range loadMsg {
215+
log.Warning(msg)
216+
}
217+
}
218+
202219
err = cfg.Save()
203220
if err != nil {
204221
log.Fatalf("Error saving configuration: %s", err.Error())
@@ -247,6 +264,7 @@ func startServer(cfg *configuration.Configuration, cancelDebugServer context.Can
247264

248265
server.ConfigureAPI()
249266
dataplaneapi.SetServerStartedCallback(cfg.Notify.ServerStarted.Notify)
267+
250268
if err := server.Serve(); err != nil {
251269
log.Fatalf("Error running HAProxy Data Plane API: %s", err.Error())
252270
}

configuration/README.md

+68
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,71 @@
44

55
example can be seen [yaml](examples/example-dataplaneapi.yaml)
66
full examples of configuration also can be seen at [yaml](examples/example-full.yaml)
7+
8+
# IMPORTANT information regarding migration from 2.x to 3.0 version
9+
10+
Some fields in dataplane configuration file are *deprecated* starting from version 3.0.
11+
12+
They are now moved to Data Plane API internal storage (`dataplane_storage_dir`): [read here](../storage/README.md)
13+
14+
15+
16+
Those fields are the one that were not really dataplane configuration attributes but *dynamic* data (cluster, users...). They are moved to a dataplane internal storage. Hence the dataplane configuration file is not any more updated with states and data and only contains configuration.
17+
18+
- `dataplaneapi.user` (**only cluster mode users, whose name are starting with `dpapi-c` are migrated**)
19+
- `cluster`
20+
- `service_discovery`
21+
- `status`
22+
23+
Those data are moved to dataplane internal storage.
24+
25+
26+
27+
## Migration from Dataplane API 2.x to 3.0 behavior
28+
29+
Data (`user`, `cluster`, `service_discovery`, `status`) that were in Dataplane API configuration file are automatically created in:
30+
- `<dataplane_storage_dir>/service_discovery.json`
31+
- `<dataplane_storage_dir>/cluster.json`
32+
33+
34+
## General behavior regarding the deprecated section
35+
36+
If some of those data are manually updated in Dataplane configuration file (**this should not be done, fields are deprecated**), or if it's the first start of a *3.0* dataplane API:
37+
- A warning log is issued (search for logs having `"[CFG DEPRECATED]`) with `[SKIP]` or `[MIGRATE]` and the category:
38+
- `[User]` or
39+
- `[Cluster]` or
40+
- `[Consul]` or
41+
- `[AWS Region]` or
42+
- `[Status]`
43+
44+
Below an an example for cluster users:
45+
46+
```
47+
time="2024-07-22T09:12:09+02:00" level=warning msg="[CFG DEPRECATED] [SKIP] [User] [dpapi-c-Abr8s1V]: already migrated. Old location [/home/helene/go/src/gitlab.int.haproxy.com/dataplaneapi-ee/.test/etc/dataplaneapi-cluster.yml] New location [/home/helene/go/src/gitlab.int.haproxy.com/dataplaneapi-ee/.test/storage/dataplane/users.json]. Use only new location"
48+
```
49+
```
50+
time="2024-07-22T09:12:09+02:00" level=warning msg="[CFG DEPRECATED] [MIGRATE] [User] [dpapi-c-8Mk2Z5UK]: migrating. Old location [/home/helene/go/src/gitlab.int.haproxy.com/dataplaneapi-ee/.test/etc/dataplaneapi-cluster.yml] New location [/home/helene/go/src/gitlab.int.haproxy.com/dataplaneapi-ee/.test/storage/dataplane/users.json]. Use only new location"
51+
```
52+
53+
- **After migration, data are removed from the dataplane configuration file.**
54+
- **If a data is added again in the dataplane configuration file, and has already been migrated to the internal storage, then the value from the configuration file is ignored. Only the value from the storage is kept.**
55+
56+
57+
58+
**IMPORTANT NOTE: only cluster mode users, whose name are starting with `dpapi-` are migrated**
59+
60+
61+
62+
## Cluster Mode: deprecation
63+
64+
The dataplane api configuration field:
65+
- `mode` (values = `single` or `cluster`)
66+
67+
is now deprecated and this value is removed from dataplane api configuration file after migration.
68+
69+
The way `cluster` vs `single` is now handled is as following:
70+
71+
| Mode | <dataplane_storage_dir>/cluster.json content |
72+
|-----------|-------------------|
73+
| Single| `cluster` attribute is not empty|
74+
| Cluster| `cluster` attribute is empty |

configuration/cluster_sync.go

+14-12
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,9 @@ func (c *ClusterSync) issueRefreshRequest(url, port, basePath string, nodesPath
186186
return err
187187
}
188188
c.cfg.Cluster.Token.Store(resp.Header.Get("X-Node-Key"))
189-
err = c.cfg.Save()
190-
if err != nil {
189+
if err = c.cfg.SaveClusterModeData(); err != nil {
191190
log.Warning(err)
192-
return err
191+
return fmt.Errorf("failed to save cluster mode data: %v", err)
193192
}
194193
c.cfg.Notify.Reload.Notify()
195194
return nil
@@ -206,7 +205,7 @@ func (c *ClusterSync) monitorBootstrapKey() {
206205
// do we need to delete cert here maybe?
207206
log.Warningf("setting bootstrap key to empty")
208207
c.cfg.Cluster.ActiveBootstrapKey.Store("")
209-
err := c.cfg.Save()
208+
err := c.cfg.SaveClusterModeData()
210209
if err != nil {
211210
log.Panic(err)
212211
}
@@ -253,8 +252,11 @@ func (c *ClusterSync) monitorBootstrapKey() {
253252
c.cfg.Cluster.ClusterID.Store(data["cluster-id"])
254253
c.cfg.HAProxy.ClusterTLSCertDir = path.Join(data["storage-dir"], "certs-cluster")
255254
c.cfg.Cluster.CertificateDir.Store(path.Join(data["storage-dir"], "certs-cluster"))
256-
c.cfg.Mode.Store(ModeCluster)
257-
err = c.cfg.Save()
255+
err = c.cfg.SaveClusterModeData()
256+
if err != nil {
257+
log.Panic(err)
258+
}
259+
258260
if err != nil {
259261
log.Panic(err)
260262
}
@@ -273,7 +275,7 @@ func (c *ClusterSync) monitorBootstrapKey() {
273275
log.Warning(err)
274276
break
275277
}
276-
err = c.cfg.Save()
278+
err = c.cfg.SaveClusterModeData()
277279
if err != nil {
278280
log.Panic(err)
279281
}
@@ -458,7 +460,7 @@ func (c *ClusterSync) issueJoinRequest(url, port, basePath string, registerPath
458460
if err != nil {
459461
return err
460462
}
461-
return c.cfg.Save()
463+
return c.cfg.SaveClusterModeData()
462464
}
463465

464466
// checkCertificate checks if we have received valid certificate or we just got CSR back
@@ -467,17 +469,17 @@ func (c *ClusterSync) issueJoinRequest(url, port, basePath string, registerPath
467469
// -----BEGIN CERTIFICATE----- or -----BEGIN CERTIFICATE REQUEST-----
468470
func (c *ClusterSync) checkCertificate(node Node) (fetched bool, err error) {
469471
if !strings.HasPrefix(node.Certificate, "-----BEGIN CERTIFICATE-----") {
470-
c.cfg.Status.Store("unconfigured")
472+
c.cfg.Status.Store(StatusUnconfigured)
471473
return false, nil
472474
}
473475
err = renameio.WriteFile(path.Join(c.cfg.GetClusterCertDir(), fmt.Sprintf("dataplane-%s.crt", c.cfg.Name.Load())), []byte(node.Certificate), 0o644)
474476
if err != nil {
475-
c.cfg.Status.Store("unconfigured")
477+
c.cfg.Status.Store(StatusUnconfigured)
476478
return false, err
477479
}
478480
c.cfg.Cluster.CertificateFetched.Store(true)
479481
c.cfg.Notify.Reload.Notify()
480-
c.cfg.Status.Store("active")
482+
c.cfg.Status.Store(StatusActive)
481483
return true, nil
482484
}
483485

@@ -548,7 +550,7 @@ func (c *ClusterSync) fetchCert() {
548550
log.Warning(err.Error())
549551
break
550552
}
551-
err = c.cfg.Save()
553+
err = c.cfg.SaveClusterModeData()
552554
if err != nil {
553555
log.Warning(err)
554556
}

0 commit comments

Comments
 (0)