From 5fbe9d2ce09eb2fc1f3223d634ec3feda88a1ce3 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:35:05 +0000 Subject: [PATCH 1/4] [Feature] [Platform] Gateway UpToDate Condition --- CHANGELOG.md | 1 + pkg/deployment/deployment_inspector.go | 6 ++ pkg/deployment/member/phase_updates.go | 1 + .../reconcile/plan_builder_gateway.go | 62 ++++++++++++++++++- pkg/deployment/reconcile/plan_builder_high.go | 1 + .../resources/config_map_gateway.go | 3 + pkg/util/constants/gateway.go | 1 + 7 files changed, 73 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d87200d9..c458da3bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/pkg/deployment/deployment_inspector.go b/pkg/deployment/deployment_inspector.go index 28fe9bf95..fa057ee30 100644 --- a/pkg/deployment/deployment_inspector.go +++ b/pkg/deployment/deployment_inspector.go @@ -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) { diff --git a/pkg/deployment/member/phase_updates.go b/pkg/deployment/member/phase_updates.go index 96573bdf6..c6c9af381 100644 --- a/pkg/deployment/member/phase_updates.go +++ b/pkg/deployment/member/phase_updates.go @@ -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)) diff --git a/pkg/deployment/reconcile/plan_builder_gateway.go b/pkg/deployment/reconcile/plan_builder_gateway.go index f4f3edccf..a69a403a2 100644 --- a/pkg/deployment/reconcile/plan_builder_gateway.go +++ b/pkg/deployment/reconcile/plan_builder_gateway.go @@ -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" ) @@ -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)) } @@ -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)) + } + 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)) + } + 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 { diff --git a/pkg/deployment/reconcile/plan_builder_high.go b/pkg/deployment/reconcile/plan_builder_high.go index 67ba5b839..fedebf34c 100644 --- a/pkg/deployment/reconcile/plan_builder_high.go +++ b/pkg/deployment/reconcile/plan_builder_high.go @@ -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). diff --git a/pkg/deployment/resources/config_map_gateway.go b/pkg/deployment/resources/config_map_gateway.go index b33266adb..de721a0b1 100644 --- a/pkg/deployment/resources/config_map_gateway.go +++ b/pkg/deployment/resources/config_map_gateway.go @@ -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 } diff --git a/pkg/util/constants/gateway.go b/pkg/util/constants/gateway.go index 35e2fc309..73b235642 100644 --- a/pkg/util/constants/gateway.go +++ b/pkg/util/constants/gateway.go @@ -33,6 +33,7 @@ const ( ArangoGatewayExecutor = "/usr/local/bin/envoy" + GatewayConfigChecksum = "gateway.checksum" GatewayConfigFileName = "gateway.yaml" GatewayConfigChecksumENV = "GATEWAY_CONFIG_CHECKSUM" From ed8bd35e9fb4398d4f06ca9513af8f3a55ed0293 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:30:21 +0000 Subject: [PATCH 2/4] Fix UT --- pkg/util/k8sutil/helm/chart_manager_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/util/k8sutil/helm/chart_manager_test.go b/pkg/util/k8sutil/helm/chart_manager_test.go index 4eba05dc0..b028b9780 100644 --- a/pkg/util/k8sutil/helm/chart_manager_test.go +++ b/pkg/util/k8sutil/helm/chart_manager_test.go @@ -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") From 5fb390607f4859ae4183741762754aad0fb2787f Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Wed, 17 Sep 2025 09:47:22 +0000 Subject: [PATCH 3/4] Fix condition check --- pkg/deployment/deployment_inspector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/deployment/deployment_inspector.go b/pkg/deployment/deployment_inspector.go index fa057ee30..d1370ebbc 100644 --- a/pkg/deployment/deployment_inspector.go +++ b/pkg/deployment/deployment_inspector.go @@ -486,7 +486,7 @@ func (d *Deployment) isUpToDateStatus(mode api.DeploymentMode, status api.Deploy return } - if !status.Conditions.Check(api.ConditionTypeGatewayConfig).Exists().IsTrue().Evaluate() { + if v, ok := status.Conditions.Get(api.ConditionTypeGatewayConfig); ok && !v.IsTrue() { upToDate = false reason = "Gateway is not propagated" return From 98f8dee7a0998e09bd1b13057686ef5ec8832102 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:53:15 +0000 Subject: [PATCH 4/4] Fix condition check --- pkg/deployment/reconcile/plan_builder_gateway.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/deployment/reconcile/plan_builder_gateway.go b/pkg/deployment/reconcile/plan_builder_gateway.go index a69a403a2..8510e2bec 100644 --- a/pkg/deployment/reconcile/plan_builder_gateway.go +++ b/pkg/deployment/reconcile/plan_builder_gateway.go @@ -91,16 +91,12 @@ func (r *Reconciler) createGatewayConfigConditionPlan(ctx context.Context, _ k8s 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)) - } + plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config UpToDate", api.ConditionTypeGatewayConfig, true, "Gateway Config Propagated", "Gateway Config Propagated", checksum)) 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)) - } + plan = append(plan, sharedReconcile.UpdateConditionActionV2("Gateway Config Not UpToDate", api.ConditionTypeGatewayConfig, false, "Gateway Config Not Propagated", "Gateway Config Not Propagated", checksum)) return plan } }