Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- (Feature) Improve GRPC JSON Handling
- (Bugfix) Fix Operator Pod Resources
- (Feature) (Platform) MetaV1 Integration Tests
- (Feature) (Platform) Gateway UpToDate Condition

## [1.3.0](https://github.com/arangodb/kube-arangodb/tree/1.3.0) (2025-08-01)
- (Feature) (Platform) Storage Debug
Expand Down
6 changes: 6 additions & 0 deletions pkg/deployment/deployment_inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ func (d *Deployment) isUpToDateStatus(mode api.DeploymentMode, status api.Deploy
return
}

if !status.Conditions.Check(api.ConditionTypeGatewayConfig).Exists().IsTrue().Evaluate() {
upToDate = false
reason = "Gateway is not propagated"
return
}

for _, m := range status.Members.AsList() {
member := m.Member
if member.Conditions.IsTrue(api.ConditionTypeRestart) || member.Conditions.IsTrue(api.ConditionTypePendingRestart) {
Expand Down
1 change: 1 addition & 0 deletions pkg/deployment/member/phase_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func removeMemberConditionsMapFunc(m *api.MemberStatus) {
m.Conditions.Remove(api.ConditionTypeArchitectureMismatch)
m.Conditions.Remove(api.ConditionTypeArchitectureChangeCannotBeApplied)
m.Conditions.Remove(api.ConditionTypeMemberVolumeUnschedulable)
m.Conditions.Remove(api.ConditionTypeGatewayConfig)

m.RemoveTerminationsBefore(time.Now().Add(-1 * utilConstants.RecentTerminationsKeepPeriod))

Expand Down
62 changes: 60 additions & 2 deletions pkg/deployment/reconcile/plan_builder_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
client "github.com/arangodb/kube-arangodb/pkg/deployment/client"
sharedReconcile "github.com/arangodb/kube-arangodb/pkg/deployment/reconcile/shared"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
utilConstants "github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)

Expand All @@ -47,8 +49,6 @@ func (r *Reconciler) createMemberGatewayConfigConditionPlan(ctx context.Context,
continue
}

logger.JSON("inv", inv).Info("Inventory Fetched")

if c, ok := m.Member.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionFalse || c.Hash != inv.Configuration.Hash {
plan = append(plan, sharedReconcile.UpdateMemberConditionActionV2("Config Present", api.ConditionTypeGatewayConfig, m.Group, m.Member.ID, true, "Config Present", "Config Present", inv.Configuration.Hash))
}
Expand All @@ -57,6 +57,64 @@ func (r *Reconciler) createMemberGatewayConfigConditionPlan(ctx context.Context,
return plan
}

func (r *Reconciler) createGatewayConfigConditionPlan(ctx context.Context, _ k8sutil.APIObject, spec api.DeploymentSpec,
status api.DeploymentStatus, planCtx PlanBuilderContext) api.Plan {
var plan api.Plan

if spec.Gateway.IsEnabled() {
cm, exists := planCtx.ACS().CurrentClusterCache().ConfigMap().V1().GetSimple(resources.GetGatewayConfigMapName(r.context.GetAPIObject().GetName()))
if !exists {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway CM Missing", api.ConditionTypeGatewayConfig, false, "Gateway CM Missing", "Gateway CM Missing", ""))
}
return plan
}

if cm == nil || cm.Data[utilConstants.GatewayConfigChecksum] == "" {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway CM Missing", api.ConditionTypeGatewayConfig, false, "Gateway CM Missing", "Gateway CM Missing", ""))
}
return plan
}

checksum := cm.Data[utilConstants.GatewayConfigChecksum]

cok := true
for _, m := range status.Members.AsListInGroup(api.ServerGroupGateways) {
if v, ok := m.Member.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || v.Status != core.ConditionTrue || v.Hash != checksum {
cok = false
}
if !cok {
break
}
}

if cok {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionFalse || c.Hash != checksum {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config UpToDate", api.ConditionTypeGatewayConfig, true, "Gateway Config Propagated", "Gateway Config Propagated", checksum))
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition check is duplicated from line 93 and creates unreachable code. The outer condition already ensures the same state, making this inner check redundant and the code block unreachable.

Suggested change
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config UpToDate", api.ConditionTypeGatewayConfig, true, "Gateway Config Propagated", "Gateway Config Propagated", checksum))
}
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config UpToDate", api.ConditionTypeGatewayConfig, true, "Gateway Config Propagated", "Gateway Config Propagated", checksum))

Copilot uses AI. Check for mistakes.
return plan
}
} else {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != checksum {
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config Not UpToDate", api.ConditionTypeGatewayConfig, false, "Gateway Config Not Propagated", "Gateway Config Not Propagated", checksum))
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition check is duplicated from line 100 and creates unreachable code. The outer condition already ensures the same state, making this inner check redundant and the code block unreachable.

Suggested change
if c, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); !ok || c.Status == core.ConditionTrue || c.Hash != "" {
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config Not UpToDate", api.ConditionTypeGatewayConfig, false, "Gateway Config Not Propagated", "Gateway Config Not Propagated", checksum))
}
plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config Not UpToDate", api.ConditionTypeGatewayConfig, false, "Gateway Config Not Propagated", "Gateway Config Not Propagated", checksum))

Copilot uses AI. Check for mistakes.
return plan
}
}

} else {
if _, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); ok {
plan = append(plan, sharedReconcile.RemoveConditionActionV2("Gateways Disabled", api.ConditionTypeGatewayConfig))
return plan
}
}

