Skip to content

v1.15.0

Latest

Choose a tag to compare

@gianlucam76 gianlucam76 released this 12 Sep 10:32
· 2 commits to release-1.15 since this release
893c29b

馃殌 New Features

Namespace-Scoped RBAC for Agentless Watches
sveltos-agent and drift-detection-manager, in agentless mode, previously assumed they could watch and list any resource anywhere, and would just 403-loop against a kubeconfig whose RBAC is scoped to a subset of namespaces. Both now support a --watch-namespaces flag: the watch registry keys watchers by (GVK, namespace) instead of a bare GVK, so a ResourceSelector with an explicit namespace watches just that namespace, and an empty ("match anywhere") selector fans out across only the configured namespaces instead of cluster-wide. Cluster-scoped resources are always let through.

Nothing needs to be set on the agents directly: a managed Cluster/SveltosCluster can carry the annotation agent.projectsveltos.io/watch-namespaces (a comma-separated namespace list), and addon-controller and classifier relay it down automatically. addon-controller passes it to drift-detection-manager's --watch-namespaces flag when deploying it in agentless mode, and also scopes its own stale-resource cleanup search to the same namespaces, so its own RBAC-restricted credential doesn't 403 on cleanup either. classifier does the same for sveltos-agent, threading the annotation into the manifest it deploys and folding its value into the deployment's config hash so a changed annotation triggers a redeploy rather than being silently ignored.
PRs: addon-controller #1939, classifier #504

Generic OIDC Workload Identity Provider
WorkloadIdentityConfig gains a fourth provider, OIDC, alongside AWS/GCP/Azure: a standard RFC 6749 client credentials grant against any compliant IdP (Dex, Keycloak, Okta, and similar), for managed clusters not on one of the three cloud providers with their own federation mechanism. Unlike the cloud cases, this is not secretless: Sveltos holds a standing client_id/client_secret in a referenced Secret and exchanges it directly at the IdP's token endpoint. The resulting token feeds into the same cache, proactive-refresh, and auth-failure eviction machinery the other three providers already use.
PR: libsveltos #675

Smooth ClusterProfile/Profile Transitions (transitionFrom)
Moving a cluster between profiles via a label swap used to force a full undeploy-then-redeploy cycle: the old profile tore down everything it managed, including resources identical to what the new profile was about to deploy, before the new one could even start. A ClusterProfile/Profile can now declare, via transitionFrom, that it replaces one or more named predecessors: teardown of the predecessor is deferred until the successor reaches Provisioned on that cluster, and the successor may take over the predecessor's resources in place, ignoring tier restrictions. Support spans addon-controller (the core deferral/takeover logic), sveltos-applier (equivalent handling for pull-mode clusters), and new documentation.
PRs: addon-controller #1951, sveltos #787


馃悶 Bug Fixes

addon-controller: RemoteURL Polling Interval Blocked Drift-Detection Recovery
A PolicyRef/KustomizationRef using RemoteURL with an Interval set NextReconcileTime on the ClusterSummary to schedule its periodic re-fetch, but that same field suppressed every other reconcile of that ClusterSummary until the cooldown expired, including one triggered by drift detection. With SyncMode: ContinuousWithDriftDetection and, say, a 10-minute RemoteURL interval, a configuration drift would sit unrecovered until that cooldown passed. NextReconcileTime is no longer set in this case.
PR: addon-controller #1929

ui-backend: Three Authentication and Authorization Bugs
/stats returned a 500 on a management cluster with no Cluster API installed; it now short-circuits to zero CAPI clusters when the CRD is absent. Every RBAC check (canListSveltosClusters, canGetClusterProfile, and similar) was sending the Kubernetes Kind as the SubjectAccessReview's resource field instead of the plural REST name RBAC rules actually use, so no real scoped ClusterRole could ever match, only a wildcard role like cluster-admin. And every SubjectAccessReview only ever set Spec.User, never Spec.Groups, so RBAC granted via a Group subject was silently denied regardless of what the role granted.
PR: ui-backend #181

