mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-04 02:57:27 +09:00
Add first-class fields so a package/app can declare the Flux helm-controller v1.5.0 kstatus health gate for the custom resource it wraps, so HelmRelease.Ready means "the CR is actually healthy" instead of "helm applied the CR" (#2642). API-owner approved in #3263. - api: WaitStrategy (scalar, maps to HelmReleaseSpec.WaitStrategy.Name — a deliberate simplification) + HealthCheckExprs ([]kustomize.CustomHealthCheck, the upstream type verbatim) on both ApplicationDefinition.spec.release (the apiserver path) and ComponentInstall (the operator path). - config.ResolveWaitStrategy: shared by both HelmRelease builders. Couples the default — healthCheckExprs imply the poller strategy when none is set, since exprs are only evaluated under poller. This removes the "must also set waitStrategy: poller" footgun and does not depend on the controller's global default. - thread through buildHelmReleaseSpec (operator) and convertApplicationToHelmRelease (apiserver); the apiserver loads the typed spec.release fields in start.go. - regenerate deepcopy, the ApplicationDefinition and PackageSource CRDs, and openapi. The backupstrategy CRDs also regenerate — benign k8s-0.35 PodSpec description drift, not a functional change. disableWait is intentionally not added (YAGNI): the only known need (the kubernetes tenant-addon deadlock) was resolved child-side, and waitStrategy: legacy is not equivalent (legacy still waits Helm-v3-style; disableWait skips waiting entirely). Add it later when a concrete leaf needs a true no-gate escape hatch. Refs #2642 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
89 lines
2.6 KiB
Go
89 lines
2.6 KiB
Go
/*
|
|
Copyright 2026 The Cozystack Authors.
|
|
|
|
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.
|
|
*/
|
|
|
|
package config
|
|
|
|
import (
|
|
"testing"
|
|
|
|
helmv2 "github.com/fluxcd/helm-controller/api/v2"
|
|
)
|
|
|
|
// ResolveWaitStrategy is the single source of truth for the wait-strategy value
|
|
// on both HelmRelease-generating paths (cozystack-api and cozystack-operator).
|
|
// The couple-the-default behavior (expressions imply poller) is what makes a
|
|
// package that sets only healthCheckExprs self-contained, so it is the part
|
|
// worth pinning against regression.
|
|
func TestResolveWaitStrategy(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
waitStrategy string
|
|
hasExprs bool
|
|
want *helmv2.WaitStrategyName // nil => expect nil *WaitStrategy
|
|
}{
|
|
{
|
|
name: "unset, no exprs -> nil (leave flux default)",
|
|
waitStrategy: "",
|
|
hasExprs: false,
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "unset, with exprs -> poller (coupled default)",
|
|
waitStrategy: "",
|
|
hasExprs: true,
|
|
want: ptr(helmv2.WaitStrategyPoller),
|
|
},
|
|
{
|
|
name: "explicit poller is honored",
|
|
waitStrategy: "poller",
|
|
hasExprs: true,
|
|
want: ptr(helmv2.WaitStrategyPoller),
|
|
},
|
|
{
|
|
name: "explicit legacy is honored even with exprs",
|
|
waitStrategy: "legacy",
|
|
hasExprs: true,
|
|
want: ptr(helmv2.WaitStrategyLegacy),
|
|
},
|
|
{
|
|
name: "explicit legacy without exprs is honored",
|
|
waitStrategy: "legacy",
|
|
hasExprs: false,
|
|
want: ptr(helmv2.WaitStrategyLegacy),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := ResolveWaitStrategy(tc.waitStrategy, tc.hasExprs)
|
|
if tc.want == nil {
|
|
if got != nil {
|
|
t.Fatalf("ResolveWaitStrategy(%q, %v) = %+v, want nil", tc.waitStrategy, tc.hasExprs, got)
|
|
}
|
|
return
|
|
}
|
|
if got == nil {
|
|
t.Fatalf("ResolveWaitStrategy(%q, %v) = nil, want %q", tc.waitStrategy, tc.hasExprs, *tc.want)
|
|
}
|
|
if got.Name != *tc.want {
|
|
t.Errorf("ResolveWaitStrategy(%q, %v).Name = %q, want %q", tc.waitStrategy, tc.hasExprs, got.Name, *tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func ptr(n helmv2.WaitStrategyName) *helmv2.WaitStrategyName { return &n }
|