saltext.kubernetes.utils._dynamic

Internal dynamic-client wrapper for the saltext-kubernetes extension.

Wraps kubernetes.dynamic.DynamicClient with the small helpers the generic-apply / generic-patch / generic-read code paths need:

  • get_dynamic_client() — lazily-cached client per process, rebuilt when the auth Configuration changes (which happens whenever _setup_conn runs against a different kubeconfig/host).

  • get_resource() — resolves a (api_version, kind) pair to a kubernetes.dynamic.Resource, with a small in-process cache keyed by (group/version, kind) to avoid re-running API discovery on every call.

  • apply_manifest() — performs a server-side apply against the resolved resource, surfacing the field-manager and force-conflicts knobs that kubectl apply --server-side exposes.

  • patch_object() — generic kind-agnostic patch with selectable patch type (strategic / RFC 7396 merge / RFC 6902 json-patch).

  • get_object(), delete_object(), list_resource() — generic read/delete/list-by-GVK counterparts to the typed CRUD wrappers in saltext.kubernetes.modules.kubernetesmod.

This module is internal. Public callers should never import from here — every helper has a public counterpart in the kubernetes execution module (saltext.kubernetes.modules.kubernetesmod) that adds the user-facing concerns these helpers deliberately omit:

  • connection lifecycle (_setup_conn / _cleanup around each call)

  • kwarg marshalling from the Salt loader (kubeconfig, context, cluster alias, env-var precedence, etc.)

  • kind-name inference from the typed kind-registry so callers can pass kind="Deployment" without spelling out api_version="apps/v1"

  • source-file rendering, multi-doc YAML, diff/idempotency tracking, test=True plumbing on the apply path

In short: this module’s functions are pure GVK plumbing, and they assume an already-installed default Configuration on kubernetes.client.Configuration. The public kubernetes.* execution-module functions are the thin wrappers that bring those preconditions about.

Public ↔ internal counterparts:

kubernetes.apply

apply_manifest()

kubernetes.patch_object

patch_object()

kubernetes.get_object

get_object()

kubernetes.delete_manifest

delete_object()

kubernetes.list_*

list_resource()

Added in version 2.1.0.

saltext.kubernetes.utils._dynamic.get_dynamic_client() DynamicClient[source]

Return a cached DynamicClient bound to the active default Configuration. Building the discoverer is expensive (an API discovery round-trip), so we hold one per Configuration instance.

saltext.kubernetes.utils._dynamic.get_resource(api_version: str, kind: str) Resource[source]

Resolve (api_version, kind) to a Resource via API discovery.

api_version may be either a bare core version ("v1") or a group/version ("apps/v1", "rbac.authorization.k8s.io/v1").

Raises CommandExecutionError with a clear message when the GVK isn’t known to the cluster (e.g. CRD not installed, typo’d apiVersion, or the user’s RBAC scope can’t see the API).

saltext.kubernetes.utils._dynamic.invalidate_caches() None[source]

Drop the dynamic-client and resource caches. Call after creating a CustomResourceDefinition in the same Salt run as the CR that uses it; otherwise the discoverer’s snapshot won’t include the new GVK.

saltext.kubernetes.utils._dynamic.apply_manifest(manifest: dict, field_manager: str = 'salt', force_conflicts: bool = False, dry_run: bool = False) dict[source]

Server-side apply manifest and return the applied object.

manifest must include apiVersion, kind and metadata.name. Namespaced resources must include metadata.namespace (the typed CRUD paths default to "default"; we deliberately do not, because silently scoping a manifest to default is a footgun).

The HTTP request is a PATCH with Content-Type: application/apply-patch+yaml, fieldManager set to field_manager, and force=true when force_conflicts is set. dry_run=True adds dryRun=All so the API server validates the manifest and reports the resulting object without persisting changes.

Raises CommandExecutionError for both API-side errors (404, conflicts, validation rejections) and client-side issues (missing apiVersion/kind, bad GVK).

saltext.kubernetes.utils._dynamic.patch_object(api_version: str, kind: str, name: str, patch, namespace: str | None = None, patch_type: str = 'strategic', field_manager: str | None = None, dry_run: bool = False) dict[source]

Patch an object by GVK with a caller-selected patch type.

Internal plumbing for the public saltext.kubernetes.modules.kubernetesmod.patch_object(). That public function is the one users call from Salt; it handles connection setup, accepts the Salt-loader kwarg conventions, and can infer api_version from the typed kind-registry when the caller omits it. This function assumes both are already resolved — api_version and kind must be supplied, and a default kubernetes.client.Configuration must already be installed (as _setup_conn() installs on every call).

patch_type selects the HTTP Content-Type and, with it, the semantics of how patch is interpreted server-side:

  • "strategic"application/strategic-merge-patch+json (kubectl’s default; works only on built-in kinds with registered strategic-merge directives).

  • "merge" / "json-merge"application/merge-patch+json (RFC 7396); whole-object replacement at each key. Works on CRDs and any kind.

  • "json" / "json-patch"application/json-patch+json (RFC 6902); patch must be a list of operation dicts like [{"op": "replace", "path": "/spec/replicas", "value": 5}].

Returns the patched object as a dict (same shape as apply_manifest()).

saltext.kubernetes.utils._dynamic.list_resource(api_version: str, kind: str, namespace: str | None = None, label_selector: str | None = None, field_selector: str | None = None) list[dict][source]

Generic list-by-GVK. Returns a list of object dicts.

Used by the kubernetes.list_ execution-module function (PR10).

saltext.kubernetes.utils._dynamic.get_object(api_version: str, kind: str, name: str, namespace: str | None = None) dict | None[source]

Generic read-by-GVK. Returns None when the object doesn’t exist (matching the existing typed show_* functions’ behaviour).

saltext.kubernetes.utils._dynamic.delete_object(api_version: str, kind: str, name: str, namespace: str | None = None, propagation_policy: str | None = None, grace_period_seconds: int | None = None) dict | None[source]

Generic delete-by-GVK. Returns None if the object was already absent (404 swallowed); otherwise returns the API server’s response body.