dashboard: OIDC Login Rejected by Audience-Checking API Servers
The dashboard's OIDC login hardcoded its scope to openid profile email offline_access, requesting no specific resource. Providers that issue single-resource access tokens (Entra ID, notably) then audience the token to the dashboard's own app registration rather than the target API server, so

dashboard: OIDC Login Rejected by Audience-Checking API Servers
The dashboard's OIDC login hardcoded its scope to openid profile email offline_access, requesting no specific resource. Providers that issue single-resource access tokens (Entra ID, notably) then audience the token to the dashboard's own app registration rather than the target API server, so a Kubernetes API server that authorizes by audience (e.g. AKS with Microsoft Entra ID authorization) rejected it with "failed to validate token." A deployer can now set an optional VITE_OIDC_SCOPE/OIDC_SCOPE to request a resource-specific scope instead; unset, behavior is unchanged.
PR: dashboard #187

libsveltos: Drift Exclusion Crashed on a Path Absent From the Helm Render
Helm's PostRenderer fed driftExclusion patches straight to kustomize with no missing-path check, unlike drift evaluation's own path, which already treats a remove on an absent path as a no-op. A chart render missing the excluded path failed hard instead of skipping it. The PostRenderer path now filters patches the same way drift evaluation does before handing them to kustomize.
PR: libsveltos #673

addon-controller: ClusterSummary Status Update Could Lose a Race
updateStatusForNonReferencedHelmReleases did a single Get plus a single Status Update with no conflict retry, unlike its two siblings on the same pass. A concurrent status write could bump the ClusterSummary's resourceVersion in between, losing the update to a resource-version conflict even though the Helm deploy had already succeeded: the feature hash never advanced, the Helm feature kept reporting Failed, and drift-detection registration was never reached. Now wrapped in the same conflict-retry the other two call sites already use.
PR: addon-controller #1937

addon-controller: Silent ResourceSummary Removal Failures
A failure removing a ResourceSummary, in either prepareForDeployment or cleanupBeforeFinalizerRemoval, was only logged, never written to ClusterSummary.status. An ongoing failure was invisible to kubectl get clustersummary: status just sat wherever it last was, silently retrying every reconcile with no visible sign anything was wrong. Both call sites now surface the error via status.
PR: addon-controller #1947

libsveltos: Auth-Rejected Clients and Workload-Identity Tokens Not Evicted From Cache
A cached client or workload-identity token rejected server-side for a reason its own recorded expiry doesn't predict (early revocation, an IdP restart, a permissions change) kept being reused until whatever proactive refresh window applied eventually caught up. GetKubernetesRestConfig/GetKubernetesClient and the workload-identity path now both wrap the returned config's transport so any 401/403 response, from any client built off it, evicts the corresponding cache entry immediately instead of waiting on a schedule.
PRs: libsveltos #674, libsveltos #676

addon-controller: Deferred Teardown Not Reflected in ClusterSummary Status
When teardown was deferred by a still-existing DependsOn dependent or a TransitionFrom successor not yet Provisioned, ClusterSummary.status.featureSummaries[].status stayed on whatever it was before, implying active work even though nothing was happening. status.dependencies already explained the wait; status itself did not. A new Blocked FeatureStatus value now reflects it directly.
PR: addon-controller #1953

Stop Polling Reports From Pull-Mode Clusters With a Dead sveltos-applier
healthcheck-manager, event-manager, and classifier each kept listing HealthCheckReports/EventReports/polling a pull-mode cluster every collection cycle regardless of whether its sveltos-applier agent was still sending a heartbeat. A cluster whose agent has died will never produce a new report, so this work, and its retry cadence, ran indefinitely for nothing. All three now check the agent's heartbeat status first and skip a cluster whose sveltos-applier has gone stale.
PRs: healthcheck-manager #430, event-manager #517, classifier #507


馃敡 Maintenance

  • All components advanced to Go v1.27.1
  • All components advanced to Cluster API v1.14.2