Let me start by reading the knowledge graph and the pages manifest, then explore the source code.
Now let me examine the constants and exceptions:
Now let me check the apply_yaml function and the get_client function signature, plus see what ResourceConstants inherits:
Let me look for key public methods in resource.py that I might have missed (the file was truncated before):
Let me also check for import paths:
Now let me look at the NamespacedResource._base_body more carefully and check for anything more:
Now let me check what the Event class looks like for the events method reference:
Let me also check for generate_yaml_from_template:
That's a test utility. Let me check for the skip_existing_resource_creation_teardown function:
Now I have all the information needed. Let me write the comprehensive API reference page.
Resource and NamespacedResource API
Complete API reference for the Resource and NamespacedResource base classes, the get_client factory function, and supporting classes (ResourceEditor, ResourceList, NamespacedResourceList, KubeAPIVersion).
Import path:
from ocp_resources.resource import (
Resource,
NamespacedResource,
ResourceEditor,
ResourceList,
NamespacedResourceList,
get_client,
)
get_client
Factory function to obtain a Kubernetes DynamicClient.
from ocp_resources.resource import get_client
client = get_client(config_file="~/.kube/config")
| Parameter | Type | Default | Description |
|---|---|---|---|
config_file |
str \| None |
None |
Path to a kubeconfig file. Falls back to KUBECONFIG env var or ~/.kube/config. |
config_dict |
dict[str, Any] \| None |
None |
Dict with kubeconfig configuration. Mutually exclusive with config_file. |
context |
str \| None |
None |
Name of the kubeconfig context to use. |
client_configuration |
kubernetes.client.Configuration \| None |
None |
Pre-built Kubernetes client configuration object. |
persist_config |
bool |
True |
Whether to persist config file changes. |
temp_file_path |
str \| None |
None |
Path to a temporary kubeconfig file. |
try_refresh_token |
bool |
True |
Try to refresh the authentication token. |
username |
str \| None |
None |
Username for basic auth. Requires password and host. |
password |
str \| None |
None |
Password for basic auth. Requires username and host. |
host |
str \| None |
None |
Cluster host URL. |
verify_ssl |
bool \| None |
None |
Whether to verify SSL certificates. |
token |
str \| None |
None |
Bearer token for authentication. Requires host. |
fake |
bool |
False |
Return a FakeDynamicClient for testing without a cluster. |
generate_kubeconfig |
bool |
False |
Save the resolved kubeconfig to a temp file and attach the path to the client. |
Returns: DynamicClient | FakeDynamicClient
# Default kubeconfig
client = get_client()
# With explicit config file and context
client = get_client(config_file="/path/to/kubeconfig", context="my-cluster")
# Token-based auth
client = get_client(host="https://api.cluster.example.com:6443", token="sha256~abc123")
# Basic auth
client = get_client(host="https://api.cluster.example.com:6443", username="admin", password="secret")
# Fake client for unit testing
client = get_client(fake=True)
Note: If neither
config_filenorconfig_dictis provided, the client falls back to theKUBECONFIGenvironment variable, then~/.kube/config, and finally in-cluster configuration.
See Connecting to Clusters for connection patterns. See Testing Without a Cluster Using the Fake Client for fake=True usage.
Resource
from ocp_resources.resource import Resource
Base class for cluster-scoped Kubernetes/OpenShift resources (e.g., Namespace, Node, ClusterRole). Inherits from ResourceConstants. All concrete resource classes inherit from either Resource or NamespacedResource.
See Understanding the Resource Class Hierarchy for the inheritance model.
Class Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
api_group |
str |
"" |
API group for the resource (e.g., "apps", "batch"). |
api_version |
str |
"" |
Full API version string (e.g., "v1", "apps/v1"). Resolved automatically if api_group is set. |
singular_name |
str |
"" |
Singular resource name for API calls. Used to disambiguate when multiple resources match the same kind. |
timeout_seconds |
int |
60 |
Default timeout for API list/watch operations. |
Constructor
Resource(
client=client,
name="my-resource",
)
| Parameter | Type | Default | Description |
|---|---|---|---|
client |
DynamicClient \| None |
None |
Kubernetes dynamic client. Will be mandatory in the next major release. |
name |
str \| None |
None |
Resource name. Required unless yaml_file or kind_dict is provided. |
teardown |
bool |
True |
Whether this resource should be deleted when used as a context manager. |
yaml_file |
str \| None |
None |
Path to a YAML file defining the resource. Mutually exclusive with kind_dict. |
delete_timeout |
int |
240 |
Timeout in seconds for delete operations. |
dry_run |
bool |
False |
If True, create operations use dry-run mode. |
node_selector |
dict[str, Any] \| None |
None |
Node selector for scheduling. |
node_selector_labels |
dict[str, str] \| None |
None |
Node selector labels for scheduling. |
config_file |
str \| None |
None |
Path to kubeconfig. Deprecated; pass client instead. |
config_dict |
dict[str, Any] \| None |
None |
Kubeconfig dict. |
context |
str \| None |
None |
Kubeconfig context name. Deprecated; pass client instead. |
label |
dict[str, str] \| None |
None |
Labels to set on the resource. |
annotations |
dict[str, str] \| None |
None |
Annotations to set on the resource. |
api_group |
str |
"" |
Override the class-level api_group. |
hash_log_data |
bool |
True |
Hash sensitive fields (defined by keys_to_hash) in log output. |
ensure_exists |
bool |
False |
Check that the resource already exists on the cluster at init time. Raises ResourceNotFoundError if not. |
kind_dict |
dict[Any, Any] \| None |
None |
Complete resource dict. Mutually exclusive with yaml_file. Bypasses to_dict() logic. |
wait_for_resource |
bool |
False |
When used as a context manager, wait for the resource to exist after creation. |
schema_validation_enabled |
bool |
False |
Enable automatic OpenAPI schema validation on create() and update_replace(). |
Raises:
| Exception | Condition |
|---|---|
ValueError |
Both yaml_file and kind_dict are provided. |
NotImplementedError |
Neither api_group nor api_version is defined on the class. |
MissingRequiredArgumentError |
None of name, yaml_file, or kind_dict is provided. |
ResourceNotFoundError |
ensure_exists=True and the resource does not exist. |
from ocp_resources.namespace import Namespace
# Basic creation
ns = Namespace(client=client, name="my-namespace")
# From a YAML file
ns = Namespace(client=client, yaml_file="namespace.yaml")
# From a dict
ns = Namespace(client=client, kind_dict={"apiVersion": "v1", "kind": "Namespace", "metadata": {"name": "test"}})
# With labels and annotations
ns = Namespace(client=client, name="my-ns", label={"env": "test"}, annotations={"owner": "team-a"})
# Verify it already exists
ns = Namespace(client=client, name="default", ensure_exists=True)
Context Manager Protocol
Resource supports the Python context manager protocol for automatic creation and cleanup.
from ocp_resources.namespace import Namespace
with Namespace(client=client, name="temp-ns") as ns:
# Resource is created on __enter__
print(ns.name)
# Resource is deleted on __exit__ (if teardown=True)
| Method | Description |
|---|---|
__enter__() |
Calls deploy(wait=self.wait_for_resource). Registers a SIGINT handler on the main thread to ensure cleanup on Ctrl+C. Returns self. |
__exit__(...) |
Calls clean_up() if teardown=True. Raises ResourceTeardownError if cleanup fails. |
Tip: Set
teardown=Falseto prevent automatic deletion on context exit.
CRUD Methods
create
def create(
self,
wait: bool = False,
exceptions_dict: dict[type[Exception], list[str]] = ...,
) -> ResourceInstance | None
Create the resource on the cluster.
| Parameter | Type | Default | Description |
|---|---|---|---|
wait |
bool |
False |
Wait for the resource to exist after creation. |
exceptions_dict |
dict[type[Exception], list[str]] |
DEFAULT_CLUSTER_RETRY_EXCEPTIONS \| PROTOCOL_ERROR_EXCEPTION_DICT |
Exceptions to retry on. |
Returns: ResourceInstance | None
Raises: ValidationError if schema_validation_enabled=True and the resource dict is invalid.
ns = Namespace(client=client, name="my-ns")
ns.create(wait=True)
delete
def delete(
self,
wait: bool = False,
timeout: int = 240,
body: dict[str, Any] | None = None,
) -> bool
Delete the resource from the cluster.
| Parameter | Type | Default | Description |
|---|---|---|---|
wait |
bool |
False |
Wait for the resource to be fully deleted. |
timeout |
int |
240 |
Timeout in seconds when wait=True. |
body |
dict[str, Any] \| None |
None |
Optional delete options body. |
Returns: bool — True if deleted or not found; False only if wait timed out.
ns.delete(wait=True, timeout=120)
update
def update(self, resource_dict: dict[str, Any]) -> None
Patch the resource with a merge-patch (application/merge-patch+json). Only updates the fields present in resource_dict.
| Parameter | Type | Description |
|---|---|---|
resource_dict |
dict[str, Any] |
Partial resource dictionary with fields to update. |
Note: Schema validation is not applied on
update()because patches are partial and would fail full-schema validation.
ns.update(resource_dict={"metadata": {"labels": {"env": "staging"}}})
update_replace
def update_replace(self, resource_dict: dict[str, Any]) -> None
Replace the full resource. Use this to remove existing fields (unlike update(), which only adds/modifies).
| Parameter | Type | Description |
|---|---|---|
resource_dict |
dict[str, Any] |
Complete resource dictionary to replace with. |
Raises: ValidationError if schema_validation_enabled=True and the dict is invalid.
full_dict = ns.instance.to_dict()
full_dict["metadata"]["labels"] = {"new-label": "only"}
ns.update_replace(resource_dict=full_dict)
Deploy / Clean Up
deploy
def deploy(self, wait: bool = False) -> Self
Create the resource (respects REUSE_IF_RESOURCE_EXISTS environment variable).
| Parameter | Type | Default | Description |
|---|---|---|---|
wait |
bool |
False |
Wait for the resource after creation. |
Returns: Self
See Environment Variables and Configuration for REUSE_IF_RESOURCE_EXISTS details.
clean_up
def clean_up(self, wait: bool = True, timeout: int | None = None) -> bool
Delete the resource (respects SKIP_RESOURCE_TEARDOWN environment variable).
| Parameter | Type | Default | Description |
|---|---|---|---|
wait |
bool |
True |
Wait for deletion to complete. |
timeout |
int \| None |
None |
Timeout in seconds. Defaults to delete_timeout. |
Returns: bool — True if deleted successfully.
See Environment Variables and Configuration for SKIP_RESOURCE_TEARDOWN details.
Query Methods and Properties
exists
@property
def exists(self) -> ResourceInstance | None
Check if the resource exists on the cluster.
Returns: ResourceInstance if found, None if not.
if ns.exists:
print("Namespace exists")
instance
@property
def instance(self) -> ResourceInstance
Get the live resource instance from the cluster. Retries on transient cluster errors.
Returns: ResourceInstance
Raises: NotFoundError if the resource does not exist.
resource_version = ns.instance.metadata.resourceVersion
status
@property
def status(self) -> str
Get status.phase from the resource instance.
Returns: str — The status phase string (e.g., "Running", "Active", "Pending").
print(ns.status) # "Active"
labels
@property
def labels(self) -> ResourceField
Get resource labels from metadata.labels.
Returns: ResourceField
for key, value in ns.labels.items():
print(f"{key}={value}")
kind
@ClassProperty
def kind(cls) -> str | None
Get the resource kind name derived from the class hierarchy. This is a class-level property — accessible on both the class and instances.
Returns: str | None
from ocp_resources.namespace import Namespace
print(Namespace.kind) # "Namespace"
api
@property
def api(self) -> ResourceInstance
Get the resource API object (shortcut for full_api() with no extra kwargs).
Returns: ResourceInstance
full_api
def full_api(self, **kwargs: Any) -> ResourceInstance
Get the resource API object with optional filtering kwargs.
| Keyword Argument | Description |
|---|---|
pretty |
Pretty-print output. |
_continue |
Continuation token for list pagination. |
field_selector |
Filter by field. |
label_selector |
Filter by label. |
limit |
Maximum number of results. |
resource_version |
Filter by resource version. |
timeout_seconds |
Request timeout. |
watch |
Enable watch mode. |
Returns: ResourceInstance
Class Method: get
@classmethod
def get(
cls,
client: DynamicClient | None = None,
dyn_client: DynamicClient | None = None,
config_file: str = "",
singular_name: str = "",
exceptions_dict: dict[type[Exception], list[str]] = ...,
raw: bool = False,
context: str | None = None,
*args: Any,
**kwargs: Any,
) -> Generator[Any, None, None]
List resources of this kind from the cluster.
| Parameter | Type | Default | Description |
|---|---|---|---|
client |
DynamicClient \| None |
None |
Kubernetes client. |
dyn_client |
DynamicClient \| None |
None |
Deprecated alias for client. |
config_file |
str |
"" |
Path to kubeconfig. Deprecated; pass client. |
singular_name |
str |
"" |
Singular resource name for disambiguation. |
exceptions_dict |
dict |
DEFAULT_CLUSTER_RETRY_EXCEPTIONS |
Exceptions to retry. |
raw |
bool |
False |
If True, yield raw ResourceInstance objects instead of wrapper instances. |
context |
str \| None |
None |
Kubeconfig context. Deprecated; pass client. |
**kwargs |
Passed through to the API (e.g., label_selector, field_selector). |
Returns: Generator of resource instances.
Note: For
Resource(cluster-scoped), yielded objects are constructed withnameonly. ForNamespacedResource, yielded objects include bothnameandnamespace.
from ocp_resources.namespace import Namespace
for ns in Namespace.get(client=client):
print(ns.name)
# With label selector
for ns in Namespace.get(client=client, label_selector="env=production"):
print(ns.name)
# Raw mode
for raw_ns in Namespace.get(client=client, raw=True):
print(raw_ns.metadata.name, raw_ns.status.phase)
See Querying and Watching Resources for advanced list/filter patterns.
Static Method: get_all_cluster_resources
@staticmethod
def get_all_cluster_resources(
client: DynamicClient | None = None,
config_file: str = "",
context: str | None = None,
config_dict: dict[str, Any] | None = None,
*args: Any,
**kwargs: Any,
) -> Generator[ResourceField, None, None]
Yield all resources across all API groups in the cluster.
| Parameter | Type | Default | Description |
|---|---|---|---|
client |
DynamicClient \| None |
None |
Kubernetes client. |
**kwargs |
Passed to the API (e.g., label_selector). |
Yields: ResourceField
for resource in Resource.get_all_cluster_resources(client=client, label_selector="app=myapp"):
print(f"{resource.kind}: {resource.metadata.name}")
Wait Methods
wait
def wait(self, timeout: int = 240, sleep: int = 1) -> None
Wait until the resource exists on the cluster.
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout |
int |
240 |
Maximum wait time in seconds. |
sleep |
int |
1 |
Sleep interval between retries. |
Raises: TimeoutExpiredError if the resource does not exist within the timeout.
wait_deleted
def wait_deleted(self, timeout: int = 240) -> bool
Wait until the resource no longer exists.
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout |
int |
240 |
Maximum wait time in seconds. |
Returns: bool — True if deleted, False if timed out.
wait_for_status
def wait_for_status(
self,
status: str,
timeout: int = 240,
stop_status: str | None = None,
sleep: int = 1,
exceptions_dict: dict[type[Exception], list[str]] = ...,
) -> None
Wait for status.phase to reach the expected value.
| Parameter | Type | Default | Description |
|---|---|---|---|
status |
str |
— | Expected status phase string. |
timeout |
int |
240 |
Maximum wait time in seconds. |
stop_status |
str \| None |
None |
Stop and fail immediately if this status is reached. Defaults to Status.FAILED. |
sleep |
int |
1 |
Sleep interval between retries. |
exceptions_dict |
dict |
PROTOCOL_ERROR_EXCEPTION_DICT \| DEFAULT_CLUSTER_RETRY_EXCEPTIONS |
Exceptions to retry. |
Raises: TimeoutExpiredError if the desired status is not reached.
from ocp_resources.pod import Pod
pod.wait_for_status(status=Pod.Status.RUNNING, timeout=120)
wait_for_condition
def wait_for_condition(
self,
condition: str,
status: str,
timeout: int = 300,
sleep_time: int = 1,
reason: str | None = None,
message: str = "",
stop_condition: str | None = None,
stop_status: str = "True",
) -> None
Wait for a specific condition to reach the desired state.
| Parameter | Type | Default | Description |
|---|---|---|---|
condition |
str |
— | Condition type name (e.g., "Ready", "Available"). |
status |
str |
— | Expected condition status (e.g., "True", "False"). |
timeout |
int |
300 |
Maximum wait time in seconds. |
sleep_time |
int |
1 |
Interval between retries. |
reason |
str \| None |
None |
Expected condition reason. If set, must match exactly. |
message |
str |
"" |
Expected substring within the condition message. |
stop_condition |
str \| None |
None |
Condition type that, if matched, stops the wait and fails immediately. |
stop_status |
str |
"True" |
Status for stop_condition matching. |
Raises:
| Exception | Condition |
|---|---|
TimeoutExpiredError |
Condition not met within timeout. |
ConditionError |
stop_condition is detected with matching stop_status. |
ns.wait_for_condition(
condition="Ready",
status="True",
timeout=60,
)
See Waiting for Resource Conditions and Status for more patterns.
wait_for_conditions
def wait_for_conditions(self) -> None
Wait for the resource to have any conditions populated in its status. Uses a 30-second timeout.
Serialization
to_dict
def to_dict(self) -> None
Populate self.res with the intended dict representation of the resource. Called automatically before create(). Override this in subclasses to add resource-specific fields.
Note: If
kind_dictoryaml_filewas provided,to_dict()uses those directly instead of building from individual parameters.
to_yaml
def to_yaml(self) -> str
Returns: str — YAML string representation of the resource dict.
print(ns.to_yaml())
Watch / Events
watcher
def watcher(
self,
timeout: int,
resource_version: str = "",
) -> Generator[dict[str, Any], None, None]
Watch for changes to this specific resource.
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout |
int |
— | Watch duration in seconds. |
resource_version |
str |
"" |
Only return events after this version. Defaults to the version at resource creation time. |
Yields: Event dicts with keys type ("ADDED", "MODIFIED", "DELETED"), raw_object, and object.
for event in ns.watcher(timeout=30):
print(event["type"], event["object"].metadata.name)
events
def events(
self,
name: str = "",
label_selector: str = "",
field_selector: str = "",
resource_version: str = "",
timeout: int = 240,
) -> Generator[Any, Any, None]
Get Kubernetes events related to this resource.
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
"" |
Filter by event name. |
label_selector |
str |
"" |
Comma-separated key=value label filters. |
field_selector |
str |
"" |
Additional field selectors (auto-prefixed with involvedObject.name==<resource_name>). |
resource_version |
str |
"" |
Filter events by resource version. |
timeout |
int |
240 |
Timeout in seconds. |
Yields: Event objects.
for event in pod.events(field_selector="type==Warning", timeout=10):
print(event.object)
Validation
validate
def validate(self) -> None
Validate self.res against the OpenAPI schema for this resource kind. Called automatically during create() and update_replace() when schema_validation_enabled=True.
Raises: ValidationError if the resource dict is invalid.
pod = Pod(client=client, name="test", namespace="default")
pod.to_dict()
pod.validate() # Raises ValidationError on invalid spec
validate_dict (classmethod)
@classmethod
def validate_dict(cls, resource_dict: dict[str, Any]) -> None
Validate an arbitrary resource dictionary against the schema without creating a resource instance.
| Parameter | Type | Description |
|---|---|---|
resource_dict |
dict[str, Any] |
Complete resource dictionary. |
Raises: ValidationError if validation fails.
from ocp_resources.pod import Pod
Pod.validate_dict({
"apiVersion": "v1",
"kind": "Pod",
"metadata": {"name": "test"},
"spec": {"containers": [{"name": "web", "image": "nginx"}]},
})
See Validating Resources Against OpenAPI Schemas for full validation guide.
API Request
api_request
def api_request(
self,
method: str,
action: str,
url: str,
retry_params: dict[str, int] | None = None,
**params: Any,
) -> dict[str, Any]
Send a raw HTTP request to the resource's API endpoint. Used internally for subresource actions (e.g., VirtualMachine start/stop).
| Parameter | Type | Default | Description |
|---|---|---|---|
method |
str |
— | HTTP method ("GET", "PUT", "POST", etc.). |
action |
str |
— | Subresource action to append to the URL (e.g., "start", "stop"). |
url |
str |
— | Base URL of the resource. |
retry_params |
dict[str, int] \| None |
None |
Dict with timeout and sleep_time keys for retry behavior. |
**params |
Additional params passed to the HTTP request. |
Returns: dict[str, Any] — Parsed JSON response, or raw response data if not valid JSON.
Utility Methods
retry_cluster_exceptions (static)
@staticmethod
def retry_cluster_exceptions(
func: Callable,
exceptions_dict: dict[type[Exception], list[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS,
timeout: int = 10,
sleep_time: int = 1,
**kwargs: Any,
) -> Any
Retry a callable on transient cluster errors.
| Parameter | Type | Default | Description |
|---|---|---|---|
func |
Callable |
— | Function to call. |
exceptions_dict |
dict |
DEFAULT_CLUSTER_RETRY_EXCEPTIONS |
Map of exception types to message substrings to match. |
timeout |
int |
10 |
Total retry timeout in seconds. |
sleep_time |
int |
1 |
Sleep between retries. |
**kwargs |
Passed to func. |
Returns: The return value of func.
Raises: The last exception if timeout is reached.
get_condition_message
def get_condition_message(
self,
condition_type: str,
condition_status: str = "",
) -> str
Get the message for a specific condition.
| Parameter | Type | Default | Description |
|---|---|---|---|
condition_type |
str |
— | Condition type name. |
condition_status |
str |
"" |
If set, only return the message when the condition status matches. |
Returns: str — The condition message, or "" if not found or status doesn't match.
hash_resource_dict
def hash_resource_dict(self, resource_dict: dict[Any, Any]) -> dict[Any, Any]
Replace sensitive fields (defined by keys_to_hash) with "*******" for logging.
| Parameter | Type | Description |
|---|---|---|
resource_dict |
dict |
The resource dict to hash. |
Returns: dict — A copy with sensitive values replaced.
Tip: Override the
keys_to_hashproperty in subclasses to define which fields to mask.
keys_to_hash
@property
def keys_to_hash(self) -> list[str]
List of key paths to mask in logs. Uses > as separator, [] for list elements.
Returns: list[str] — Default: [] (no hashing).
# Example override in a Secret subclass:
@property
def keys_to_hash(self):
return ["data", "stringData"]
Inner Classes
Resource.Status
Pre-defined status phase constants (inherited from ResourceConstants).
| Constant | Value |
|---|---|
Status.SUCCEEDED |
"Succeeded" |
Status.FAILED |
"Failed" |
Status.DELETING |
"Deleting" |
Status.DEPLOYED |
"Deployed" |
Status.PENDING |
"Pending" |
Status.COMPLETED |
"Completed" |
Status.RUNNING |
"Running" |
Status.READY |
"Ready" |
Status.TERMINATING |
"Terminating" |
Status.ERROR |
"Error" |
Status.ACTIVE |
"Active" |
Status.SCHEDULING |
"Scheduling" |
Status.CRASH_LOOPBACK_OFF |
"CrashLoopBackOff" |
Status.IMAGE_PULL_BACK_OFF |
"ImagePullBackOff" |
pod.wait_for_status(status=Pod.Status.RUNNING)
Resource.Condition
Pre-defined condition type and status constants.
| Constant | Value |
|---|---|
Condition.READY |
"Ready" |
Condition.AVAILABLE |
"Available" |
Condition.DEGRADED |
"Degraded" |
Condition.PROGRESSING |
"Progressing" |
Condition.UPGRADEABLE |
"Upgradeable" |
Condition.Status.TRUE |
"True" |
Condition.Status.FALSE |
"False" |
Condition.Status.UNKNOWN |
"Unknown" |
ns.wait_for_condition(
condition=Resource.Condition.READY,
status=Resource.Condition.Status.TRUE,
)
Resource.ApiGroup
Pre-defined API group string constants. A selection of commonly used values:
| Constant | Value |
|---|---|
ApiGroup.APPS |
"apps" |
ApiGroup.BATCH |
"batch" |
ApiGroup.NETWORKING_K8S_IO |
"networking.k8s.io" |
ApiGroup.RBAC_AUTHORIZATION_K8S_IO |
"rbac.authorization.k8s.io" |
ApiGroup.STORAGE_K8S_IO |
"storage.k8s.io" |
ApiGroup.CONFIG_OPENSHIFT_IO |
"config.openshift.io" |
ApiGroup.KUBEVIRT_IO |
"kubevirt.io" |
ApiGroup.CDI_KUBEVIRT_IO |
"cdi.kubevirt.io" |
ApiGroup.ROUTE_OPENSHIFT_IO |
"route.openshift.io" |
ApiGroup.MACHINE_OPENSHIFT_IO |
"machine.openshift.io" |
Note: Over 100 API group constants are available. Use IDE auto-complete to discover all values.
Resource.ApiVersion
| Constant | Value |
|---|---|
ApiVersion.V1 |
"v1" |
ApiVersion.V1BETA1 |
"v1beta1" |
ApiVersion.V1ALPHA1 |
"v1alpha1" |
ApiVersion.V1ALPHA3 |
"v1alpha3" |
NamespacedResource
from ocp_resources.resource import NamespacedResource
Base class for namespace-scoped resources (e.g., Pod, Deployment, Service, ConfigMap). Extends Resource with namespace awareness.
Constructor
NamespacedResource(
client=client,
name="my-pod",
namespace="my-namespace",
)
All parameters from Resource are accepted, plus:
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
str \| None |
None |
Kubernetes namespace. Required unless yaml_file or kind_dict is provided. |
Raises: MissingRequiredArgumentError if neither (name + namespace) nor yaml_file / kind_dict is provided.
from ocp_resources.pod import Pod
pod = Pod(
client=client,
name="nginx",
namespace="default",
label={"app": "web"},
)
Overridden Methods
instance
@property
def instance(self) -> ResourceInstance
Get the live resource instance, scoped to self.namespace.
Returns: ResourceInstance
to_dict
def to_dict(self) -> None
Populates self.res and sets metadata.namespace. If using yaml_file or kind_dict, reads the namespace from the YAML/dict.
Raises: MissingRequiredArgumentError if namespace is still not set after processing.
get (classmethod)
Behaves like Resource.get(), but yields instances constructed with both name and namespace.
from ocp_resources.pod import Pod
for pod in Pod.get(client=client, namespace="default"):
print(f"{pod.namespace}/{pod.name}")
# With label selector
for pod in Pod.get(client=client, namespace="default", label_selector="app=web"):
print(pod.name)
ResourceEditor
from ocp_resources.resource import ResourceEditor
Temporarily patch resources and automatically restore original values. Designed for test scenarios.
Constructor
ResourceEditor(
patches: dict[Any, Any],
action: str = "update",
user_backups: dict[Any, Any] | None = None,
)
| Parameter | Type | Default | Description |
|---|---|---|---|
patches |
dict |
— | Map of {Resource: patch_dict}. |
action |
str |
"update" |
"update" for merge-patch, "replace" for full replacement. |
user_backups |
dict \| None |
None |
Pre-computed backup dicts. If provided, skips automatic backup creation. |
Context Manager Usage
from ocp_resources.resource import ResourceEditor
from ocp_resources.namespace import Namespace
ns = Namespace(client=client, name="my-ns", ensure_exists=True)
with ResourceEditor(
patches={ns: {"metadata": {"labels": {"temporary": "true"}}}}
) as editor:
# Labels are patched
assert ns.instance.metadata.labels.temporary == "true"
# Labels are restored to original values
Methods
| Method | Signature | Description |
|---|---|---|
update |
update(backup_resources: bool = False) -> None |
Apply patches. If backup_resources=True, back up original values first. |
restore |
restore() -> None |
Restore all backed-up values. |
Properties
| Property | Type | Description |
|---|---|---|
backups |
dict[Any, Any] |
Backed-up original values for each patched resource. |
patches |
dict[Any, Any] |
The patches dict from the constructor. |
Warning: The
DynamicClientused to obtain the resource objects must have sufficient privileges to patch and replace resources.
See Editing Resources Temporarily with ResourceEditor for detailed patterns.
ResourceList
from ocp_resources.resource import ResourceList
Create and manage N copies of a cluster-scoped resource with indexed names.
Constructor
ResourceList(
resource_class: type[Resource],
num_resources: int,
client: DynamicClient,
**kwargs: Any,
)
| Parameter | Type | Description |
|---|---|---|
resource_class |
type[Resource] |
The resource class to instantiate. |
num_resources |
int |
Number of resource copies to create. |
client |
DynamicClient |
Kubernetes client. |
**kwargs |
Passed to each resource constructor. Must include name (used as base name). |
Resources are named {name}-1, {name}-2, ..., {name}-N.
from ocp_resources.namespace import Namespace
from ocp_resources.resource import ResourceList
namespaces = ResourceList(
resource_class=Namespace,
num_resources=3,
client=client,
name="test-ns",
)
with namespaces:
# Creates test-ns-1, test-ns-2, test-ns-3
for ns in namespaces:
print(ns.name)
# All three namespaces are deleted
Methods (inherited from BaseResourceList)
| Method | Signature | Returns | Description |
|---|---|---|---|
deploy |
deploy(wait=False) |
list[Resource] |
Deploy all resources. |
clean_up |
clean_up(wait=True) |
bool |
Delete all resources in reverse order. |
__len__ |
__len__() |
int |
Number of resources. |
__getitem__ |
__getitem__(index) |
Resource |
Access by index. |
__iter__ |
__iter__() |
Generator |
Iterate over resources. |
NamespacedResourceList
from ocp_resources.resource import NamespacedResourceList
Create one instance of a namespaced resource in each namespace from a ResourceList.
Constructor
NamespacedResourceList(
resource_class: type[NamespacedResource],
namespaces: ResourceList,
client: DynamicClient,
**kwargs: Any,
)
| Parameter | Type | Description |
|---|---|---|
resource_class |
type[NamespacedResource] |
The namespaced resource class (e.g., Pod). |
namespaces |
ResourceList |
A ResourceList of Namespace resources. |
client |
DynamicClient |
Kubernetes client. |
**kwargs |
Passed to each resource constructor. Must include name. |
Raises: TypeError if any resource in namespaces is not a Namespace.
from ocp_resources.namespace import Namespace
from ocp_resources.pod import Pod
from ocp_resources.resource import ResourceList, NamespacedResourceList
namespaces = ResourceList(
resource_class=Namespace, num_resources=2, client=client, name="test-ns"
)
pods = NamespacedResourceList(
resource_class=Pod,
namespaces=namespaces,
client=client,
name="nginx",
)
with namespaces:
with pods:
# Creates nginx in test-ns-1 and test-ns-2
for pod in pods:
print(f"{pod.namespace}/{pod.name}")
See Managing Bulk Resources with ResourceList for full usage patterns.
KubeAPIVersion
from ocp_resources.resource import KubeAPIVersion
Implements Kubernetes API versioning with comparison operators. Extends packaging.version.Version.
Constructor
KubeAPIVersion(vstring: str)
| Parameter | Type | Description |
|---|---|---|
vstring |
str |
Version string (e.g., "v1", "v1beta1", "v1alpha2"). |
Raises: ValueError if the version string does not conform to Kubernetes versioning.
Ordering
Versions are ordered: v1alpha1 < v1alpha2 < v1beta1 < v1beta2 < v1 < v2.
assert KubeAPIVersion("v1") > KubeAPIVersion("v1beta1")
assert KubeAPIVersion("v1beta1") > KubeAPIVersion("v1alpha1")
assert KubeAPIVersion("v1") == KubeAPIVersion("v1")
Exceptions
All exceptions are importable from ocp_resources.exceptions.
from ocp_resources.exceptions import (
MissingRequiredArgumentError,
ResourceTeardownError,
ValidationError,
ConditionError,
)
| Exception | Raised By | Description |
|---|---|---|
MissingRequiredArgumentError |
Resource.__init__, NamespacedResource.__init__, NamespacedResource._base_body |
Required parameters (name, namespace) not provided. |
ResourceTeardownError |
Resource.__exit__ |
clean_up() returned False during context manager exit. |
ValidationError |
validate(), validate_dict(), create(), update_replace() |
Resource dict fails OpenAPI schema validation. Has message, path, and schema_error attributes. |
ConditionError |
wait_for_condition() |
A stop_condition was detected during condition waiting. |
MissingResourceResError |
Resource._base_body |
Deprecated. self.res is empty after _base_body(). |
Timeout Constants
Available from ocp_resources.utils.constants:
from ocp_resources.utils.constants import (
TIMEOUT_1SEC, # 1
TIMEOUT_5SEC, # 5
TIMEOUT_10SEC, # 10
TIMEOUT_30SEC, # 30
TIMEOUT_1MINUTE, # 60
TIMEOUT_2MINUTES, # 120
TIMEOUT_4MINUTES, # 240
TIMEOUT_10MINUTES, # 600
)
Module-Level Functions
replace_key_with_hashed_value
from ocp_resources.resource import replace_key_with_hashed_value
replace_key_with_hashed_value(resource_dict: dict, key_name: str) -> dict
Recursively replace the value at a key path with "*******". Supports dict paths (a>b>c) and list paths (a>b[]>c).
| Parameter | Type | Description |
|---|---|---|
resource_dict |
dict |
The nested dictionary. |
key_name |
str |
Key path using > as separator, [] for list elements. |
Returns: dict — A deep copy with the value replaced.
data = {"spec": {"secret": {"token": "sensitive"}}}
hashed = replace_key_with_hashed_value(data, "spec>secret>token")
# {"spec": {"secret": {"token": "*******"}}}
# With list path
data = {"spec": {"containers": [{"env": [{"value": "secret"}]}]}}
hashed = replace_key_with_hashed_value(data, "spec>containers[]>env[]>value")