Changelog¶
The changelog format is based on Keep a Changelog.
This project uses Semantic Versioning - MAJOR.MINOR.PATCH
2.1.0 (2026-05-22)¶
No significant changes.
2.1.0 (2026-05-22)¶
Deprecated¶
The legacy
k8sexecution module (saltext.kubernetes.modules.k8s) is deprecated and emits aDeprecationWarningat import time. It will be removed in saltext-kubernetes 3.0.0. Use the modernkubernetesexecution module (kubernetesmod) instead, which is built on the official Kubernetes Python client and supports all current resource types.
Changed¶
Internal plumbing for the upcoming generic-apply path. New
saltext.kubernetes.utils._dynamicmodule wrapskubernetes.dynamic.DynamicClientwith a per-Configuration cache, an in-process resource-discovery cache (so repeated apply calls against the same kind don’t re-query OpenAPI), and helpersapply_manifest,get_object,list_resource,delete_objectthat surface clearCommandExecutionErrormessages for missing GVKs, missingmetadata.namespaceon namespaced kinds, and missingmetadata.name. Thekubernetesruntime dependency floor is bumped to>=24.2.0(required for reliableResource.server_side_applysemantics). The user-visiblekubernetes.applyexecution-module function andmanifest_present/manifest_absentstates that build on these primitives ship in a follow-up.Internal refactor: the per-kind metadata used by the resource-wait subsystem (
_wait_for_resource_status) is now centralised insaltext.kubernetes.utils._kinds._KIND_REGISTRY. Thekubernetesmod._wait_for_resource_statusfunction dispatches through this registry instead of carrying duplicatedresource_type → method_nameliteral dicts. Adding a new typed kind now requires one registry entry rather than two parallel dict updates. Public signature, kwargs, and return semantics of_wait_for_resource_statusare unchanged.
Fixed¶
Improved Kubernetes resource wait handling by making compound resource name resolution more consistent and normalizing configmap wait references. #25
Compatibility with both
kubernetes-client24-35 and 36+. The 36.0.0 release updated the OpenAPI generator and renamed several attributes / kwargs we depend on. The extension now detects which spelling the installed client exposes and routes through whichever is present, so a single saltext-kubernetes release works against any client>=24.2.0(our floor). Surfaces handled:V1PolicyRule.non_resource_ur_ls↔non_resource_urls;ApiClient.call_api(response_type=)↔response_types_map=; the exec-auth refresh hook now writes both legacy (api_key["authorization"]) and modern (api_key["BearerToken"]+api_key_prefix["BearerToken"]="Bearer") shapes so kubeconfig-exec-style auth (EKS / GKE) keeps working on both client versions. 11 new unit tests pin the shim contract on both spellings.
Added¶
Added support to manage statefulset resources in kubernetes clusters. #23
Added support to manage replicaset resources in kubernetes clusters. #25
Added support to manage daemonset resources in kubernetes clusters. #27
Added support to manage storageclass resources in kubernetes clusters. #30
Added node lifecycle operations:
kubernetes.cordon/kubernetes.uncordon(mark a node un/schedulable),kubernetes.taint/kubernetes.untaint(manage node taints with(key, effect)identity), andkubernetes.drain(cordon + evict managed pods via the eviction API, respecting PodDisruption Budgets). Drain skips DaemonSet-owned pods by default (ignore_daemonsets=True), refuses pods withemptyDirvolumes unlessdelete_emptydir_data=Trueorforce=True, refuses bare (uncontrolled) pods unlessforce=True, and supportsdisable_eviction=Trueto fall back to direct DELETE bypassing PDBs. Returns a structured report withevicted/skipped/errorslists. Companion idempotent state functions:kubernetes.node_cordoned,kubernetes.node_uncordoned,kubernetes.node_tainted,kubernetes.node_untainted. Drain itself is intentionally not exposed as a state — it’s an imperative operation, not a desired-state declaration.Added pod operations modules:
kubernetes.exec(run commands inside a Pod and capture stdout/stderr/retcode),kubernetes.logs(fetch logs withcontainer,previous,since_seconds,tail_lines,timestampsfilters),kubernetes.cp_toandkubernetes.cp_from(copy files into and out of a Pod via tar pipe through the exec subresource). All four are namespace-aware and honourcontainerfor multi-container Pods. The exec subresource websocket has no portable way to signal stdin EOF, so commands that wait for EOF (cat,tee) are bounded by a wall-clocktimeoutand surfaceretcode=-1if exceeded; the recommended idiom for stdin-bearing exec is a byte-bounded reader likehead -c N. Linux-only; Windows is unsupported because the cp path depends on POSIX tar semantics.Added rich authentication modes to the
kubernetesexecution module: in-cluster ServiceAccount (auto-detected when running in a pod), bearer token (kubernetes.api_key), basic auth (kubernetes.username/kubernetes.password), and explicit client certificate (kubernetes.client_cert/kubernetes.client_key/kubernetes.ca_cert). Proxy support added viakubernetes.proxy,kubernetes.no_proxy,kubernetes.proxy_headers. TLS verification toggled withkubernetes.verify_ssl. All options can also be provided viaK8S_AUTH_*environment variables (matching Ansible’skubernetes.corecollection) or as per-call kwargs. The legacy kubeconfig path is unchanged and remains the default. See the auth guide (docs/topics/auth.md) for details.Added six
kuberesource_*companion execution modules that ride on Salt’s resources subsystem to dispatch operations against individual Kubernetes resources by their bare ID.kuberesource_cmd(run, run_all, run_stdout — Pod-only),kuberesource_logs(fetch, tail — Pod-only),kuberesource_cp(to_pod, from_pod — Pod-only),kuberesource_node(cordon, uncordon, drain, taint, untaint — Node-only),kuberesource_workload(scale, restart, rollback — Deployment/StatefulSet/ReplicaSet/DaemonSet), andkuberesource_state(apply with the active resource’s identity exposed to the manifest’s Jinja template context). All six are dormant on stock Salt —__virtual__returns False unlesssalt.utils.resourcesis importable. They light up automatically on a Salt build that includes the resources branch, at which point dispatches likesalt 'pod:default/nginx-abc' kuberesource_cmd.run "echo hi"route to the correct typedkubernetes.*execution.Added support for RBAC resources: Role, RoleBinding, ClusterRole, ClusterRoleBinding, and ServiceAccount. Each gets the standard six-verb execution-module surface (
list_*,show_*,create_*,replace_*,patch_*,delete_*) and matching state functions (*_present,*_absent). Specs accept either snake_case or camelCase keys;roleRef.apiGroupdefaults torbac.authorization.k8s.io. Replace and patch surface a clear error when the operation would change a binding’s immutableroleRef, matching kubectl behaviour. ClusterRole supportsaggregationRulefor aggregated roles. ServiceAccount supportsautomountServiceAccountToken,imagePullSecrets, andsecrets.Added the Kubernetes resource type for Salt’s in-flight
resourcessubsystem (saltext.kubernetes.resource.kubernetes). The module ships dormant on stock Salt — its__virtual__returns False whensalt.utils.resourcesisn’t importable — and “lights up” automatically once a Salt build that includes the resources branch is in use. Implements the full lifecycle contract:init,initialized,discover,grains,grains_refresh,shutdown. On enabled clusters, declaring aresources.kubernetesblock in pillar publishes pods/deployments/nodes/etc. into the master’s resource registry, where they become first-class targets for grain-based and bare-ID targeting (e.g.salt -G 'app:nginx' kubernetes.show_pod).Added the user-visible generic-apply surface:
kubernetes.apply(server-side apply one or more manifests; accepts a dict, list of dicts, YAML string, or salt://sourcepath; supports Jinja templating, multi-document YAML, fieldManager, force_conflicts, dry_run, and per-namespace defaulting), andkubernetes.delete_manifest(the symmetric deletion path). Companion idempotent state functions:kubernetes.manifest_presentandkubernetes.manifest_absent. The state functions honour Salt’stest=Truemode by issuing a server-side dry-run apply through the API server’s own validation — admission webhook rejections surface duringstate.apply test=Truerather than at commit time. Unlike the typed CRUD path which silently scopes namespaced resources to"default", the apply path requires an explicit namespace (either inmetadata.namespaceor via thenamespaceparameter) and fails loudly otherwise.Added typed support for
PersistentVolume(cluster-scoped) andPersistentVolumeClaim(namespaced): 12 module functions and 4 state functions. Spec helpers validate the requiredaccessModesand (for PV)capacity/ (for PVC)resources. Replace and patch surface immutability errors clearly — most PV fields are immutable after binding, and PVCaccessModes,selector,volumeName, andstorageClassNameare immutable after binding. Spec helpers now do generic camelCase→snake_case translation for unmapped keys, so volume-backend fields likehostPath,nfs,csi,awsElasticBlockStorework without per-field map entries.Four additional kinds (
NetworkPolicy,ResourceQuota,LimitRange,PriorityClass) get registry entries — so the wait subsystem and_dynamic.get_objectrecognise them — but no typed CRUD wrappers. The recommended path for these iskubernetes.apply/kubernetes.manifest_present. See the new “Apply-only kinds” docs page.Added typed support for the batch kinds:
kubernetes.{jobs, show_job, create_job, replace_job, patch_job, delete_job}and the matchingcron_jobset, plus thekubernetes.{job,cron_job}_{present,absent}states.create_jobacceptswait_for_completion=Trueto block untilstatus.conditionsreportsComplete=True(or fail onFailed=True/ wall-clocktimeoutelapsed). CronJob spec validatesconcurrencyPolicy(Allow / Forbid / Replace) and requiresschedule. Job pod templates defaultrestartPolicytoNeverand rejectAlways(matching kubectl-create-job). Patch on these kinds passes the body through verbatim — unlike RBAC where the patch helper flattensspec:because those kinds have no real.spec, batch kinds have a genuine nested.spec(e.g.spec.suspend,spec.schedule) that must be preserved.Added typed support for three more kinds:
Ingress(NetworkingV1Api),HorizontalPodAutoscaler(autoscaling/v2 — modern), andPodDisruptionBudget(PolicyV1Api). 18 module functions and 6 state functions follow the same pattern as the other typed kinds. PDB validates that exactly one ofminAvailable/maxUnavailableis set (matching kubectl) and requires aselector. HPA spec validates the requiredscaleTargetRefandmaxReplicas. Spec helpers translate top-level camelCase keys (ingressClassName,scaleTargetRef,minReplicas,minAvailable, etc.) to the snake_case kwargs the V1*Spec constructors expect; nested fields in user-supplied dicts (e.g.pathTypeinside ingress rules,averageUtilizationinside HPA targets) must use the wire camelCase names.Added workload + cluster operations:
kubernetes.scale(set replica counts on Deployment / StatefulSet / ReplicaSet via the/scalesubresource),kubernetes.restart(rolling restart of Deployment / StatefulSet / DaemonSet / ReplicaSet via thekubectl.kubernetes.io/restartedAtpod-template annotation),kubernetes.rollback(revert a Deployment to a previous revision by patching the pod template from the target ReplicaSet — works on all current K8s versions, doesn’t depend on the deprecated/rollbacksubresource), andkubernetes.cluster_info(server version, healthz, and available API groups). Scale uses PATCH rather than read-modify-write to avoid 409 conflicts from concurrent reconciliation by the deployment controller.New docs page
topics/examples-terraform-equivalents.mdtranslates the common Kubernetes orchestration patterns from HashiCorp’s Terraform Kubernetes provider into equivalent Salt SLS states: app deploy (Namespace+ConfigMap+Secret+Deployment+Service), RBAC (Role+RoleBinding+ServiceAccount), Ingress with cert-manager TLS, StatefulSet with PVC and StorageClass, multi-tenant namespace template (Quota+LimitRange+NetworkPolicy+RBAC), HPA+PDB, and CRD+custom resource. Each example includes the Terraform original side-by-side with the Salt equivalent and a note on what differs in the two models.Resources subsystem now supports declarative pillar-only inventory. Requires Salt >= 3008.0 (the resources subsystem under
salt.utils.resourcesships in 3008; the plug-in stays dormant on 3006/3007). Thekubernetesresource type accepts aresources:list in its pillar block (e.g.[{kind: deployment, namespace: prod, name: web}, ...]) which is returned verbatim fromdiscover()— no API call is made. Useful for air-gapped clusters, strict-RBAC scenarios where the discovery user lackslistpermission, bootstrap workflows that declare resources before they exist, and avoiding discovery cost on busy clusters. Pillar keymode:(one ofdiscover,pillar,merge) makes the precedence explicit; when omitted,pillaris inferred from the presence ofresources:, otherwisediscover. Inmergemode the declared list is unioned with API-discovered IDs. Also adds the previously-missingnodeandcustom_resource_definitionkinds to the registry, fixes typos in_DEFAULT_KINDS(stateful_set→statefulset,daemon_set→daemonset) that silently disabled discovery for those kinds, and expands_DEFAULT_KINDSto cover the typed first-class kind set so users get useful out-of-box discovery without explicit pillar opt-in.
2.0.0 (2026-04-20)¶
Breaking changes¶
Dropped legacy connection setup. Either
kubeconfigorkubeconfig-dataand (always)contextconfiguration is required now. This change affects backwards compatibility and may not work on very old versions of kubernetes.kubernetes.create_configmapwithsourceparameter now expects to receive a properly formatted spec with the configmap data in thedatakey. Previously, the loaded data was used as the data directly.
Changed¶
API responses now return
camelCasekeys matching Kubernetes YAML manifests instead ofsnake_case, and_presentstate functions usepatchinstead of delete-and-recreate (thereplaceparameter has been removed). #16
Fixed¶
Added Kubernetes patch functionality to the execution module for applying patch operations to cluster resources during runtime. Also fixed general idempotency issues in absent functions by checking resource existence before modifications. #16
Added¶
Added enhanced functionality including Jinja2 templating via
template_contextparameter,waitandtimeoutparameters for resource operations,secret_typeandmetadataparameters for secrets, and improved parameter validation across resource types. #10Added Kubernetes patch functionality to the execution module for applying patch operations to cluster resources during runtime. #16
1.1.0 (2025-01-14)¶
Changed¶
Updated
kubernetesmodto work with newer versions of the Kubernetes Python client. #1
1.0.1 (2023-12-29)¶
Initial release of saltext-kubernetes. This release tracks the functionality in the core Salt code base at this point.