mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-09 14:02:56 +09:00
test(sdn): drop the serviceexposure chainsaw suite left after the feature removal (#3336)
## What this PR does Removes the dead `serviceexposure` chainsaw suite and its wiring. Commit3dbc7d366dropped ExposureClass/ServiceExposure (api/network, the controller, and the `network.cozystack.io` CRDs shipped in `cozystack-controller/definitions`) in favor of the native LoadBalancer path, but the chainsaw port that landed the next day (dd2f89d20) brought the suite along, so it tests an API that no longer exists. Since then every full-suite E2E run — any PR touching core paths, and every release cut — fails `serviceexposure-delete` and `serviceexposure-externalips` with `no matches for network.cozystack.io/v1alpha1` (see the crust-gather snapshot of e.g. run 29561399440 on #3333: the network CRDs are absent while sibling CRDs from the same `definitions/` dir, like `tenantgateways.gateway.cozystack.io`, are present, confirming the chart applied and the API is simply gone). Alongside the suite dir this drops the `suite_to_source` case and its core-platform bats test in `hack/select-install*`, the now-unreachable `-` mapping mechanism itself (no suite returns it anymore and its only executable coverage was the removed bats test; re-adding the three lines with the next core-platform-owned suite is cheaper than keeping an untestable dead branch), and the suite list entry in `hack/e2e-chainsaw/README.md`. The `securitygroup` suite from the same port is alive and green and is untouched. If the native LoadBalancer replacement needs E2E coverage, that is a new suite against the new API, not a revival of this one. Verified: `hack/select-install.sh --validate` passes (97 sources), `select-install_test.bats` 17/17, `select-e2e_test.bats` 13/13. ## Release note ```release-note NONE ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Tightened installation suite-to-PackageSource validation: `serviceexposure` no longer has special handling, and mappings to `-` are now treated as invalid unless the referenced PackageSource exists. * **Tests** * Removed Chainsaw E2E fixture coverage and manifests for `serviceexposure`, and updated the listed E2E suites accordingly. * Updated installation mapping tests to match the stricter validation and added a negative validation case for a missing mapped PackageSource. * **Documentation** * Updated contributing guidance to reference the `networking.publishing.externalIPs` → `publishing.loadBalancerClass` migration. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
6 files changed
+31
-178
No files matched your search
@@ -195,7 +195,7 @@ The provider is hand-written: every Kind carries a hand-maintained Terraform sch
|
||||
- Add a required key to `packages/core/installer/values.yaml`, or rename one the role passes (`cozystackOperator.variant`, `cozystack.apiServerHost`, `cozystack.apiServerPort`) → the chart values block in the role's `main.yml` task, and its `defaults/main.yml`.
|
||||
- Change the `cozy-system` namespace or the PSA pre-install hook contract → the role carries namespace-adoption logic written against the current behaviour of `packages/core/installer/templates/`.
|
||||
- Add or rename a platform variant → the variant list is hardcoded in Go, in `cmd/cozystack-operator/main.go`; over there it is `cozystack_platform_variant` in `defaults/main.yml` and the README table.
|
||||
- Change a `packages/core/platform/values.yaml` key the role sets — `networking.podCIDR`, `networking.podGateway`, `networking.serviceCIDR`, `networking.joinCIDR`, `publishing.host`, `publishing.apiServerEndpoint`, `publishing.externalIPs` → the role's platform-package template. The `externalIPs` to `exposureClass` migration in particular needs a coordinated PR there.
|
||||
- Change a `packages/core/platform/values.yaml` key the role sets — `networking.podCIDR`, `networking.podGateway`, `networking.serviceCIDR`, `networking.joinCIDR`, `publishing.host`, `publishing.apiServerEndpoint`, `publishing.externalIPs` → the role's platform-package template. The `externalIPs` to `publishing.loadBalancerClass` migration in particular needs a coordinated PR there.
|
||||
- Rename an object the role waits on — `deployment/cozystack-operator`, `crd/packages.cozystack.io`, the root `Tenant` — or change the `<packagesource>.<package>` naming scheme of the Package it applies → the role's tasks and its own CI assertions.
|
||||
- Change node prerequisites in `hack/e2e-prepare-cluster.bats` — the kernel modules a node must load, the containerd settings, the LVM `global_filter` → those are mirrored by hand into that repo's `examples/ubuntu`, `examples/rhel` and `examples/suse` prepare playbooks. Its CI tests some of them, but never against this repo, so a kernel module added here and not there surfaces as a broken storage layer on a generic cluster.
|
||||
- Change what Cozystack requires from the Kubernetes distribution (CNI, kube-proxy, cluster domain, max pods) → the k3s flags, which live only in that repo's inventories.
|
||||
|
||||
@@ -18,7 +18,7 @@ hack/e2e-chainsaw/
|
||||
└── ...
|
||||
```
|
||||
|
||||
Suites: `postgres`, `bucket`, `mariadb`, `mongodb`, `redis`, `qdrant`, `clickhouse`, `kafka`, `etcd`, `openbao`, `harbor`, `foundationdb`, `external-dns`, `kuberture`, `vminstance`, `gateway`, `kubernetes-latest`, `kubernetes-previous`, `kubernetes-oidc-system`, `kubernetes-oidc-customconfig`, `securitygroup`, `serviceexposure`.
|
||||
Suites: `postgres`, `bucket`, `mariadb`, `mongodb`, `redis`, `qdrant`, `clickhouse`, `kafka`, `etcd`, `openbao`, `harbor`, `foundationdb`, `external-dns`, `kuberture`, `vminstance`, `gateway`, `kubernetes-latest`, `kubernetes-previous`, `kubernetes-oidc-system`, `kubernetes-oidc-customconfig`, `securitygroup`.
|
||||
|
||||
## What Chainsaw buys over the BATS suite
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
# Chainsaw port of hack/e2e-apps/serviceexposure.bats.
|
||||
#
|
||||
# Smoke test for the ServiceExposure controller (network.cozystack.io): the
|
||||
# CRDs are installed, the controller resolves a ServiceExposure to its
|
||||
# ExposureClass, renders NO foreign backend CRs for the externalIPs backend,
|
||||
# and reports status. See serviceexposure.yaml for why externalIPs.
|
||||
#
|
||||
# Both Tests reuse the same fixture names — safe under the global
|
||||
# execution.parallel: 1 (the first Test's auto-cleanup completes before the
|
||||
# second starts).
|
||||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: serviceexposure-externalips
|
||||
spec:
|
||||
catch:
|
||||
- events: {}
|
||||
- describe:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
name: se-e2e
|
||||
- get:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ExposureClass
|
||||
name: se-e2e-externalips
|
||||
- podLogs:
|
||||
namespace: cozy-system
|
||||
selector: app=cozystack-controller
|
||||
tail: 100
|
||||
steps:
|
||||
- name: create-fixtures
|
||||
try:
|
||||
- apply:
|
||||
file: serviceexposure.yaml
|
||||
|
||||
- name: resolved-backend
|
||||
try:
|
||||
# The controller stamps status.resolvedBackend once it has reconciled.
|
||||
- assert:
|
||||
timeout: 2m
|
||||
resource:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
metadata:
|
||||
name: se-e2e
|
||||
status:
|
||||
resolvedBackend: externalIPs
|
||||
|
||||
- name: no-backend-pool
|
||||
try:
|
||||
# externalIPs backend must not create a MetalLB pool
|
||||
# (backend.PoolName = cozystack-<class>). resolvedBackend above already
|
||||
# proved the reconcile ran, so a short non-existence poll is race-free —
|
||||
# same ordering as the bats.
|
||||
- error:
|
||||
timeout: 30s
|
||||
resource:
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: IPAddressPool
|
||||
metadata:
|
||||
name: cozystack-se-e2e-externalips
|
||||
namespace: cozy-metallb
|
||||
|
||||
- name: ready-and-assigned-ips
|
||||
try:
|
||||
# The pinned externalIPs make the exposure Ready.
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
metadata:
|
||||
name: se-e2e
|
||||
status:
|
||||
(conditions[?type == 'Ready']):
|
||||
- status: "True"
|
||||
(assignedIPs[0]): 203.0.113.10
|
||||
---
|
||||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: serviceexposure-delete
|
||||
spec:
|
||||
catch:
|
||||
- events: {}
|
||||
- describe:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
name: se-e2e
|
||||
- podLogs:
|
||||
namespace: cozy-system
|
||||
selector: app=cozystack-controller
|
||||
tail: 100
|
||||
steps:
|
||||
- name: create-fixtures
|
||||
try:
|
||||
- apply:
|
||||
file: serviceexposure.yaml
|
||||
- assert:
|
||||
timeout: 2m
|
||||
resource:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
metadata:
|
||||
name: se-e2e
|
||||
status:
|
||||
resolvedBackend: externalIPs
|
||||
|
||||
- name: delete-completes-despite-finalizer
|
||||
try:
|
||||
# Deletion must complete despite the cleanup finalizer (nothing to GC for
|
||||
# the externalIPs backend, so the finalizer is removed promptly). The
|
||||
# chainsaw delete op waits for the object to be fully gone — the delete
|
||||
# IS the test. 3m covers the bats' 2m delete + 1m wait-for-delete.
|
||||
- delete:
|
||||
timeout: 3m
|
||||
ref:
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
name: se-e2e
|
||||
@@ -1,37 +0,0 @@
|
||||
# The externalIPs path is chosen deliberately so the test creates no
|
||||
# MetalLB/Cilium pool — it cannot collide with the cluster's existing
|
||||
# LoadBalancer address pools or depend on real L2 reachability
|
||||
# (203.0.113.10 is TEST-NET-3), keeping it deterministic. The metallb and
|
||||
# cilium rendering paths (pool + announcer CRs, garbage collection, take-over
|
||||
# guard) are covered exhaustively by the Go unit tests in
|
||||
# internal/controller/serviceexposure.
|
||||
#
|
||||
# The ExposureClass is cluster-scoped; Chainsaw tracks cluster-scoped applies
|
||||
# too, so auto-cleanup reclaims all three objects in reverse apply order.
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ExposureClass
|
||||
metadata:
|
||||
name: se-e2e-externalips
|
||||
spec:
|
||||
backend: externalIPs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: se-e2e-svc
|
||||
spec:
|
||||
type: ClusterIP
|
||||
externalIPs:
|
||||
- 203.0.113.10
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
apiVersion: network.cozystack.io/v1alpha1
|
||||
kind: ServiceExposure
|
||||
metadata:
|
||||
name: se-e2e
|
||||
spec:
|
||||
serviceRef:
|
||||
name: se-e2e-svc
|
||||
exposureClassName: se-e2e-externalips
|
||||
+4
-11
@@ -24,7 +24,7 @@
|
||||
# --validate: check the whole graph AND the suite mapping — every dependsOn
|
||||
# target resolves to a real PackageSource, there are no dependency cycles, and
|
||||
# every Chainsaw suite under <suites-dir> resolves via suite_to_source() to a
|
||||
# real PackageSource or to "-". Exit non-zero on any failure. The graph lives
|
||||
# real PackageSource. Exit non-zero on any failure. The graph lives
|
||||
# next to the packages and cannot drift from the suite directories; the
|
||||
# hand-maintained suite mapping is the only part that can, so it is guarded here.
|
||||
#
|
||||
@@ -59,11 +59,6 @@ fi
|
||||
|
||||
# suite name -> owning PackageSource. Prints:
|
||||
# - a "cozystack.*" name the suite's primary install target
|
||||
# - "-" the suite targets a core-platform feature that
|
||||
# has no separately-enabled package (always
|
||||
# present via the base install), e.g.
|
||||
# serviceexposure (ExposureClass/ServiceExposure
|
||||
# live in packages/core/platform)
|
||||
# - nothing no mapping is known (caller fails closed)
|
||||
# Most suites follow the <suite>-application convention; a bare-<suite> fallback
|
||||
# and the explicit cases cover suites whose source is named differently. Kept in
|
||||
@@ -82,7 +77,6 @@ suite_to_source() {
|
||||
echo cozystack.kubernetes-application ; return ;;
|
||||
vminstance) echo cozystack.vm-instance-application ; return ;;
|
||||
securitygroup) echo cozystack.securitygroup-controller ; return ;;
|
||||
serviceexposure) echo - ; return ;;
|
||||
esac
|
||||
for cand in "cozystack.$1-application" "cozystack.$1"; do
|
||||
if echo "$NODES" | grep -Fxq "$cand"; then echo "$cand"; return; fi
|
||||
@@ -149,8 +143,8 @@ if [ "$MODE" = "validate" ]; then
|
||||
done
|
||||
done
|
||||
|
||||
# 3. Suite mapping: every Chainsaw suite dir must resolve to a real source or
|
||||
# "-". The suite universe is auto-discovered while suite_to_source() is
|
||||
# 3. Suite mapping: every Chainsaw suite dir must resolve to a real source.
|
||||
# The suite universe is auto-discovered while suite_to_source() is
|
||||
# hand-maintained, so this is the part that actually drifts. A missing
|
||||
# suites dir is itself a failure — otherwise a moved/misspelled path would
|
||||
# make discovery yield nothing and silently pass this whole check.
|
||||
@@ -163,7 +157,7 @@ if [ "$MODE" = "validate" ]; then
|
||||
if [ -z "$src" ]; then
|
||||
echo "select-install: suite '$suite' has no PackageSource mapping (add it to suite_to_source)" >&2
|
||||
rc=1
|
||||
elif [ "$src" != "-" ] && ! echo "$NODES" | grep -Fxq "$src"; then
|
||||
elif ! echo "$NODES" | grep -Fxq "$src"; then
|
||||
echo "select-install: suite '$suite' maps to '$src', not a PackageSource in $SOURCES_DIR" >&2
|
||||
rc=1
|
||||
fi
|
||||
@@ -181,7 +175,6 @@ for suite in $SUITES; do
|
||||
[ -z "$suite" ] && continue
|
||||
src="$(suite_to_source "$suite")"
|
||||
case "$src" in
|
||||
"-") continue ;; # core-platform feature — nothing separate to enable
|
||||
"")
|
||||
# Fail closed: a suite that maps to nothing must abort, not silently emit
|
||||
# an empty set. Collect every bad suite so one run reports them all.
|
||||
|
||||
@@ -101,14 +101,6 @@
|
||||
echo "$output" | grep -wq cozystack.gateway-api-crds
|
||||
}
|
||||
|
||||
@test "core-platform suite contributes no package and emits no warning" {
|
||||
# serviceexposure is a core-platform CRD; nothing to enable, no warning.
|
||||
err=$(hack/select-install.sh "serviceexposure" 2>&1 1>/dev/null)
|
||||
[ -z "$err" ]
|
||||
output=$(hack/select-install.sh "serviceexposure" 2>/dev/null)
|
||||
[ -z "$output" ]
|
||||
}
|
||||
|
||||
@test "validate passes on the real source graph and suite mapping" {
|
||||
hack/select-install.sh --validate
|
||||
}
|
||||
@@ -180,6 +172,31 @@ YAML
|
||||
fi
|
||||
}
|
||||
|
||||
@test "validate detects a suite mapped to a source absent from the graph" {
|
||||
# suite_to_source() hardcodes securitygroup -> cozystack.securitygroup-controller;
|
||||
# a sources dir without that PackageSource must fail validation (fail closed),
|
||||
# pinning that the elif validates every mapping, including hardcoded ones,
|
||||
# against the graph.
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/sources" "$tmp/suites/securitygroup"
|
||||
: > "$tmp/suites/securitygroup/chainsaw-test.yaml"
|
||||
cat > "$tmp/sources/standalone.yaml" <<'YAML'
|
||||
apiVersion: cozystack.io/v1alpha1
|
||||
kind: PackageSource
|
||||
metadata:
|
||||
name: cozystack.standalone
|
||||
spec:
|
||||
variants:
|
||||
- name: default
|
||||
YAML
|
||||
err=$(hack/select-install.sh --validate "$tmp/sources" "$tmp/suites" 2>&1 1>/dev/null) && {
|
||||
echo "expected validation to fail on a mapping to a missing source" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "$err" | grep -q "maps to 'cozystack.securitygroup-controller', not a PackageSource"
|
||||
}
|
||||
|
||||
@test "validate fails when the suites dir does not exist" {
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
Reference in new issue
Block a user