return plan
}

func (r *Reconciler) getGatewayInventoryConfig(ctx context.Context, planCtx PlanBuilderContext, group api.ServerGroup, member api.MemberStatus) (*client.Inventory, error) {
serverClient, err := planCtx.GetServerClient(ctx, group, member.ID)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/deployment/reconcile/plan_builder_high.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIOb
ApplyIfEmpty(r.updateMemberRotationConditionsPlan).
ApplyIfEmpty(r.createMemberAllowUpgradeConditionPlan).
ApplyIfEmpty(r.createMemberGatewayConfigConditionPlan).
ApplyIfEmpty(r.createGatewayConfigConditionPlan).
ApplyIfEmpty(r.createMemberRecreationConditionsPlan).
ApplyIfEmpty(r.createMemberPodSchedulingFailurePlan).
ApplyIfEmpty(r.createRotateServerStoragePVCPendingResizeConditionPlan).
Expand Down
3 changes: 3 additions & 0 deletions pkg/deployment/resources/config_map_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,21 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec

if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName()), map[string]string{
utilConstants.GatewayConfigFileName: string(gatewayCfgYaml),
utilConstants.GatewayConfigChecksum: baseGatewayCfgYamlChecksum,
}); err != nil {
return err
}

if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName(), "cds"), map[string]string{
utilConstants.GatewayConfigFileName: string(gatewayCfgCDSYaml),
utilConstants.GatewayConfigChecksum: baseGatewayCfgYamlChecksum,
}); err != nil {
return err
}

if err := r.ensureGatewayConfigMap(ctx, cachedStatus, configMaps, GetGatewayConfigMapName(r.context.GetAPIObject().GetName(), "lds"), map[string]string{
utilConstants.GatewayConfigFileName: string(gatewayCfgLDSYaml),
utilConstants.GatewayConfigChecksum: baseGatewayCfgYamlChecksum,
}); err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/util/constants/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (

ArangoGatewayExecutor = "/usr/local/bin/envoy"

GatewayConfigChecksum = "gateway.checksum"
GatewayConfigFileName = "gateway.yaml"
GatewayConfigChecksumENV = "GATEWAY_CONFIG_CHECKSUM"

Expand Down
4 changes: 3 additions & 1 deletion pkg/util/k8sutil/helm/chart_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ func Test_Manager_Tag(t *testing.T) {
mgr, err := NewChartManager(context.Background(), nil, "https://arangodb-platform-dev-chart-registry.s3.amazonaws.com/index.yaml")
require.NoError(t, err)

repo, ok := mgr.Get("platform_test_example")
require.True(t, len(mgr.Repositories()) > 0)

repo, ok := mgr.Get(mgr.Repositories()[0])
require.True(t, ok)

repo.GetByTag("dev")
Expand Down