Skip to content

Commit fe97fc3

Browse files
authored
[Feature] [Gateway] Dynamic Configuration (#1718)
1 parent 3d46436 commit fe97fc3

20 files changed

+552
-47
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- (Feature) (Gateway) ArangoDB JWT Auth Integration
2727
- (Feature) Scheduler Handler
2828
- (Feature) (Gateway) ArangoDB Auth Token
29+
- (Feature) (Gateway) Dynamic Configuration
2930

3031
## [1.2.42](https://github.com/arangodb/kube-arangodb/tree/1.2.42) (2024-07-23)
3132
- (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries

docs/api/ArangoDeployment.V1.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3043,6 +3043,17 @@ Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.
30433043

30443044
***
30453045

3046+
### .spec.gateway.dynamic
3047+
3048+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec_gateway.go#L38)</sup>
3049+
3050+
Dynamic setting enables/disables support dynamic configuration of the gateway in the cluster.
3051+
When enabled, gateway config will be reloaded by ConfigMap live updates.
3052+
3053+
Default Value: `false`
3054+
3055+
***
3056+
30463057
### .spec.gateway.enabled
30473058

30483059
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec_gateway.go#L33)</sup>
@@ -3056,7 +3067,7 @@ Default Value: `false`
30563067

30573068
### .spec.gateway.image
30583069

3059-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec_gateway.go#L37)</sup>
3070+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec_gateway.go#L42)</sup>
30603071

30613072
Image is the image to use for the gateway.
30623073
By default, the image is determined by the operator.

pkg/apis/deployment/v1/deployment_spec_gateway.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ type DeploymentSpecGateway struct {
3232
// +doc/default: false
3333
Enabled *bool `json:"enabled,omitempty"`
3434

35+
// Dynamic setting enables/disables support dynamic configuration of the gateway in the cluster.
36+
// When enabled, gateway config will be reloaded by ConfigMap live updates.
37+
// +doc/default: false
38+
Dynamic *bool `json:"dynamic,omitempty"`
39+
3540
// Image is the image to use for the gateway.
3641
// By default, the image is determined by the operator.
3742
Image *string `json:"image"`
@@ -49,6 +54,15 @@ func (d *DeploymentSpecGateway) IsEnabled() bool {
4954
return *d.Enabled
5055
}
5156

57+
// IsDynamic returns whether the gateway dynamic config is enabled.
58+
func (d *DeploymentSpecGateway) IsDynamic() bool {
59+
if d == nil || d.Dynamic == nil {
60+
return false
61+
}
62+
63+
return *d.Dynamic
64+
}
65+
5266
func (d *DeploymentSpecGateway) GetSidecar() *schedulerApi.IntegrationSidecar {
5367
if d == nil || d.Sidecar == nil {
5468
return nil

pkg/apis/deployment/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/deployment/v2alpha1/deployment_spec_gateway.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ type DeploymentSpecGateway struct {
3232
// +doc/default: false
3333
Enabled *bool `json:"enabled,omitempty"`
3434

35+
// Dynamic setting enables/disables support dynamic configuration of the gateway in the cluster.
36+
// When enabled, gateway config will be reloaded by ConfigMap live updates.
37+
// +doc/default: false
38+
Dynamic *bool `json:"dynamic,omitempty"`
39+
3540
// Image is the image to use for the gateway.
3641
// By default, the image is determined by the operator.
3742
Image *string `json:"image"`
@@ -49,6 +54,15 @@ func (d *DeploymentSpecGateway) IsEnabled() bool {
4954
return *d.Enabled
5055
}
5156

57+
// IsDynamic returns whether the gateway dynamic config is enabled.
58+
func (d *DeploymentSpecGateway) IsDynamic() bool {
59+
if d == nil || d.Dynamic == nil {
60+
return false
61+
}
62+
63+
return *d.Dynamic
64+
}
65+
5266
func (d *DeploymentSpecGateway) GetSidecar() *schedulerApi.IntegrationSidecar {
5367
if d == nil || d.Sidecar == nil {
5468
return nil

pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/crd/crds/database-deployment.schema.generated.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6567,6 +6567,11 @@ v1:
65676567
gateway:
65686568
description: Gateway defined main Gateway configuration.
65696569
properties:
6570+
dynamic:
6571+
description: |-
6572+
Dynamic setting enables/disables support dynamic configuration of the gateway in the cluster.
6573+
When enabled, gateway config will be reloaded by ConfigMap live updates.
6574+
type: boolean
65706575
enabled:
65716576
description: |-
65726577
Enabled setting enables/disables support for gateway in the cluster.
@@ -23084,6 +23089,11 @@ v1alpha:
2308423089
gateway:
2308523090
description: Gateway defined main Gateway configuration.
2308623091
properties:
23092+
dynamic:
23093+
description: |-
23094+
Dynamic setting enables/disables support dynamic configuration of the gateway in the cluster.
23095+
When enabled, gateway config will be reloaded by ConfigMap live updates.
23096+
type: boolean
2308723097
enabled:
2308823098
description: |-
2308923099
Enabled setting enables/disables support for gateway in the cluster.

pkg/deployment/resources/config_map_gateway.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,26 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec
5555
return errors.WithStack(errors.Wrapf(err, "Failed to generate gateway config"))
5656
}
5757

58-
gatewayCfgYaml, gatewayCfgChecksum, _, err := cfg.RenderYAML()
58+
gatewayCfgYaml, _, _, err := cfg.RenderYAML()
59+
if err != nil {
60+
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
61+
}
62+
63+
gatewayCfgCDSYaml, _, _, err := cfg.RenderCDSYAML()
64+
if err != nil {
65+
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway cds config"))
66+
}
67+
68+
gatewayCfgLDSYaml, _, _, err := cfg.RenderLDSYAML()
69+
if err != nil {
70+
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway lds config"))
71+
}
72+
73+
elements, err := r.renderConfigMap(map[string]string{
74+
GatewayConfigFileName: string(gatewayCfgYaml),
75+
GatewayCDSConfigFileName: string(gatewayCfgCDSYaml),
76+
GatewayLDSConfigFileName: string(gatewayCfgLDSYaml),
77+
})
5978
if err != nil {
6079
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
6180
}
@@ -66,10 +85,7 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec
6685
ObjectMeta: meta.ObjectMeta{
6786
Name: configMapName,
6887
},
69-
Data: map[string]string{
70-
GatewayConfigFileName: string(gatewayCfgYaml),
71-
GatewayConfigChecksumFileName: gatewayCfgChecksum,
72-
},
88+
Data: elements,
7389
}
7490

7591
owner := r.context.GetAPIObject().AsOwner()
@@ -88,17 +104,14 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec
88104
return errors.Reconcile()
89105
} else {
90106
// CM Exists, checks checksum - if key is not in the map we return empty string
91-
if existingSha, existingChecksumSha := util.SHA256FromString(cm.Data[GatewayConfigFileName]), cm.Data[GatewayConfigChecksumFileName]; existingSha != gatewayCfgChecksum || existingChecksumSha != gatewayCfgChecksum {
107+
if currentSha, expectedSha := util.Optional(cm.Data, ConfigMapChecksumKey, ""), util.Optional(elements, ConfigMapChecksumKey, ""); currentSha != expectedSha || currentSha == "" {
92108
// We need to do the update
93109
if _, changed, err := patcher.Patcher[*core.ConfigMap](ctx, cachedStatus.ConfigMapsModInterface().V1(), cm, meta.PatchOptions{},
94-
patcher.PatchConfigMapData(map[string]string{
95-
GatewayConfigFileName: string(gatewayCfgYaml),
96-
GatewayConfigChecksumFileName: gatewayCfgChecksum,
97-
})); err != nil {
110+
patcher.PatchConfigMapData(elements)); err != nil {
98111
log.Err(err).Debug("Failed to patch GatewayConfig ConfigMap")
99112
return errors.WithStack(err)
100113
} else if changed {
101-
log.Str("service", cm.GetName()).Str("before", existingSha).Str("after", gatewayCfgChecksum).Info("Updated GatewayConfig")
114+
log.Str("configmap", cm.GetName()).Str("before", currentSha).Str("after", expectedSha).Info("Updated GatewayConfig")
102115
}
103116
}
104117
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package resources
22+
23+
import (
24+
"context"
25+
26+
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
27+
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/gateway"
28+
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
29+
)
30+
31+
func (r *Resources) ensureMemberConfigGatewayConfig(ctx context.Context, cachedStatus inspectorInterface.Inspector, member api.DeploymentStatusMemberElement) (map[string]string, error) {
32+
if member.Group != api.ServerGroupGateways {
33+
return nil, nil
34+
}
35+
36+
data, _, _, err := gateway.NodeDynamicConfig("arangodb", member.Member.ID, &gateway.DynamicConfig{
37+
Path: GatewayVolumeMountDir,
38+
File: GatewayCDSConfigFileName,
39+
}, &gateway.DynamicConfig{
40+
Path: GatewayVolumeMountDir,
41+
File: GatewayLDSConfigFileName,
42+
})
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
return map[string]string{
48+
GatewayDynamicConfigFileName: string(data),
49+
}, nil
50+
}

pkg/deployment/resources/config_maps.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ func (r *Resources) EnsureConfigMaps(ctx context.Context, cachedStatus inspector
5454
if err := reconcileRequired.WithError(r.ensureGatewayConfig(ctx, cachedStatus, configMaps)); err != nil {
5555
return errors.Section(err, "Gateway ConfigMap")
5656
}
57+
if err := reconcileRequired.WithError(r.ensureMemberConfig(ctx, cachedStatus, configMaps)); err != nil {
58+
return errors.Section(err, "Member ConfigMap")
59+
}
5760
}
5861
return reconcileRequired.Reconcile(ctx)
5962
}

0 commit comments

Comments
 (0)