diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d0adde5f..ac20f3c68 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,6 +46,7 @@
- (Bugfix) (Platform) Proper Path handler in StorageV2
- (Feature) Helm Chart Values merge methods
- (Feature) (Platform) Expose Route Name via Header
+- (Feature) (Platform) Route Upstream Timeout
## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14)
- (Feature) ArangoRoute CRD
diff --git a/docs/api/ArangoRoute.V1Alpha1.md b/docs/api/ArangoRoute.V1Alpha1.md
index 676ae906c..26bec1a7f 100644
--- a/docs/api/ArangoRoute.V1Alpha1.md
+++ b/docs/api/ArangoRoute.V1Alpha1.md
@@ -83,7 +83,7 @@ UID keeps the information about object UID
### .spec.destination.path
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L46)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L51)
Path defines service path used for overrides
@@ -91,7 +91,7 @@ Path defines service path used for overrides
### .spec.destination.protocol
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L40)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L45)
Protocol defines http protocol used for the route
@@ -103,7 +103,7 @@ Possible Values:
### .spec.destination.schema
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L35)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L40)
Schema defines HTTP/S schema used for connection
@@ -153,6 +153,14 @@ UID keeps the information about object UID
***
+### .spec.destination.timeout
+
+Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination.go#L57)
+
+Timeout specify the upstream request timeout
+
+***
+
### .spec.destination.tls.insecure
Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_spec_destination_tls.go#L25)
@@ -273,7 +281,7 @@ Possible Values:
### .status.target.path
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L49)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L51)
Path specifies request path override
@@ -281,12 +289,20 @@ Path specifies request path override
### .status.target.protocol
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L40)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L42)
Protocol defines http protocol used for the route
***
+### .status.target.timeout
+
+Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L54)
+
+Timeout specify the upstream request timeout
+
+***
+
### .status.target.tls.insecure
Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target_tls.go#L27)
@@ -297,7 +313,7 @@ Insecure allows Insecure traffic
### .status.target.type
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L34)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.43/pkg/apis/networking/v1alpha1/route_status_target.go#L36)
Type define destination type
diff --git a/pkg/apis/networking/v1alpha1/route_spec_destination.go b/pkg/apis/networking/v1alpha1/route_spec_destination.go
index c4d32f683..2366415d3 100644
--- a/pkg/apis/networking/v1alpha1/route_spec_destination.go
+++ b/pkg/apis/networking/v1alpha1/route_spec_destination.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,7 +20,12 @@
package v1alpha1
-import shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
+import (
+ meta "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
+)
type ArangoRouteSpecDestination struct {
// Service defines service upstream reference
@@ -47,6 +52,9 @@ type ArangoRouteSpecDestination struct {
// Authentication defines auth methods
Authentication *ArangoRouteSpecDestinationAuthentication `json:"authentication,omitempty"`
+
+ // Timeout specify the upstream request timeout
+ Timeout *meta.Duration `json:"timeout,omitempty"`
}
func (a *ArangoRouteSpecDestination) GetService() *ArangoRouteSpecDestinationService {
@@ -89,6 +97,16 @@ func (a *ArangoRouteSpecDestination) GetPath() string {
return *a.Path
}
+func (a *ArangoRouteSpecDestination) GetTimeout() meta.Duration {
+ if a == nil || a.Timeout == nil {
+ return meta.Duration{
+ Duration: constants.DefaultEnvoyUpstreamTimeout,
+ }
+ }
+
+ return *a.Timeout
+}
+
func (a *ArangoRouteSpecDestination) GetTLS() *ArangoRouteSpecDestinationTLS {
if a == nil || a.TLS == nil {
return nil
diff --git a/pkg/apis/networking/v1alpha1/route_status_target.go b/pkg/apis/networking/v1alpha1/route_status_target.go
index 2b8cb5bd7..c166a0525 100644
--- a/pkg/apis/networking/v1alpha1/route_status_target.go
+++ b/pkg/apis/networking/v1alpha1/route_status_target.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,6 +23,8 @@ package v1alpha1
import (
"fmt"
+ meta "k8s.io/apimachinery/pkg/apis/meta/v1"
+
"github.com/arangodb/kube-arangodb/pkg/util"
)
@@ -47,6 +49,9 @@ type ArangoRouteStatusTarget struct {
// Path specifies request path override
Path string `json:"path,omitempty"`
+
+ // Timeout specify the upstream request timeout
+ Timeout meta.Duration `json:"timeout,omitempty"`
}
func (a *ArangoRouteStatusTarget) RenderURLs() []string {
@@ -73,5 +78,5 @@ func (a *ArangoRouteStatusTarget) Hash() string {
if a == nil {
return ""
}
- return util.SHA256FromStringArray(a.Destinations.Hash(), a.Type.Hash(), a.TLS.Hash(), a.Protocol.String(), a.Path, a.Authentication.Hash(), a.Options.Hash())
+ return util.SHA256FromStringArray(a.Destinations.Hash(), a.Type.Hash(), a.TLS.Hash(), a.Protocol.String(), a.Path, a.Authentication.Hash(), a.Options.Hash(), a.Timeout.String())
}
diff --git a/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go
index 7058314e5..c6698d399 100644
--- a/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go
@@ -27,7 +27,8 @@ package v1alpha1
import (
deploymentv1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
- v1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
+ sharedv1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
intstr "k8s.io/apimachinery/pkg/util/intstr"
)
@@ -167,6 +168,11 @@ func (in *ArangoRouteSpecDestination) DeepCopyInto(out *ArangoRouteSpecDestinati
*out = new(ArangoRouteSpecDestinationAuthentication)
(*in).DeepCopyInto(*out)
}
+ if in.Timeout != nil {
+ in, out := &in.Timeout, &out.Timeout
+ *out = new(v1.Duration)
+ **out = **in
+ }
return
}
@@ -211,7 +217,7 @@ func (in *ArangoRouteSpecDestinationEndpoints) DeepCopyInto(out *ArangoRouteSpec
*out = *in
if in.Object != nil {
in, out := &in.Object, &out.Object
- *out = new(v1.Object)
+ *out = new(sharedv1.Object)
(*in).DeepCopyInto(*out)
}
if in.Port != nil {
@@ -237,7 +243,7 @@ func (in *ArangoRouteSpecDestinationService) DeepCopyInto(out *ArangoRouteSpecDe
*out = *in
if in.Object != nil {
in, out := &in.Object, &out.Object
- *out = new(v1.Object)
+ *out = new(sharedv1.Object)
(*in).DeepCopyInto(*out)
}
if in.Port != nil {
@@ -378,7 +384,7 @@ func (in *ArangoRouteStatus) DeepCopyInto(out *ArangoRouteStatus) {
}
if in.Deployment != nil {
in, out := &in.Deployment, &out.Deployment
- *out = new(v1.Object)
+ *out = new(sharedv1.Object)
(*in).DeepCopyInto(*out)
}
if in.Target != nil {
@@ -418,6 +424,7 @@ func (in *ArangoRouteStatusTarget) DeepCopyInto(out *ArangoRouteStatusTarget) {
*out = new(ArangoRouteStatusTargetOptions)
(*in).DeepCopyInto(*out)
}
+ out.Timeout = in.Timeout
return
}
diff --git a/pkg/apis/shared/errors.go b/pkg/apis/shared/errors.go
index 9e15af9da..6887b53c4 100644
--- a/pkg/apis/shared/errors.go
+++ b/pkg/apis/shared/errors.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
+// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -53,6 +53,11 @@ func (p *ResourceError) Format(s fmt.State, verb rune) {
}
}
+// PrefixResourceErrorFunc creates new prefixed error from func output. If error is already prefixed then current key is appended
+func PrefixResourceErrorFunc(prefix string, f func() error) error {
+ return PrefixResourceError(prefix, f())
+}
+
// PrefixResourceError creates new prefixed error. If error is already prefixed then current key is appended
func PrefixResourceError(prefix string, err error) error {
if err == nil {
diff --git a/pkg/crd/crds/networking-route.schema.generated.yaml b/pkg/crd/crds/networking-route.schema.generated.yaml
index d8ba4e7d7..cfa8761cb 100644
--- a/pkg/crd/crds/networking-route.schema.generated.yaml
+++ b/pkg/crd/crds/networking-route.schema.generated.yaml
@@ -81,6 +81,9 @@ v1alpha1:
description: UID keeps the information about object UID
type: string
type: object
+ timeout:
+ description: Timeout specify the upstream request timeout
+ type: string
tls:
description: TLS defines TLS Configuration
properties:
diff --git a/pkg/deployment/resources/config_map_gateway.go b/pkg/deployment/resources/config_map_gateway.go
index 0e840a453..6c8d23d35 100644
--- a/pkg/deployment/resources/config_map_gateway.go
+++ b/pkg/deployment/resources/config_map_gateway.go
@@ -34,6 +34,7 @@ import (
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/gateway"
+ "github.com/arangodb/kube-arangodb/pkg/platform"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
@@ -44,21 +45,35 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher"
)
-const (
- EnvoyRouteHeader = "arangodb-platform-route"
-)
-
func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspectorInterface.Inspector, configMaps generic.ModClient[*core.ConfigMap]) error {
- deploymentName := r.context.GetAPIObject().GetName()
- configMapName := GetGatewayConfigMapName(deploymentName)
-
- log := r.log.Str("section", "gateway-config").Str("name", configMapName)
-
cfg, err := r.renderGatewayConfig(cachedStatus)
if err != nil {
return errors.WithStack(errors.Wrapf(err, "Failed to generate gateway config"))
}
+ _, baseGatewayCfgYamlChecksum, _, err := cfg.RenderYAML()
+ if err != nil {
+ return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
+ }
+
+ cfg.Destinations[constants.EnvoyInventoryConfigDestination] = gateway.ConfigDestination{
+ Type: util.NewType(gateway.ConfigDestinationTypeStatic),
+ AuthExtension: &gateway.ConfigAuthZExtension{
+ AuthZExtension: map[string]string{
+ pbImplEnvoyAuthV3.AuthConfigAuthRequiredKey: pbImplEnvoyAuthV3.AuthConfigKeywordTrue,
+ pbImplEnvoyAuthV3.AuthConfigAuthPassModeKey: string(networkingApi.ArangoRouteSpecAuthenticationPassModeRemove),
+ },
+ },
+ Static: &gateway.ConfigDestinationStatic{
+ Code: util.NewType[uint32](200),
+ Response: &platform.State{
+ Configuration: platform.StateConfiguration{
+ Hash: baseGatewayCfgYamlChecksum,
+ },
+ },
+ },
+ }
+
gatewayCfgYaml, _, _, err := cfg.RenderYAML()
if err != nil {
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
@@ -74,20 +89,40 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway lds config"))
}
- elements, err := r.renderConfigMap(map[string]string{
- GatewayConfigFileName: string(gatewayCfgYaml),
- GatewayCDSConfigFileName: string(gatewayCfgCDSYaml),
- GatewayLDSConfigFileName: string(gatewayCfgLDSYaml),
- })
+ if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName()), map[string]string{
+ constants.GatewayConfigFileName: string(gatewayCfgYaml),
+ }); err != nil {
+ return err
+ }
+
+ if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName(), "cds"), map[string]string{
+ constants.GatewayConfigFileName: string(gatewayCfgCDSYaml),
+ }); err != nil {
+ return err
+ }
+
+ if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName(), "lds"), map[string]string{
+ constants.GatewayConfigFileName: string(gatewayCfgLDSYaml),
+ }); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (r *Resources) ensureGatewayConfigMap(ctx context.Context, cachedStatus inspectorInterface.Inspector, configMaps generic.ModClient[*core.ConfigMap], name string, data map[string]string) error {
+ log := r.log.Str("section", "gateway-config").Str("name", name)
+
+ elements, err := r.renderConfigMap(data)
if err != nil {
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
}
- if cm, exists := cachedStatus.ConfigMap().V1().GetSimple(configMapName); !exists {
+ if cm, exists := cachedStatus.ConfigMap().V1().GetSimple(name); !exists {
// Create
cm = &core.ConfigMap{
ObjectMeta: meta.ObjectMeta{
- Name: configMapName,
+ Name: name,
},
Data: elements,
}
@@ -108,7 +143,7 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec
return errors.Reconcile()
} else {
// CM Exists, checks checksum - if key is not in the map we return empty string
- if currentSha, expectedSha := util.Optional(cm.Data, ConfigMapChecksumKey, ""), util.Optional(elements, ConfigMapChecksumKey, ""); currentSha != expectedSha || currentSha == "" {
+ if currentSha, expectedSha := util.Optional(cm.Data, constants.ConfigMapChecksumKey, ""), util.Optional(elements, constants.ConfigMapChecksumKey, ""); currentSha != expectedSha || currentSha == "" {
// We need to do the update
if _, changed, err := patcher.Patcher[*core.ConfigMap](ctx, cachedStatus.ConfigMapsModInterface().V1(), cm, meta.PatchOptions{},
patcher.PatchConfigMapData(elements)); err != nil {
@@ -137,6 +172,10 @@ func (r *Resources) renderGatewayConfig(cachedStatus inspectorInterface.Inspecto
var cfg gateway.Config
+ cfg.Options = &gateway.ConfigOptions{
+ MergeSlashes: util.NewType(true),
+ }
+
cfg.IntegrationSidecar = &gateway.ConfigDestinationTarget{
Host: "127.0.0.1",
Port: int32(r.context.GetSpec().Integration.GetSidecar().GetListenPort()),
@@ -150,6 +189,9 @@ func (r *Resources) renderGatewayConfig(cachedStatus inspectorInterface.Inspecto
},
},
AuthExtension: &gateway.ConfigAuthZExtension{},
+ Timeout: &meta.Duration{
+ Duration: constants.MaxGatewayTimeout,
+ },
}
if spec.TLS.IsSecure() {
@@ -227,6 +269,7 @@ func (r *Resources) renderGatewayConfig(cachedStatus inspectorInterface.Inspecto
}
}
dest.Path = util.NewType(target.Path)
+ dest.Timeout = target.Timeout.DeepCopy()
dest.AuthExtension = &gateway.ConfigAuthZExtension{
AuthZExtension: map[string]string{
pbImplEnvoyAuthV3.AuthConfigAuthRequiredKey: util.BoolSwitch[string](target.Authentication.Type.Get() == networkingApi.ArangoRouteSpecAuthenticationTypeRequired, pbImplEnvoyAuthV3.AuthConfigKeywordTrue, pbImplEnvoyAuthV3.AuthConfigKeywordFalse),
@@ -234,7 +277,7 @@ func (r *Resources) renderGatewayConfig(cachedStatus inspectorInterface.Inspecto
},
}
dest.ResponseHeaders = map[string]string{
- EnvoyRouteHeader: at.GetName(),
+ constants.EnvoyRouteHeader: at.GetName(),
}
cfg.Destinations[at.Spec.GetRoute().GetPath()] = dest
}
diff --git a/pkg/deployment/resources/config_map_gateway_member.go b/pkg/deployment/resources/config_map_gateway_member.go
index 2ca0c509e..fddfa3196 100644
--- a/pkg/deployment/resources/config_map_gateway_member.go
+++ b/pkg/deployment/resources/config_map_gateway_member.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/gateway"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
)
@@ -34,17 +35,17 @@ func (r *Resources) ensureMemberConfigGatewayConfig(ctx context.Context, cachedS
}
data, _, _, err := gateway.NodeDynamicConfig("arangodb", member.Member.ID, &gateway.DynamicConfig{
- Path: GatewayVolumeMountDir,
- File: GatewayCDSConfigFileName,
+ Path: constants.GatewayCDSVolumeMountDir,
+ File: constants.GatewayConfigFileName,
}, &gateway.DynamicConfig{
- Path: GatewayVolumeMountDir,
- File: GatewayLDSConfigFileName,
+ Path: constants.GatewayLDSVolumeMountDir,
+ File: constants.GatewayConfigFileName,
})
if err != nil {
return nil, err
}
return map[string]string{
- GatewayDynamicConfigFileName: string(data),
+ constants.GatewayConfigFileName: string(data),
}, nil
}
diff --git a/pkg/deployment/resources/config_maps_member.go b/pkg/deployment/resources/config_maps_member.go
index 90bd1117d..88712a6b1 100644
--- a/pkg/deployment/resources/config_maps_member.go
+++ b/pkg/deployment/resources/config_maps_member.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/assertion"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/globals"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
@@ -38,15 +39,6 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher"
)
-const (
- ConfigMapChecksumKey = "CHECKSUM"
-
- MemberConfigVolumeMountDir = "/etc/member/"
- MemberConfigVolumeName = "member-config"
-
- MemberConfigChecksumENV = "MEMBER_CONFIG_CHECKSUM"
-)
-
type memberConfigMapRenderer func(ctx context.Context, cachedStatus inspectorInterface.Inspector, member api.DeploymentStatusMemberElement) (map[string]string, error)
func (r *Resources) ensureMemberConfig(ctx context.Context, cachedStatus inspectorInterface.Inspector, configMaps generic.ModClient[*core.ConfigMap]) error {
@@ -111,7 +103,7 @@ func (r *Resources) ensureMemberConfig(ctx context.Context, cachedStatus inspect
return errors.Reconcile()
} else {
// CM Exists, checks checksum - if key is not in the map we return empty string
- if currentSha, expectedSha := util.Optional(obj.Data, ConfigMapChecksumKey, ""), util.Optional(elements, ConfigMapChecksumKey, ""); currentSha != expectedSha || currentSha == "" {
+ if currentSha, expectedSha := util.Optional(obj.Data, constants.ConfigMapChecksumKey, ""), util.Optional(elements, constants.ConfigMapChecksumKey, ""); currentSha != expectedSha || currentSha == "" {
// We need to do the update
if _, changed, err := patcher.Patcher[*core.ConfigMap](ctx, cachedStatus.ConfigMapsModInterface().V1(), obj, meta.PatchOptions{},
patcher.PatchConfigMapData(elements)); err != nil {
@@ -152,7 +144,7 @@ func (r *Resources) renderConfigMap(elements ...map[string]string) (map[string]s
return nil, nil
}
- result[ConfigMapChecksumKey] = util.SHA256FromStringMap(result)
+ result[constants.ConfigMapChecksumKey] = util.SHA256FromStringMap(result)
return result, nil
}
diff --git a/pkg/deployment/resources/gateway/gateway_authz_extension.go b/pkg/deployment/resources/gateway/gateway_authz_extension.go
index b7e6edf0c..931482128 100644
--- a/pkg/deployment/resources/gateway/gateway_authz_extension.go
+++ b/pkg/deployment/resources/gateway/gateway_authz_extension.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import (
pbImplEnvoyAuthV3 "github.com/arangodb/kube-arangodb/integrations/envoy/auth/v3"
"github.com/arangodb/kube-arangodb/pkg/util"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
)
type ConfigAuthZExtension struct {
@@ -57,7 +58,7 @@ func (c *ConfigAuthZExtension) RenderTypedFilterConfig() (util.KV[string, *anypb
}
return util.KV[string, *anypb.Any]{
- K: IntegrationSidecarFilterName,
+ K: constants.EnvoyIntegrationSidecarFilterName,
V: q,
}, nil
}
diff --git a/pkg/deployment/resources/gateway/gateway_config.go b/pkg/deployment/resources/gateway/gateway_config.go
index f55d8a20a..b18bf335b 100644
--- a/pkg/deployment/resources/gateway/gateway_config.go
+++ b/pkg/deployment/resources/gateway/gateway_config.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ import (
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/util"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
@@ -56,6 +57,8 @@ type Config struct {
IntegrationSidecar *ConfigDestinationTarget `json:"integrationSidecar,omitempty"`
SNI ConfigSNIList `json:"sni,omitempty"`
+
+ Options *ConfigOptions `json:"options,omitempty"`
}
func (c Config) Validate() error {
@@ -212,6 +215,9 @@ func (c Config) RenderClusters() ([]*clusterAPI.Cluster, error) {
return nil, err
}
+ if c == nil {
+ continue
+ }
clusters = append(clusters, c)
}
@@ -267,7 +273,7 @@ func (c Config) RenderIntegrationSidecarFilter() (*httpConnectionManagerAPI.Http
}
return &httpConnectionManagerAPI.HttpFilter{
- Name: IntegrationSidecarFilterName,
+ Name: constants.EnvoyIntegrationSidecarFilterName,
ConfigType: &httpConnectionManagerAPI.HttpFilter_TypedConfig{
TypedConfig: e,
},
@@ -300,6 +306,7 @@ func (c Config) RenderFilters() ([]*listenerAPI.Filter, error) {
StatPrefix: "ingress_http",
CodecType: httpConnectionManagerAPI.HttpConnectionManager_AUTO,
ServerHeaderTransformation: httpConnectionManagerAPI.HttpConnectionManager_PASS_THROUGH,
+ MergeSlashes: c.Options.GetMergeSlashes(),
RouteSpecifier: &httpConnectionManagerAPI.HttpConnectionManager_RouteConfig{
RouteConfig: &routeAPI.RouteConfiguration{
Name: "default",
diff --git a/pkg/deployment/resources/gateway/gateway_config_destination.go b/pkg/deployment/resources/gateway/gateway_config_destination.go
index fb2ddda7e..feed655e6 100644
--- a/pkg/deployment/resources/gateway/gateway_config_destination.go
+++ b/pkg/deployment/resources/gateway/gateway_config_destination.go
@@ -21,6 +21,7 @@
package gateway
import (
+ "encoding/json"
"time"
clusterAPI "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
@@ -29,8 +30,10 @@ import (
routeAPI "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"
+ meta "k8s.io/apimachinery/pkg/apis/meta/v1"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
@@ -72,22 +75,53 @@ type ConfigDestination struct {
TLS ConfigDestinationTLS `json:"tls,omitempty"`
+ Timeout *meta.Duration `json:"timeout,omitempty"`
+
ResponseHeaders map[string]string `json:"responseHeaders,omitempty"`
+
+ Static *ConfigDestinationStatic `json:"static,omitempty"`
}
func (c *ConfigDestination) Validate() error {
if c == nil {
c = &ConfigDestination{}
}
- return shared.WithErrors(
- shared.PrefixResourceError("targets", c.Targets.Validate()),
- shared.PrefixResourceError("type", c.Type.Validate()),
- shared.PrefixResourceError("protocol", c.Protocol.Validate()),
- shared.PrefixResourceError("tls", c.TLS.Validate()),
- shared.PrefixResourceError("path", shared.ValidateAPIPath(c.GetPath())),
- shared.PrefixResourceError("authExtension", c.AuthExtension.Validate()),
- shared.PrefixResourceError("upgradeConfigs", c.UpgradeConfigs.Validate()),
- )
+
+ switch c.Type.Get() {
+ case ConfigDestinationTypeStatic:
+ return shared.WithErrors(
+ shared.PrefixResourceError("type", c.Type.Validate()),
+ shared.PrefixResourceError("path", shared.ValidateAPIPath(c.GetPath())),
+ shared.PrefixResourceError("authExtension", c.AuthExtension.Validate()),
+ shared.PrefixResourceError("static", shared.ValidateRequiredInterface(c.Static)),
+ )
+ default:
+ return shared.WithErrors(
+ shared.PrefixResourceError("targets", c.Targets.Validate()),
+ shared.PrefixResourceError("type", c.Type.Validate()),
+ shared.PrefixResourceError("protocol", c.Protocol.Validate()),
+ shared.PrefixResourceError("tls", c.TLS.Validate()),
+ shared.PrefixResourceError("path", shared.ValidateAPIPath(c.GetPath())),
+ shared.PrefixResourceError("authExtension", c.AuthExtension.Validate()),
+ shared.PrefixResourceError("upgradeConfigs", c.UpgradeConfigs.Validate()),
+ shared.PrefixResourceErrorFunc("timeout", func() error {
+ if t := c.GetTimeout(); t < constants.MinGatewayTimeout {
+ return errors.Errorf("Timeout lower than %s not allowed", constants.MinGatewayTimeout.String())
+ } else if t > constants.MaxGatewayTimeout {
+ return errors.Errorf("Timeout greater than %s not allowed", constants.MaxGatewayTimeout.String())
+ }
+ return nil
+ }),
+ )
+ }
+}
+
+func (c *ConfigDestination) GetTimeout() time.Duration {
+ if c == nil || c.Timeout == nil {
+ return constants.DefaultEnvoyUpstreamTimeout
+ }
+
+ return c.Timeout.Duration
}
func (c *ConfigDestination) GetPath() string {
@@ -99,16 +133,9 @@ func (c *ConfigDestination) GetPath() string {
}
func (c *ConfigDestination) RenderRoute(name, prefix string) (*routeAPI.Route, error) {
- var tcg []TypedFilterConfigGen
-
- if c != nil && c.AuthExtension != nil {
- tcg = append(tcg, c.AuthExtension)
- }
- tc, err := NewTypedFilterConfig(tcg...)
- if err != nil {
- return nil, err
+ if c == nil {
+ return nil, errors.Errorf("Route cannot be nil")
}
-
var headers []*coreAPI.HeaderValueOption
for k, v := range c.ResponseHeaders {
@@ -122,24 +149,72 @@ func (c *ConfigDestination) RenderRoute(name, prefix string) (*routeAPI.Route, e
})
}
- return &routeAPI.Route{
+ var tcg []TypedFilterConfigGen
+
+ if c.AuthExtension != nil {
+ tcg = append(tcg, c.AuthExtension)
+ }
+ tc, err := NewTypedFilterConfig(tcg...)
+ if err != nil {
+ return nil, err
+ }
+
+ r := &routeAPI.Route{
Match: &routeAPI.RouteMatch{
PathSpecifier: &routeAPI.RouteMatch_Prefix{
Prefix: prefix,
},
},
ResponseHeadersToAdd: headers,
- Action: &routeAPI.Route_Route{
- Route: &routeAPI.RouteAction{
- ClusterSpecifier: &routeAPI.RouteAction_Cluster{
- Cluster: name,
+
+ TypedPerFilterConfig: tc,
+ }
+
+ if err := c.appendRouteAction(r, name); err != nil {
+ return nil, err
+ }
+
+ return r, nil
+}
+
+func (c *ConfigDestination) appendRouteAction(route *routeAPI.Route, name string) error {
+ if c.Type.Get() == ConfigDestinationTypeStatic {
+ obj := c.Static.GetResponse()
+
+ if obj == nil {
+ obj = struct{}{}
+ }
+
+ data, err := json.Marshal(obj)
+ if err != nil {
+ return err
+ }
+
+ // Return static response
+ route.Action = &routeAPI.Route_DirectResponse{
+ DirectResponse: &routeAPI.DirectResponseAction{
+ Status: c.Static.GetCode(),
+ Body: &coreAPI.DataSource{
+ Specifier: &coreAPI.DataSource_InlineBytes{
+ InlineBytes: data,
+ },
},
- UpgradeConfigs: c.getUpgradeConfigs().render(),
- PrefixRewrite: c.GetPath(),
},
+ }
+ return nil
+ }
+
+ route.Action = &routeAPI.Route_Route{
+ Route: &routeAPI.RouteAction{
+ ClusterSpecifier: &routeAPI.RouteAction_Cluster{
+ Cluster: name,
+ },
+ UpgradeConfigs: c.getUpgradeConfigs().render(),
+ PrefixRewrite: c.GetPath(),
+ Timeout: durationpb.New(c.GetTimeout()),
},
- TypedPerFilterConfig: tc,
- }, nil
+ }
+ return nil
}
func (c *ConfigDestination) getUpgradeConfigs() ConfigDestinationsUpgrade {
@@ -151,6 +226,10 @@ func (c *ConfigDestination) getUpgradeConfigs() ConfigDestinationsUpgrade {
}
func (c *ConfigDestination) RenderCluster(name string) (*clusterAPI.Cluster, error) {
+ if c.Type.Get() == ConfigDestinationTypeStatic {
+ return nil, nil
+ }
+
hpo, err := anypb.New(c.Protocol.Options())
if err != nil {
return nil, err
diff --git a/pkg/deployment/resources/gateway/gateway_config_destination_static.go b/pkg/deployment/resources/gateway/gateway_config_destination_static.go
new file mode 100644
index 000000000..7979127ec
--- /dev/null
+++ b/pkg/deployment/resources/gateway/gateway_config_destination_static.go
@@ -0,0 +1,51 @@
+//
+// DISCLAIMER
+//
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Copyright holder is ArangoDB GmbH, Cologne, Germany
+//
+
+package gateway
+
+import (
+ "net/http"
+)
+
+type ConfigDestinationStatic struct {
+ Code *uint32 `json:"insecure,omitempty"`
+
+ Response any `json:"response,omitempty"`
+}
+
+func (c *ConfigDestinationStatic) Validate() error {
+ return nil
+}
+
+func (c *ConfigDestinationStatic) GetResponse() any {
+ if c == nil || c.Response == nil {
+ return []byte("{}")
+ }
+
+ return c.Response
+}
+
+func (c *ConfigDestinationStatic) GetCode() uint32 {
+ if c == nil || c.Code == nil {
+ return http.StatusOK
+ }
+
+ return *c.Code
+}
diff --git a/pkg/deployment/resources/gateway/gateway_config_destination_type.go b/pkg/deployment/resources/gateway/gateway_config_destination_type.go
index 4e281900a..ef4638a81 100644
--- a/pkg/deployment/resources/gateway/gateway_config_destination_type.go
+++ b/pkg/deployment/resources/gateway/gateway_config_destination_type.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ type ConfigDestinationType int
const (
ConfigDestinationTypeHTTP ConfigDestinationType = iota
ConfigDestinationTypeHTTPS
+ ConfigDestinationTypeStatic
)
func (c *ConfigDestinationType) Get() ConfigDestinationType {
@@ -42,7 +43,7 @@ func (c *ConfigDestinationType) Get() ConfigDestinationType {
}
switch v := *c; v {
- case ConfigDestinationTypeHTTP, ConfigDestinationTypeHTTPS:
+ case ConfigDestinationTypeHTTP, ConfigDestinationTypeHTTPS, ConfigDestinationTypeStatic:
return v
default:
return ConfigDestinationTypeHTTP
@@ -78,7 +79,7 @@ func (c *ConfigDestinationType) RenderUpstreamTransportSocket(protocol *ConfigDe
func (c *ConfigDestinationType) Validate() error {
switch c.Get() {
- case ConfigDestinationTypeHTTP, ConfigDestinationTypeHTTPS:
+ case ConfigDestinationTypeHTTP, ConfigDestinationTypeHTTPS, ConfigDestinationTypeStatic:
return nil
default:
return errors.Errorf("Invalid destination type")
diff --git a/pkg/deployment/resources/gateway/gateway_config_options.go b/pkg/deployment/resources/gateway/gateway_config_options.go
new file mode 100644
index 000000000..2bade44d0
--- /dev/null
+++ b/pkg/deployment/resources/gateway/gateway_config_options.go
@@ -0,0 +1,37 @@
+//
+// DISCLAIMER
+//
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Copyright holder is ArangoDB GmbH, Cologne, Germany
+//
+
+package gateway
+
+type ConfigOptions struct {
+ MergeSlashes *bool `json:"mergeSlashes,omitempty"`
+}
+
+func (c *ConfigOptions) Validate() error {
+ return nil
+}
+
+func (c *ConfigOptions) GetMergeSlashes() bool {
+ if c == nil || c.MergeSlashes == nil {
+ return true
+ }
+
+ return *c.MergeSlashes
+}
diff --git a/pkg/deployment/resources/gateway/gateway_config_test.go b/pkg/deployment/resources/gateway/gateway_config_test.go
index 05fcfd119..b5a280b8c 100644
--- a/pkg/deployment/resources/gateway/gateway_config_test.go
+++ b/pkg/deployment/resources/gateway/gateway_config_test.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -401,4 +401,66 @@ func Test_GatewayConfig(t *testing.T) {
},
})
})
+
+ t.Run("Default", func(t *testing.T) {
+ renderAndPrintGatewayConfig(t, Config{
+ DefaultDestination: ConfigDestination{
+ Targets: []ConfigDestinationTarget{
+ {
+ Host: "127.0.0.1",
+ Port: 12345,
+ },
+ },
+ Path: util.NewType("/test/path/"),
+ Type: util.NewType(ConfigDestinationTypeHTTPS),
+ },
+ DefaultTLS: &ConfigTLS{
+ CertificatePath: "/test",
+ PrivateKeyPath: "/test12",
+ },
+ SNI: []ConfigSNI{
+ {
+ ConfigTLS: ConfigTLS{
+ CertificatePath: "/cp",
+ PrivateKeyPath: "/pp",
+ },
+ ServerNames: []string{
+ "example.com",
+ },
+ },
+ {
+ ConfigTLS: ConfigTLS{
+ CertificatePath: "/c2",
+ PrivateKeyPath: "/p2",
+ },
+ ServerNames: []string{
+ "2.example.com",
+ },
+ },
+ },
+ Destinations: ConfigDestinations{
+ "/_test/": {
+ Targets: []ConfigDestinationTarget{
+ {
+ Host: "127.0.0.1",
+ Port: 12346,
+ },
+ },
+ Path: util.NewType("/test/path/"),
+ Type: util.NewType(ConfigDestinationTypeHTTP),
+ },
+ "/_test2": {
+ Type: util.NewType(ConfigDestinationTypeStatic),
+ Static: &ConfigDestinationStatic{
+ Code: util.NewType[uint32](302),
+ Response: struct {
+ Data string `json:"data"`
+ }{
+ Data: "TEST",
+ },
+ },
+ },
+ },
+ })
+ })
}
diff --git a/pkg/deployment/resources/pod_creator.go b/pkg/deployment/resources/pod_creator.go
index a80fd48c3..efaef3ef5 100644
--- a/pkg/deployment/resources/pod_creator.go
+++ b/pkg/deployment/resources/pod_creator.go
@@ -290,9 +290,9 @@ func createArangoSyncArgs(apiObject meta.Object, spec api.DeploymentSpec, group
func createArangoGatewayArgs(input pod.Input, additionalOptions ...k8sutil.OptionPair) []string {
options := k8sutil.CreateOptionPairs(64)
if input.Deployment.Gateway.IsDynamic() {
- options.Add("--config-path", path.Join(MemberConfigVolumeMountDir, GatewayDynamicConfigFileName))
+ options.Add("--config-path", path.Join(constants.MemberConfigVolumeMountDir, constants.GatewayConfigFileName))
} else {
- options.Add("--config-path", path.Join(GatewayVolumeMountDir, GatewayConfigFileName))
+ options.Add("--config-path", path.Join(constants.GatewayVolumeMountDir, constants.GatewayConfigFileName))
}
options.Append(additionalOptions...)
diff --git a/pkg/deployment/resources/pod_creator_gateway.go b/pkg/deployment/resources/pod_creator_gateway.go
index 0450b007e..8bcd41b29 100644
--- a/pkg/deployment/resources/pod_creator_gateway.go
+++ b/pkg/deployment/resources/pod_creator_gateway.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,41 +22,48 @@ package resources
import (
"fmt"
+ "strings"
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
-const (
- ArangoGatewayExecutor = "/usr/local/bin/envoy"
- GatewayVolumeMountDir = "/etc/gateway/"
- GatewayVolumeName = "gateway"
- GatewayConfigFileName = "gateway.yaml"
- GatewayDynamicConfigFileName = "gateway.dynamic.yaml"
- GatewayCDSConfigFileName = "gateway.dynamic.cds.yaml"
- GatewayLDSConfigFileName = "gateway.dynamic.lds.yaml"
- GatewayConfigChecksumENV = "GATEWAY_CONFIG_CHECKSUM"
-)
+func GetGatewayConfigMapName(name string, parts ...string) string {
+ if len(parts) == 0 {
+ return fmt.Sprintf("%s-gateway", name)
+ }
-func GetGatewayConfigMapName(name string) string {
- return fmt.Sprintf("%s-gateway", name)
+ return fmt.Sprintf("%s-gateway-%s", name, strings.Join(parts, "-"))
}
func createGatewayVolumes(input pod.Input) pod.Volumes {
volumes := pod.NewVolumes()
- volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(GatewayVolumeName, GetGatewayConfigMapName(input.ApiObject.GetName())))
- volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(MemberConfigVolumeName, input.ArangoMember.GetName()))
+ volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(constants.GatewayVolumeName, GetGatewayConfigMapName(input.ApiObject.GetName())))
+ volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(constants.GatewayCDSVolumeName, GetGatewayConfigMapName(input.ApiObject.GetName(), "cds")))
+ volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(constants.GatewayLDSVolumeName, GetGatewayConfigMapName(input.ApiObject.GetName(), "lds")))
+ volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(constants.MemberConfigVolumeName, input.ArangoMember.GetName()))
+ volumes.AddVolumeMount(core.VolumeMount{
+ Name: constants.GatewayVolumeName,
+ MountPath: constants.GatewayVolumeMountDir,
+ ReadOnly: true,
+ })
+ volumes.AddVolumeMount(core.VolumeMount{
+ Name: constants.GatewayCDSVolumeName,
+ MountPath: constants.GatewayCDSVolumeMountDir,
+ ReadOnly: true,
+ })
volumes.AddVolumeMount(core.VolumeMount{
- Name: GatewayVolumeName,
- MountPath: GatewayVolumeMountDir,
+ Name: constants.GatewayLDSVolumeName,
+ MountPath: constants.GatewayLDSVolumeMountDir,
ReadOnly: true,
})
volumes.AddVolumeMount(core.VolumeMount{
- Name: MemberConfigVolumeName,
- MountPath: MemberConfigVolumeMountDir,
+ Name: constants.MemberConfigVolumeName,
+ MountPath: constants.MemberConfigVolumeMountDir,
ReadOnly: true,
})
diff --git a/pkg/deployment/resources/pod_creator_gateway_container.go b/pkg/deployment/resources/pod_creator_gateway_container.go
index cfbd6bc6c..4d893e4ee 100644
--- a/pkg/deployment/resources/pod_creator_gateway_container.go
+++ b/pkg/deployment/resources/pod_creator_gateway_container.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/interfaces"
kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
@@ -70,7 +71,7 @@ func (a *ArangoGatewayContainer) GetPorts() []core.ContainerPort {
}
func (a *ArangoGatewayContainer) GetExecutor() string {
- return a.groupSpec.GetEntrypoint(ArangoGatewayExecutor)
+ return a.groupSpec.GetEntrypoint(constants.ArangoGatewayExecutor)
}
func (a *ArangoGatewayContainer) GetSecurityContext() *core.SecurityContext {
@@ -133,9 +134,9 @@ func (a *ArangoGatewayContainer) GetEnvs() ([]core.EnvVar, []core.EnvFromSource)
if !a.spec.Gateway.IsDynamic() {
if cm, ok := a.cachedStatus.ConfigMap().V1().GetSimple(GetGatewayConfigMapName(a.input.ApiObject.GetName())); ok {
- if v, ok := cm.Data[ConfigMapChecksumKey]; ok {
+ if v, ok := cm.Data[constants.ConfigMapChecksumKey]; ok {
envs.Add(true, core.EnvVar{
- Name: GatewayConfigChecksumENV,
+ Name: constants.GatewayConfigChecksumENV,
Value: v,
})
}
diff --git a/pkg/handlers/networking/route/handler_destination_endpoints.go b/pkg/handlers/networking/route/handler_destination_endpoints.go
index 9d7f469e1..c4a94fffb 100644
--- a/pkg/handlers/networking/route/handler_destination_endpoints.go
+++ b/pkg/handlers/networking/route/handler_destination_endpoints.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -119,6 +119,7 @@ func (h *handler) HandleArangoDestinationEndpoints(ctx context.Context, item ope
var target networkingApi.ArangoRouteStatusTarget
target.Path = dest.GetPath()
+ target.Timeout = dest.GetTimeout()
target.Type = networkingApi.ArangoRouteStatusTargetEndpointsType
target.Protocol = dest.GetProtocol().Get()
diff --git a/pkg/handlers/networking/route/handler_destination_service.go b/pkg/handlers/networking/route/handler_destination_service.go
index 175917e3b..5ccb1a3b3 100644
--- a/pkg/handlers/networking/route/handler_destination_service.go
+++ b/pkg/handlers/networking/route/handler_destination_service.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -118,6 +118,7 @@ func (h *handler) HandleArangoDestinationService(ctx context.Context, item opera
var target networkingApi.ArangoRouteStatusTarget
target.Path = dest.GetPath()
+ target.Timeout = dest.GetTimeout()
target.Type = networkingApi.ArangoRouteStatusTargetServiceType
target.Protocol = dest.GetProtocol().Get()
diff --git a/pkg/deployment/resources/gateway/consts.go b/pkg/platform/state.go
similarity index 73%
rename from pkg/deployment/resources/gateway/consts.go
rename to pkg/platform/state.go
index a624495df..57417f28c 100644
--- a/pkg/deployment/resources/gateway/consts.go
+++ b/pkg/platform/state.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2024 ArangoDB GmbH, Cologne, Germany
+// Copyright 2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,8 +18,12 @@
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
-package gateway
+package platform
-const (
- IntegrationSidecarFilterName = "envoy.filters.http.ext_authz"
-)
+type State struct {
+ Configuration StateConfiguration `json:"configuration,omitempty"`
+}
+
+type StateConfiguration struct {
+ Hash string `json:"hash,omitempty"`
+}
diff --git a/pkg/util/constants/envoy.go b/pkg/util/constants/envoy.go
new file mode 100644
index 000000000..b25e9b0c0
--- /dev/null
+++ b/pkg/util/constants/envoy.go
@@ -0,0 +1,33 @@
+//
+// DISCLAIMER
+//
+// Copyright 2025 ArangoDB GmbH, Cologne, Germany
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Copyright holder is ArangoDB GmbH, Cologne, Germany
+//
+
+package constants
+
+import "time"
+
+const (
+ EnvoyRouteHeader = "arangodb-platform-route"
+
+ EnvoyInventoryConfigDestination = "/_inventory"
+
+ EnvoyIntegrationSidecarFilterName = "envoy.filters.http.ext_authz"
+
+ DefaultEnvoyUpstreamTimeout = time.Minute
+)
diff --git a/pkg/util/constants/gateway.go b/pkg/util/constants/gateway.go
new file mode 100644
index 000000000..2b4408030
--- /dev/null
+++ b/pkg/util/constants/gateway.go
@@ -0,0 +1,47 @@
+//
+// DISCLAIMER
+//
+// Copyright 2025 ArangoDB GmbH, Cologne, Germany
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Copyright holder is ArangoDB GmbH, Cologne, Germany
+//
+
+package constants
+
+import "time"
+
+const (
+ MaxGatewayTimeout = 15 * time.Minute
+ MinGatewayTimeout = 15 * time.Second
+
+ ConfigMapChecksumKey = "CHECKSUM"
+
+ ArangoGatewayExecutor = "/usr/local/bin/envoy"
+
+ GatewayConfigFileName = "gateway.yaml"
+ GatewayConfigChecksumENV = "GATEWAY_CONFIG_CHECKSUM"
+
+ GatewayVolumeMountDir = "/etc/gateway/core/"
+ GatewayVolumeName = "gateway"
+
+ GatewayLDSVolumeMountDir = "/etc/gateway/lds/"
+ GatewayLDSVolumeName = "gateway-lds"
+
+ GatewayCDSVolumeMountDir = "/etc/gateway/cds/"
+ GatewayCDSVolumeName = "gateway-cds"
+
+ MemberConfigVolumeMountDir = "/etc/gateway/member/"
+ MemberConfigVolumeName = "member-config"
+)