refactor: extract shared reconciliation logic into pkg/reconcile#1572
refactor: extract shared reconciliation logic into pkg/reconcile#1572istio-testing merged 3 commits intoistio-ecosystem:mainfrom
Conversation
|
Hi @aslakknutsen. Thanks for your PR. I'm waiting for a istio-ecosystem or istio member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1572 +/- ##
==========================================
+ Coverage 71.09% 80.70% +9.61%
==========================================
Files 40 50 +10
Lines 2072 2441 +369
==========================================
+ Hits 1473 1970 +497
+ Misses 430 347 -83
+ Partials 169 124 -45 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
/ok-to-test |
809c9aa to
23d4aeb
Compare
Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no>
23d4aeb to
5eb5ab1
Compare
…ecks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no>
fb192cb to
e96e291
Compare
pkg/reconcile/istiod.go
Outdated
| // GetReleaseName returns the Helm release name for a given revision and chart. | ||
| func GetReleaseName(revisionName, chartName string) string { | ||
| return fmt.Sprintf("%s-%s", revisionName, chartName) | ||
| } | ||
|
|
||
| // GetChartPath returns the path to a chart for a given version. | ||
| func GetChartPath(version, chartName string) string { | ||
| return path.Join(version, "charts", chartName) | ||
| } |
There was a problem hiding this comment.
Do these need to be exported? I don't see them currently used outside this package but maybe it's intended for users of the library to consume these?
There was a problem hiding this comment.
GetChartPath is used across all reconcilers and from the Library install package(downstream), so moved to common.go(types.go).
GetReleaseName is only used in istiod so unexported.
Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no>
10cdd85 to
c51614a
Compare
* upstream/main: (30 commits) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1546) fixing the step numbers in our docs (istio-ecosystem#1545) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1543) ...
* upstream/main: (31 commits) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1546) fixing the step numbers in our docs (istio-ecosystem#1545) ...
* upstream/main: (31 commits) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1546) fixing the step numbers in our docs (istio-ecosystem#1545) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (33 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1549) ...
* upstream/main: (34 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) docs: Add comprehensive Istio Ambient Mode update and waypoint proxy procedures (istio-ecosystem#1279) ...
* upstream/main: (35 commits) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) ...
* upstream/main: (35 commits) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1551) ...
* upstream/main: (36 commits) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) ...
* upstream/main: (36 commits) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) ...
* upstream/main: (36 commits) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) ...
* upstream/main: (36 commits) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) Fix profile column status (istio-ecosystem#1553) ...
* upstream/main: (37 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) ...
* upstream/main: (37 commits) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1557) ...
* upstream/main: (38 commits) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) ...
* upstream/main: (38 commits) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1558) ...
* upstream/main: (39 commits) Add Claude /refactor command for code improvements (istio-ecosystem#1489) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) ...
* upstream/main: (39 commits) Add Claude /refactor command for code improvements (istio-ecosystem#1489) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) ...
* upstream/main: (39 commits) Add Claude /refactor command for code improvements (istio-ecosystem#1489) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) ...
* upstream/main: (39 commits) Add Claude /refactor command for code improvements (istio-ecosystem#1489) Improve scorecard test to avoid running on kind cluster inside OCP cl… (istio-ecosystem#1589) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1587) Adding TARGET_ARCH to tag definition when run on CI true (istio-ecosystem#1583) Expose "peerCaCrl" Ztunnel param added in Helm (istio-ecosystem#1578) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1579) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1577) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1576) feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1573) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1571) Add automation for updating EOL Istio versions (istio-ecosystem#1562) Fix e2e midstream CI mode (istio-ecosystem#1564) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1565) Migrate to fs.FS as the sole resource loading interface (istio-ecosystem#1561) Adding documentation for zero downtime ztunnel upgrade (istio-ecosystem#1552) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1563) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1560) Automator: Update dependencies in istio-ecosystem/sail-operator@main (istio-ecosystem#1559) ...
…io-ecosystem#1572) * refactor: extract shared reconciliation logic into pkg/reconcile Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(validation): consolidate validation and move CRD-specific checks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(reconcile): use GetChartPath helper and tidy up exports Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> Signed-off-by: Daniel Grimm <dgrimm@redhat.com>
…io-ecosystem#1572) * refactor: extract shared reconciliation logic into pkg/reconcile Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(validation): consolidate validation and move CRD-specific checks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(reconcile): use GetChartPath helper and tidy up exports Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 3001001) Backport-Change: Apply ApplyZTunnelFipsValues in pkg/reconcile ZTunnel ComputeValues (was only in controller on release-3.3) Backport-Reason: Upstream commit series omitted FIPS merge; preserve OSSM behavior after refactor.
…io-ecosystem#1572) * refactor: extract shared reconciliation logic into pkg/reconcile Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(validation): consolidate validation and move CRD-specific checks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(reconcile): use GetChartPath helper and tidy up exports Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 3001001) Backport-Change: Apply ApplyZTunnelFipsValues in pkg/reconcile ZTunnel ComputeValues (was only in controller on release-3.3) Backport-Reason: Upstream commit series omitted FIPS merge; preserve OSSM behavior after refactor.
* refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) * refactor: extract shared reconciliation logic into pkg/reconcile Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(validation): consolidate validation and move CRD-specific checks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(reconcile): use GetChartPath helper and tidy up exports Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 3001001) Backport-Change: Apply ApplyZTunnelFipsValues in pkg/reconcile ZTunnel ComputeValues (was only in controller on release-3.3) Backport-Reason: Upstream commit series omitted FIPS merge; preserve OSSM behavior after refactor. * feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) Adds RenderChart() and RenderLoadedChart() to render Helm chart templates without cluster access. This enables extracting resource types from charts for watch setup in the install library. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 360205e) * feat(helm): make managed-by label value configurable via ChartManagerOption (istio-ecosystem#1630) Allow callers to override the "managed-by" label value set on all Helm-managed resources by passing WithManagedByValue() to NewChartManager. The default remains "sail-operator" so existing operator behavior is unchanged. The value is threaded from ChartManager through HelmPostRenderer, replacing the previously hardcoded constant. BREAKING CHANGE: NewHelmPostRenderer now requires a managedByValue parameter Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit cb42ccb) * feat(library): Add `pkg/install` library for embedding Istio installation in external operators (#721) * feat(install): add GetWatchSpecs for drift detection Adds WatchSpec types and GetWatchSpecs() method that dynamically extracts GVKs by rendering Helm charts. This allows library consumers to set up watches for owned resources to detect configuration drift. The extraction happens at runtime to ensure watch specs always match what the charts actually create for the given options. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add Gateway API value helpers Adds GatewayAPIDefaults() and MergeValues() as exported helper functions for consumers to configure istiod for Gateway API mode. This approach keeps YAML profiles (like "openshift") for Helm chart processing, while providing programmatic defaults as composable helpers that consumers can modify directly: values := install.GatewayAPIDefaults() values.Pilot.Env["CONTROLLER_NAME"] = "my-controller" installer.Install(ctx, Options{Values: values}) The Gateway API defaults include: - Disabled PDB and CNI (not needed for Gateway API only) - Gateway API env vars for deployment controller mode - Disabled sidecar injection by default - Proxy header configuration for gateway traffic Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(crds): embed CRD YAML files for programmatic access Adds an embed.FS in chart/crds/ that exposes all CRD YAML files. This enables downstream libraries to install CRDs programmatically without requiring filesystem access to the chart directory. CRD files follow the naming convention: {group}_{plural}.yaml (e.g., extensions.istio.io_wasmplugins.yaml) Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add CRD management for Gateway API mode Adds automatic CRD installation based on PILOT_IGNORE_RESOURCES and PILOT_INCLUDE_RESOURCES filters. For Gateway API mode, only 3 Istio CRDs are installed: WASMPlugin, EnvoyFilter, and DestinationRule. Changes: - Add resource filtering constants (X_ prefixed until Istio feature ready) - Add GatewayAPIIgnoreResources and GatewayAPIIncludeResources values - Include resource filtering env vars in GatewayAPIDefaults() - Add ManageCRDs option (defaults to true) to control CRD installation - Add ensureCRDs() that derives CRD filenames dynamically from resource names - Add matchesPattern() using filepath.Match for glob wildcards (*.istio.io) - Add shouldManageResource() with correct filter precedence: INCLUDE > IGNORE The X_ prefix on env var names prevents Istio from processing them until the upstream feature is available. The library uses these values internally to determine which CRDs to install. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): use shared value computation pipeline Replace local prepareValues() with revision.ComputeValues() to ensure the library uses the same value processing as the operator: - image digest application - vendor default values - profile and platform defaults - FIPS configuration - namespace and revision overrides This aligns the library code path with the operator, ensuring bug fixes and enhancements in value computation apply to both. Note: Image digests currently require config.Config to be populated, which is a known limitation being tracked separately. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add DriftReconciler for automatic drift detection Add a DriftReconciler that watches resources created by Install() and automatically restores them when drift is detected. This enables library consumers to maintain installation consistency without implementing their own watch logic. Key changes: - Install() now returns (*DriftReconciler, error) instead of just error, ensuring opts consistency between installation and drift detection - DriftReconciler uses dynamic informers to watch namespaced and cluster-scoped resources separately - Ignores Add events entirely (avoids reconciliation on initial cache sync) - Predicates filter Update/Delete events to avoid unnecessary reconciliation (e.g., status-only changes, ServiceAccount token updates) - Support for owner reference filtering when OwnerRef is configured - Rate-limited workqueue coalesces rapid events into single reconciliation Usage: reconciler, _ := installer.Install(ctx, opts) reconciler.Start(ctx) // blocks until stopped BREAKING CHANGE: Install() signature changed from returning `error` to returning `(*DriftReconciler, error)`. Callers that don't need drift detection can ignore the first return value with `_, err := Install(...)`. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add LibraryRBACRules for consumer RBAC aggregation Expose the RBAC PolicyRules required by library consumers as a Go API. Rules are derived from chart/templates/rbac/role.yaml with sailoperator.io CRs filtered out, since library consumers don't manage Sail CRDs. This allows operators using the install library (e.g., OpenShift Ingress) to aggregate the required permissions into their own ClusterRole at build time rather than discovering them at runtime. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): auto-populate downstream image refs from embedded FS The library path has no OLM config file to provide production image refs. SetImageDefaults scans the embedded resource FS for version directories and constructs full image refs from a registry and naming convention. NewInstaller calls SetImageDefaults with the same resourceFS used for chart loading, ensuring consistency. The operator path (config.Read) takes precedence if already populated. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): derive version from resource FS instead of versions.yaml The library path doesn't use the operator's versions.yaml, so relying on istioversion.Default and istioversion.Resolve was wrong for downstream. DefaultVersion scans the resource FS for the highest stable semver directory, and ValidateVersion checks a version directory exists directly. This removes the istioversion dependency from pkg/install entirely, making version resolution consistent with the FS used for charts and images. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): replace manual MergeValues with generic map merge The previous MergeValues implementation manually copied each supported field from overlay to base, requiring updates whenever new fields were added to v1.Values. This was brittle and would silently ignore new fields until explicitly handled. The new implementation: - Converts Values to map[string]any via helm.FromValues() - Uses recursive mergeOverwrite (copied from istiovalues package) - Converts back via helm.ToValues() This matches Helm's merge semantics: maps merge recursively, lists replace entirely. Added explicit test coverage for list replacement behavior to document this semantic. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add batch CRD ownership management and Status type The per-CRD create-if-not-exists approach didn't account for ownership conflicts between CIO, OSSM/OLM, and third-party CRD installations. This rewrites CRD management to classify all target CRDs as a batch before acting, preventing mixed ownership scenarios. Key changes: - Add Status type covering both CRD state and Helm install result - Add CRDManagementState enum (ManagedByCIO, ManagedByOLM, UnknownManagement, MixedOwnership, NoneExist) - Batch CRD classification: check all targets, aggregate ownership, act atomically (install all or touch none) - CIO-owned CRDs get ingress.operator.openshift.io/owned label and helm.sh/resource-policy:keep annotation - CIO-owned CRDs are updated on each reconcile (not just created) - Add IncludeAllCRDs option (default false: only PILOT_INCLUDE_RESOURCES) - Extract doInstall() so DriftReconciler avoids creating nested reconcilers - Install() returns (*DriftReconciler, Status) instead of error BREAKING CHANGE: Install() signature changed from returning `(*DriftReconciler, error)` to `(*DriftReconciler, Status)`. Check `status.Error` instead of the error return. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install)!: replace Installer+DriftReconciler with Library actor The Installer+DriftReconciler pair forced the consumer to manage two separate types and couldn't propagate status from internal drift reconciliations back to the controller. Replace with a single Library type that runs as an independent actor: - New() creates the Library with kube and dynamic clients - Start(ctx) returns a <-chan struct{} notification channel, launches the internal worker goroutine, and sits idle until first Apply() - Apply(opts) sets desired state; no-op if options unchanged (deep compare via optionsEqual) - Status() returns the latest reconciliation result (thread-safe) The Library owns its own workqueue, informers, and lifecycle. The consumer just sends desired state and watches the notification channel, which fits the controller-runtime source.Channel pattern for the CIO. BREAKING CHANGE: `NewInstaller`, `Installer`, `DriftReconciler`, and `Install()` are removed. Use `New()`, `Library.Start()`, `Library.Apply()`, and `Library.Status()` instead. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): watch CRDs for ownership changes and lifecycle events The Library needs to detect when Istio CRDs are created, deleted, or have their ownership labels changed (e.g. OSSM takes over via OLM, or CRDs are removed). Without this, the Library would only re-classify CRD ownership on explicit Apply() calls or Helm resource drift. Add WatchTypeCRD with a dedicated event handler that filters by target CRD names and triggers on label/annotation/generation changes, plus create and delete events. The CRD informer is set up alongside Helm resource informers when ManageCRDs is enabled. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * ix(install): resolve default version in getWatchSpecs getWatchSpecs called applyDefaults() which fills in namespace and revision but not version. When version was empty, ValidateVersion failed silently and no Helm resource informers were created — only CRD informers. Drift detection for Deployments, ConfigMaps, etc. was completely disabled without any visible error. Add the same DefaultVersion(resourceFS) fallback that reconcile() uses, and add logging so silent informer setup failures are visible. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add Status.String() for human-readable status output Include all fields in the output: installed state, version, CRD aggregate state, per-CRD name:state pairs, and error if present. Useful for logging and debugging from consumer operators. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add structured logging to Library internals The Library had no logging at all — errors from getWatchSpecs were silently swallowed, informer setup failures were invisible, and drift events left no trace. Add ctrllog-based logging to run loop, setupInformers, and event handlers so operators can diagnose issues without attaching a debugger. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): reclaim CRDs with lost labels and reinstall deleted ones Three related fixes to CRD drift recovery: 1. aggregateCRDState treated CIO+unknown as UnknownManagement, blocking all action. Now treats it as ManagedByCIO — if no OLM is involved, unknown labels are drift, not foreign ownership. 2. updateCRDs only did Get+Update, failing on deleted CRDs. Now falls back to Create when the CRD is NotFound. 3. manageCRDs CIO branch now re-labels unknowns and reinstalls missing CRDs, reporting what it did in the status message. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): remove error retry loop from workqueue AddRateLimited on permanent errors (CRD classification, bad config) caused infinite reconcile loops. The library is event-driven — informers trigger on state changes and Apply() enqueues explicitly. No need for automatic retries. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(install): extract CRDManager type and split filtering utilities CRD logic in crds.go was a mix of free functions, Library methods, and filtering utilities with no clear entry point. This extracts a CRDManager type that owns the client and provides Reconcile() as the single entry point for CRD classification/install/update. Pure filtering functions (pattern matching, filename conversion, target resolution) move to crds_filter.go. Tests split accordingly. - Add CRDResult type to replace the 4-tuple return from manageCRDs - Introduce CRDManager with Reconcile(), WatchTargets(), and private classifyCRD/installCRDs/updateCRDs methods - Simplify Library.buildCRDWatchSpec to delegate to CRDManager.WatchTargets - Add classifyCRD unit tests using fake client - Add unlabeledCRDNames tests Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): strip "v" prefix from image tags and normalize version input Image tags in container registries use bare semver (e.g. 1.28.0), but SetImageDefaults was using the directory name directly (v1.28.0). Also adds NormalizeVersion to accept version input with or without the "v" prefix, called from applyDefaults so it's caught at a single point. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): deep-copy Values to prevent infinite reconcile loop Apply() and reconcile() shared the same *v1.Values pointer. When ComputeValues (via ApplyDigests) mutated the Values in place during reconcile, the stored desiredOpts diverged from freshly built Options, causing optionsEqual to fail and re-enqueue on every Apply() call. Fix by deep-copying at two boundaries: - Apply(): DeepCopy Values on store, isolating from the caller's pointer - reconcile(): DeepCopy Values at entry, isolating from all downstream mutations (ApplyDigests, future code, etc.) Also adds TestCIOReconcileLoopConverges which simulates the full Library-controller interaction to verify the loop converges after exactly one reconcile, and adds caller tracing to enqueue() for debugging. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install)!: remove OwnerRef and support Apply/Uninstall lifecycle Multiple GatewayClasses can share one istiod, so OwnerRef-based GC is wrong. Replace with explicit lifecycle management: the consumer calls Uninstall() when no GatewayClasses remain, using labels for drift filtering instead. Rework the run() loop to support multiple idle/active cycles so the Library can be reused after Uninstall. Add a lifecycle mutex so Apply blocks while Uninstall is in progress, preventing the drift-repair loop from fighting Helm teardown. BREAKING CHANGE: `Options.OwnerRef` field removed; `Uninstall` signature changed from `Uninstall(ctx, namespace, revision)` to `Uninstall(ctx)`. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): restructure package for clarity and fix race condition Split the monolithic install.go into focused files by responsibility: - library.go: public API surface (Library, Options, Status, New) - lifecycle.go: run loop, workqueue, Apply/Uninstall/Start - installer.go: core reconcile/uninstall logic and watch-spec computation - informers.go: informer setup and event handler constructors - values.go: GatewayAPIDefaults, MergeValues (renamed from profiles.go) Extract installer struct from Library so reconcile, uninstall, and watch-spec logic can be tested without concurrency machinery. Make predicates and event handlers take explicit dependencies instead of closing over Library state. Unexport internal symbols (CRDManager, WatchType, WatchSpec, label/env constants) to shrink the API surface. Replace 100ms polling in waitForDesiredState with a signal channel. Replace custom combineErrors with stdlib errors.Join. Move env/pattern constants to crds_filter.go where they are consumed. Fix a race in processWorkQueue where Uninstall could nil desiredOpts between a nil-check and dereference done under separate locks. Fix repeated regex compilation in shouldReconcileValidatingWebhook by hoisting to a package-level MustCompile. Hoist isClusterScoped map to a package-level var. Normalize function naming to consistent patterns (apiVersionKindToGVK, shouldFilterStatusChanges). Add unit tests for installer.reconcile status paths and event handler constructor predicate matrix. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * test(install): add fake-client tests for crdManager Cover Reconcile, classifyCRDs, WatchTargets, loadCRD, and applyCIOLabels using a fake Kubernetes client. Tests exercise fresh install, CIO-owned updates, reinstall of missing CRDs, reclaiming unlabeled CRDs, OLM-owned passthrough, mixed ownership error, and no-targets short circuit. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): use configurable managed-by label for Library resources Set the managed-by label to "sail-library" on all Helm resources created by the Library, distinguishing them from operator-managed resources. Thread the value into informer predicates so drift detection filters on the correct label. Also fix isOwnedResource to check the actual managed-by key set by the post-renderer instead of stale app.kubernetes.io/managed-by == "sail-operator" match. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install)!: accept namespace/revision params in Uninstall for crash recovery After a crash, the Library has no in-memory desiredOpts, so Uninstall silently returned nil while the Helm release remained on the cluster. By taking explicit namespace and revision parameters, callers can uninstall without needing a prior Apply() call. BREAKING CHANGE: Uninstall signature changed from (ctx) to (ctx, namespace, revision). Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): allow consumer to adopt orphaned OLM-managed CRDs When OLM manages Istio CRDs via a subscription, deleting that subscription leaves the CRDs with olm.managed=true but no actual owner. Add OverwriteOLMManagedCRDFunc callback to Options so the consumer can inspect the CRD's OLM annotations and decide whether to take ownership. The callback is invoked during classification; returning true reclassifies the CRD as CIO-managed so the existing update path replaces OLM labels with CIO labels. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add Enqueue() to force reconciliation on external state changes Apply() skips reconciliation when Options are unchanged, which prevents consumers from triggering CRD re-classification when external cluster state changes (e.g. OLM Subscription deleted) but Options stay the same. Enqueue() bypasses the optionsEqual check and directly adds a work item, letting the consumer signal "something outside my Options changed, please re-evaluate." This avoids removing the idempotency guard in Apply(), which would create an infinite notify-Apply-reconcile feedback loop. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): prevent panic on double Uninstall by niling closed channels Uninstall() captured informerStop and processingDone from the Library struct but never cleared them. A second Uninstall() would attempt to close the already-closed channels, causing a panic. Nil out both fields after capturing the locals so subsequent calls see nil and skip the close/wait via the existing guards. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): add exponential backoff on failed reconciliations When Helm install fails, its partial-create/rollback cycle fires informer events that immediately re-enqueue work. Because enqueue() used Add() (bypassing the rate limiter) and processWorkQueue always called Forget() (resetting the backoff counter), the library spun at full speed retrying permanent errors every ~3 seconds. Switch enqueue() to AddRateLimited() so informer-driven re-enqueues respect the backoff counter. Only call Forget() on success so the counter accumulates on failure. Apply() uses Add() directly to ensure explicit user intent is never delayed by prior failures. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): fix Uninstall deadlock caused by niled processingDone channel Commit 909ab26 nils l.processingDone in Uninstall to prevent double-close panics, but processWorkQueue's defer re-read the struct field — which is now nil — and skipped closing the channel. Uninstall then blocks forever on <-processingDone. Fix by capturing both channels as locals under the lock in run() and passing them to callees. processWorkQueue now receives the done channel as a parameter, so Uninstall niling the struct field doesn't affect it. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * docs(install): add README and fix source.Channel usage in USAGE.md The USAGE.md example used source.Channel with a <-chan struct{}, which doesn't compile against controller-runtime v0.23.1 (expects TypedGenericEvent). Replace with source.Func and remove the now-unnecessary custom event handler section. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): load image digests from embedded CSV annotations The library previously constructed image refs from hardcoded downstream registry/name/tag values. This reads the canonical image references directly from the ClusterServiceVersion pod template annotations, which are already maintained by the build pipeline. This means the library gets the correct upstream images (or digest-pinned images when built with USE_IMAGE_DIGESTS=true) without requiring manual synchronization. Signed-off-by: Aslak Knutsen <aslak@redhat.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): clear status after successful Uninstall Uninstall never updated the stored Status, so Status() returned stale data with Installed:true after the Helm release was removed. Reset to zero-value Status on the success path so consumers see Installed:false. The old status is preserved if the uninstall fails, since the release may still exist. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * fix(embed): update embed csv ref to match downstream * fix: remove unused default values and deprecated api refs * refactor(bundle): move CSV embed out of bundle/manifests to avoid operator-sdk validation errors operator-sdk bundle validation rejects non-YAML files in bundle/manifests/. Move the embed to bundle/bundle.go as []byte, simplify LoadImageDigestsFromCSV to accept raw bytes instead of fs.FS, and add a test against the real embedded CSV. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * fix: lint stuff * fix: lint stuff * fix: make gen go.mod updates * fix(install): align clearIgnoredFields with upstream webhook predicate Clear caBundle from clientConfig for both ValidatingWebhookConfiguration and MutatingWebhookConfiguration, and only clear failurePolicy for validating webhooks. Uses a kind-based switch to avoid affecting unrelated resource types. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> Signed-off-by: Aslak Knutsen <aslak@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit 665c0b8)
* refactor: extract shared reconciliation logic into pkg/reconcile (istio-ecosystem#1572) * refactor: extract shared reconciliation logic into pkg/reconcile Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode. Changes: - Add pkg/reconcile with IstiodReconciler, CNIReconciler, ZTunnelReconciler - Each reconciler provides ValidateSpec(), Validate(), Install(), Uninstall() - Export ApplyCNIImageDigests() and ApplyZTunnelImageDigests() for reuse - Refactor IstioRevision, IstioCNI, ZTunnel controllers to delegate to shared reconcilers - Update controller tests to use shared reconcilers Design decisions: - Two-tier validation: ValidateSpec() for basic checks, Validate() for K8s API checks (supports library usage without K8s client) - Controller-agnostic error messages (e.g., "version not set" instead of "spec.version not set") Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(validation): consolidate validation and move CRD-specific checks to controller The validation was awkwardly split between ValidateSpec (no client) and Validate (with client), but both paths actually need a client. This refactoring creates a cleaner separation: - General validations (version/namespace/values checks, target namespace exists) remain in pkg/reconcile - CRD-specific validations (revision name consistency, IstioRevisionTag conflict) move to the controller level Changes: - Remove ValidateSpec from IstiodReconciler, CNIReconciler, ZTunnelReconciler - Collapse validation into single Validate function that always requires client - Add validateRevisionConsistency and validateNoTagConflict to controller - Update tests to reflect new validation structure This enables library consumers to use pkg/reconcile without needing to implement operator-specific validation logic. Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(reconcile): use GetChartPath helper and tidy up exports Replace inline path.Join(version, "charts", ...) calls with the existing GetChartPath helper across all three reconcilers. Unexport getReleaseName since it's only used within istiod.go. Move GetChartPath and its test to common.go/common_test.go (renamed from types.go) since it's shared across packages. Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 3001001) Backport-Change: Apply ApplyZTunnelFipsValues in pkg/reconcile ZTunnel ComputeValues (was only in controller on release-3.3) Backport-Reason: Upstream commit series omitted FIPS merge; preserve OSSM behavior after refactor. * feat(helm): add RenderChart functions for template rendering (istio-ecosystem#1575) Adds RenderChart() and RenderLoadedChart() to render Helm chart templates without cluster access. This enables extracting resource types from charts for watch setup in the install library. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> (cherry picked from commit 360205e) * feat(helm): make managed-by label value configurable via ChartManagerOption (istio-ecosystem#1630) Allow callers to override the "managed-by" label value set on all Helm-managed resources by passing WithManagedByValue() to NewChartManager. The default remains "sail-operator" so existing operator behavior is unchanged. The value is threaded from ChartManager through HelmPostRenderer, replacing the previously hardcoded constant. BREAKING CHANGE: NewHelmPostRenderer now requires a managedByValue parameter Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit cb42ccb) * feat(library): Add `pkg/install` library for embedding Istio installation in external operators (#721) * feat(install): add GetWatchSpecs for drift detection Adds WatchSpec types and GetWatchSpecs() method that dynamically extracts GVKs by rendering Helm charts. This allows library consumers to set up watches for owned resources to detect configuration drift. The extraction happens at runtime to ensure watch specs always match what the charts actually create for the given options. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add Gateway API value helpers Adds GatewayAPIDefaults() and MergeValues() as exported helper functions for consumers to configure istiod for Gateway API mode. This approach keeps YAML profiles (like "openshift") for Helm chart processing, while providing programmatic defaults as composable helpers that consumers can modify directly: values := install.GatewayAPIDefaults() values.Pilot.Env["CONTROLLER_NAME"] = "my-controller" installer.Install(ctx, Options{Values: values}) The Gateway API defaults include: - Disabled PDB and CNI (not needed for Gateway API only) - Gateway API env vars for deployment controller mode - Disabled sidecar injection by default - Proxy header configuration for gateway traffic Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(crds): embed CRD YAML files for programmatic access Adds an embed.FS in chart/crds/ that exposes all CRD YAML files. This enables downstream libraries to install CRDs programmatically without requiring filesystem access to the chart directory. CRD files follow the naming convention: {group}_{plural}.yaml (e.g., extensions.istio.io_wasmplugins.yaml) Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add CRD management for Gateway API mode Adds automatic CRD installation based on PILOT_IGNORE_RESOURCES and PILOT_INCLUDE_RESOURCES filters. For Gateway API mode, only 3 Istio CRDs are installed: WASMPlugin, EnvoyFilter, and DestinationRule. Changes: - Add resource filtering constants (X_ prefixed until Istio feature ready) - Add GatewayAPIIgnoreResources and GatewayAPIIncludeResources values - Include resource filtering env vars in GatewayAPIDefaults() - Add ManageCRDs option (defaults to true) to control CRD installation - Add ensureCRDs() that derives CRD filenames dynamically from resource names - Add matchesPattern() using filepath.Match for glob wildcards (*.istio.io) - Add shouldManageResource() with correct filter precedence: INCLUDE > IGNORE The X_ prefix on env var names prevents Istio from processing them until the upstream feature is available. The library uses these values internally to determine which CRDs to install. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): use shared value computation pipeline Replace local prepareValues() with revision.ComputeValues() to ensure the library uses the same value processing as the operator: - image digest application - vendor default values - profile and platform defaults - FIPS configuration - namespace and revision overrides This aligns the library code path with the operator, ensuring bug fixes and enhancements in value computation apply to both. Note: Image digests currently require config.Config to be populated, which is a known limitation being tracked separately. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add DriftReconciler for automatic drift detection Add a DriftReconciler that watches resources created by Install() and automatically restores them when drift is detected. This enables library consumers to maintain installation consistency without implementing their own watch logic. Key changes: - Install() now returns (*DriftReconciler, error) instead of just error, ensuring opts consistency between installation and drift detection - DriftReconciler uses dynamic informers to watch namespaced and cluster-scoped resources separately - Ignores Add events entirely (avoids reconciliation on initial cache sync) - Predicates filter Update/Delete events to avoid unnecessary reconciliation (e.g., status-only changes, ServiceAccount token updates) - Support for owner reference filtering when OwnerRef is configured - Rate-limited workqueue coalesces rapid events into single reconciliation Usage: reconciler, _ := installer.Install(ctx, opts) reconciler.Start(ctx) // blocks until stopped BREAKING CHANGE: Install() signature changed from returning `error` to returning `(*DriftReconciler, error)`. Callers that don't need drift detection can ignore the first return value with `_, err := Install(...)`. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add LibraryRBACRules for consumer RBAC aggregation Expose the RBAC PolicyRules required by library consumers as a Go API. Rules are derived from chart/templates/rbac/role.yaml with sailoperator.io CRs filtered out, since library consumers don't manage Sail CRDs. This allows operators using the install library (e.g., OpenShift Ingress) to aggregate the required permissions into their own ClusterRole at build time rather than discovering them at runtime. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): auto-populate downstream image refs from embedded FS The library path has no OLM config file to provide production image refs. SetImageDefaults scans the embedded resource FS for version directories and constructs full image refs from a registry and naming convention. NewInstaller calls SetImageDefaults with the same resourceFS used for chart loading, ensuring consistency. The operator path (config.Read) takes precedence if already populated. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): derive version from resource FS instead of versions.yaml The library path doesn't use the operator's versions.yaml, so relying on istioversion.Default and istioversion.Resolve was wrong for downstream. DefaultVersion scans the resource FS for the highest stable semver directory, and ValidateVersion checks a version directory exists directly. This removes the istioversion dependency from pkg/install entirely, making version resolution consistent with the FS used for charts and images. Co-authored-by: Cursor noreply@cursor.com Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): replace manual MergeValues with generic map merge The previous MergeValues implementation manually copied each supported field from overlay to base, requiring updates whenever new fields were added to v1.Values. This was brittle and would silently ignore new fields until explicitly handled. The new implementation: - Converts Values to map[string]any via helm.FromValues() - Uses recursive mergeOverwrite (copied from istiovalues package) - Converts back via helm.ToValues() This matches Helm's merge semantics: maps merge recursively, lists replace entirely. Added explicit test coverage for list replacement behavior to document this semantic. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): add batch CRD ownership management and Status type The per-CRD create-if-not-exists approach didn't account for ownership conflicts between CIO, OSSM/OLM, and third-party CRD installations. This rewrites CRD management to classify all target CRDs as a batch before acting, preventing mixed ownership scenarios. Key changes: - Add Status type covering both CRD state and Helm install result - Add CRDManagementState enum (ManagedByCIO, ManagedByOLM, UnknownManagement, MixedOwnership, NoneExist) - Batch CRD classification: check all targets, aggregate ownership, act atomically (install all or touch none) - CIO-owned CRDs get ingress.operator.openshift.io/owned label and helm.sh/resource-policy:keep annotation - CIO-owned CRDs are updated on each reconcile (not just created) - Add IncludeAllCRDs option (default false: only PILOT_INCLUDE_RESOURCES) - Extract doInstall() so DriftReconciler avoids creating nested reconcilers - Install() returns (*DriftReconciler, Status) instead of error BREAKING CHANGE: Install() signature changed from returning `(*DriftReconciler, error)` to `(*DriftReconciler, Status)`. Check `status.Error` instead of the error return. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install)!: replace Installer+DriftReconciler with Library actor The Installer+DriftReconciler pair forced the consumer to manage two separate types and couldn't propagate status from internal drift reconciliations back to the controller. Replace with a single Library type that runs as an independent actor: - New() creates the Library with kube and dynamic clients - Start(ctx) returns a <-chan struct{} notification channel, launches the internal worker goroutine, and sits idle until first Apply() - Apply(opts) sets desired state; no-op if options unchanged (deep compare via optionsEqual) - Status() returns the latest reconciliation result (thread-safe) The Library owns its own workqueue, informers, and lifecycle. The consumer just sends desired state and watches the notification channel, which fits the controller-runtime source.Channel pattern for the CIO. BREAKING CHANGE: `NewInstaller`, `Installer`, `DriftReconciler`, and `Install()` are removed. Use `New()`, `Library.Start()`, `Library.Apply()`, and `Library.Status()` instead. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): watch CRDs for ownership changes and lifecycle events The Library needs to detect when Istio CRDs are created, deleted, or have their ownership labels changed (e.g. OSSM takes over via OLM, or CRDs are removed). Without this, the Library would only re-classify CRD ownership on explicit Apply() calls or Helm resource drift. Add WatchTypeCRD with a dedicated event handler that filters by target CRD names and triggers on label/annotation/generation changes, plus create and delete events. The CRD informer is set up alongside Helm resource informers when ManageCRDs is enabled. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * ix(install): resolve default version in getWatchSpecs getWatchSpecs called applyDefaults() which fills in namespace and revision but not version. When version was empty, ValidateVersion failed silently and no Helm resource informers were created — only CRD informers. Drift detection for Deployments, ConfigMaps, etc. was completely disabled without any visible error. Add the same DefaultVersion(resourceFS) fallback that reconcile() uses, and add logging so silent informer setup failures are visible. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add Status.String() for human-readable status output Include all fields in the output: installed state, version, CRD aggregate state, per-CRD name:state pairs, and error if present. Useful for logging and debugging from consumer operators. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add structured logging to Library internals The Library had no logging at all — errors from getWatchSpecs were silently swallowed, informer setup failures were invisible, and drift events left no trace. Add ctrllog-based logging to run loop, setupInformers, and event handlers so operators can diagnose issues without attaching a debugger. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): reclaim CRDs with lost labels and reinstall deleted ones Three related fixes to CRD drift recovery: 1. aggregateCRDState treated CIO+unknown as UnknownManagement, blocking all action. Now treats it as ManagedByCIO — if no OLM is involved, unknown labels are drift, not foreign ownership. 2. updateCRDs only did Get+Update, failing on deleted CRDs. Now falls back to Create when the CRD is NotFound. 3. manageCRDs CIO branch now re-labels unknowns and reinstalls missing CRDs, reporting what it did in the status message. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): remove error retry loop from workqueue AddRateLimited on permanent errors (CRD classification, bad config) caused infinite reconcile loops. The library is event-driven — informers trigger on state changes and Apply() enqueues explicitly. No need for automatic retries. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(install): extract CRDManager type and split filtering utilities CRD logic in crds.go was a mix of free functions, Library methods, and filtering utilities with no clear entry point. This extracts a CRDManager type that owns the client and provides Reconcile() as the single entry point for CRD classification/install/update. Pure filtering functions (pattern matching, filename conversion, target resolution) move to crds_filter.go. Tests split accordingly. - Add CRDResult type to replace the 4-tuple return from manageCRDs - Introduce CRDManager with Reconcile(), WatchTargets(), and private classifyCRD/installCRDs/updateCRDs methods - Simplify Library.buildCRDWatchSpec to delegate to CRDManager.WatchTargets - Add classifyCRD unit tests using fake client - Add unlabeledCRDNames tests Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): strip "v" prefix from image tags and normalize version input Image tags in container registries use bare semver (e.g. 1.28.0), but SetImageDefaults was using the directory name directly (v1.28.0). Also adds NormalizeVersion to accept version input with or without the "v" prefix, called from applyDefaults so it's caught at a single point. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): deep-copy Values to prevent infinite reconcile loop Apply() and reconcile() shared the same *v1.Values pointer. When ComputeValues (via ApplyDigests) mutated the Values in place during reconcile, the stored desiredOpts diverged from freshly built Options, causing optionsEqual to fail and re-enqueue on every Apply() call. Fix by deep-copying at two boundaries: - Apply(): DeepCopy Values on store, isolating from the caller's pointer - reconcile(): DeepCopy Values at entry, isolating from all downstream mutations (ApplyDigests, future code, etc.) Also adds TestCIOReconcileLoopConverges which simulates the full Library-controller interaction to verify the loop converges after exactly one reconcile, and adds caller tracing to enqueue() for debugging. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install)!: remove OwnerRef and support Apply/Uninstall lifecycle Multiple GatewayClasses can share one istiod, so OwnerRef-based GC is wrong. Replace with explicit lifecycle management: the consumer calls Uninstall() when no GatewayClasses remain, using labels for drift filtering instead. Rework the run() loop to support multiple idle/active cycles so the Library can be reused after Uninstall. Add a lifecycle mutex so Apply blocks while Uninstall is in progress, preventing the drift-repair loop from fighting Helm teardown. BREAKING CHANGE: `Options.OwnerRef` field removed; `Uninstall` signature changed from `Uninstall(ctx, namespace, revision)` to `Uninstall(ctx)`. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> * refactor(install): restructure package for clarity and fix race condition Split the monolithic install.go into focused files by responsibility: - library.go: public API surface (Library, Options, Status, New) - lifecycle.go: run loop, workqueue, Apply/Uninstall/Start - installer.go: core reconcile/uninstall logic and watch-spec computation - informers.go: informer setup and event handler constructors - values.go: GatewayAPIDefaults, MergeValues (renamed from profiles.go) Extract installer struct from Library so reconcile, uninstall, and watch-spec logic can be tested without concurrency machinery. Make predicates and event handlers take explicit dependencies instead of closing over Library state. Unexport internal symbols (CRDManager, WatchType, WatchSpec, label/env constants) to shrink the API surface. Replace 100ms polling in waitForDesiredState with a signal channel. Replace custom combineErrors with stdlib errors.Join. Move env/pattern constants to crds_filter.go where they are consumed. Fix a race in processWorkQueue where Uninstall could nil desiredOpts between a nil-check and dereference done under separate locks. Fix repeated regex compilation in shouldReconcileValidatingWebhook by hoisting to a package-level MustCompile. Hoist isClusterScoped map to a package-level var. Normalize function naming to consistent patterns (apiVersionKindToGVK, shouldFilterStatusChanges). Add unit tests for installer.reconcile status paths and event handler constructor predicate matrix. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * test(install): add fake-client tests for crdManager Cover Reconcile, classifyCRDs, WatchTargets, loadCRD, and applyCIOLabels using a fake Kubernetes client. Tests exercise fresh install, CIO-owned updates, reinstall of missing CRDs, reclaiming unlabeled CRDs, OLM-owned passthrough, mixed ownership error, and no-targets short circuit. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): use configurable managed-by label for Library resources Set the managed-by label to "sail-library" on all Helm resources created by the Library, distinguishing them from operator-managed resources. Thread the value into informer predicates so drift detection filters on the correct label. Also fix isOwnedResource to check the actual managed-by key set by the post-renderer instead of stale app.kubernetes.io/managed-by == "sail-operator" match. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install)!: accept namespace/revision params in Uninstall for crash recovery After a crash, the Library has no in-memory desiredOpts, so Uninstall silently returned nil while the Helm release remained on the cluster. By taking explicit namespace and revision parameters, callers can uninstall without needing a prior Apply() call. BREAKING CHANGE: Uninstall signature changed from (ctx) to (ctx, namespace, revision). Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): allow consumer to adopt orphaned OLM-managed CRDs When OLM manages Istio CRDs via a subscription, deleting that subscription leaves the CRDs with olm.managed=true but no actual owner. Add OverwriteOLMManagedCRDFunc callback to Options so the consumer can inspect the CRD's OLM annotations and decide whether to take ownership. The callback is invoked during classification; returning true reclassifies the CRD as CIO-managed so the existing update path replaces OLM labels with CIO labels. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(install): add Enqueue() to force reconciliation on external state changes Apply() skips reconciliation when Options are unchanged, which prevents consumers from triggering CRD re-classification when external cluster state changes (e.g. OLM Subscription deleted) but Options stay the same. Enqueue() bypasses the optionsEqual check and directly adds a work item, letting the consumer signal "something outside my Options changed, please re-evaluate." This avoids removing the idempotency guard in Apply(), which would create an infinite notify-Apply-reconcile feedback loop. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): prevent panic on double Uninstall by niling closed channels Uninstall() captured informerStop and processingDone from the Library struct but never cleared them. A second Uninstall() would attempt to close the already-closed channels, causing a panic. Nil out both fields after capturing the locals so subsequent calls see nil and skip the close/wait via the existing guards. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): add exponential backoff on failed reconciliations When Helm install fails, its partial-create/rollback cycle fires informer events that immediately re-enqueue work. Because enqueue() used Add() (bypassing the rate limiter) and processWorkQueue always called Forget() (resetting the backoff counter), the library spun at full speed retrying permanent errors every ~3 seconds. Switch enqueue() to AddRateLimited() so informer-driven re-enqueues respect the backoff counter. Only call Forget() on success so the counter accumulates on failure. Apply() uses Add() directly to ensure explicit user intent is never delayed by prior failures. Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): fix Uninstall deadlock caused by niled processingDone channel Commit 909ab26 nils l.processingDone in Uninstall to prevent double-close panics, but processWorkQueue's defer re-read the struct field — which is now nil — and skipped closing the channel. Uninstall then blocks forever on <-processingDone. Fix by capturing both channels as locals under the lock in run() and passing them to callees. processWorkQueue now receives the done channel as a parameter, so Uninstall niling the struct field doesn't affect it. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * docs(install): add README and fix source.Channel usage in USAGE.md The USAGE.md example used source.Channel with a <-chan struct{}, which doesn't compile against controller-runtime v0.23.1 (expects TypedGenericEvent). Replace with source.Func and remove the now-unnecessary custom event handler section. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * feat(install): load image digests from embedded CSV annotations The library previously constructed image refs from hardcoded downstream registry/name/tag values. This reads the canonical image references directly from the ClusterServiceVersion pod template annotations, which are already maintained by the build pipeline. This means the library gets the correct upstream images (or digest-pinned images when built with USE_IMAGE_DIGESTS=true) without requiring manual synchronization. Signed-off-by: Aslak Knutsen <aslak@redhat.com> Signed-off-by: Aslak Knutsen <aslak@4fs.no> Made-with: Cursor * fix(install): clear status after successful Uninstall Uninstall never updated the stored Status, so Status() returned stale data with Installed:true after the Helm release was removed. Reset to zero-value Status on the success path so consumers see Installed:false. The old status is preserved if the uninstall fails, since the release may still exist. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * fix(embed): update embed csv ref to match downstream * fix: remove unused default values and deprecated api refs * refactor(bundle): move CSV embed out of bundle/manifests to avoid operator-sdk validation errors operator-sdk bundle validation rejects non-YAML files in bundle/manifests/. Move the embed to bundle/bundle.go as []byte, simplify LoadImageDigestsFromCSV to accept raw bytes instead of fs.FS, and add a test against the real embedded CSV. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> * fix: lint stuff * fix: lint stuff * fix: make gen go.mod updates * fix(install): align clearIgnoredFields with upstream webhook predicate Clear caBundle from clientConfig for both ValidatingWebhookConfiguration and MutatingWebhookConfiguration, and only clear failurePolicy for validating webhooks. Uses a kind-based switch to avoid affecting unrelated resource types. Made-with: Cursor Signed-off-by: Aslak Knutsen <aslak@4fs.no> --------- Signed-off-by: Aslak Knutsen <aslak@4fs.no> Signed-off-by: Aslak Knutsen <aslak@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit 665c0b8)
What type of PR is this?
What this PR does / why we need it:
Move validation, Helm installation, and image digest logic from individual controllers into a shared pkg/reconcile package. This enables code reuse between operator controllers and (future) the install library, ensuring the same code path is used regardless of deployment mode.
Changes:
Design decisions:
Which issue(s) this PR fixes:
Additional information:
Co-authored-by: Cursor noreply@cursor.com