Coverage for ocp_resources/pod.py: 34%
170 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-30 10:51 +0200
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-30 10:51 +0200
1# Generated using https://github.com/RedHatQE/openshift-python-wrapper/blob/main/scripts/resource/README.md
3import json
5from typing import Any, Dict, List, Optional
7import kubernetes
8from timeout_sampler import TimeoutWatch
10from ocp_resources.utils.constants import TIMEOUT_5SEC
11from ocp_resources.exceptions import ExecOnPodError
12from ocp_resources.node import Node
14from ocp_resources.resource import NamespacedResource, MissingRequiredArgumentError
17class Pod(NamespacedResource):
18 """
19 Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts.
20 """
22 api_version: str = NamespacedResource.ApiVersion.V1
24 def __init__(
25 self,
26 active_deadline_seconds: Optional[int] = None,
27 affinity: Optional[Dict[str, Any]] = None,
28 automount_service_account_token: Optional[bool] = None,
29 containers: Optional[List[Any]] = None,
30 dns_config: Optional[Dict[str, Any]] = None,
31 dns_policy: Optional[str] = "",
32 enable_service_links: Optional[bool] = None,
33 ephemeral_containers: Optional[List[Any]] = None,
34 host_aliases: Optional[List[Any]] = None,
35 host_ipc: Optional[bool] = None,
36 host_network: Optional[bool] = None,
37 host_pid: Optional[bool] = None,
38 host_users: Optional[bool] = None,
39 hostname: Optional[str] = "",
40 image_pull_secrets: Optional[List[Any]] = None,
41 init_containers: Optional[List[Any]] = None,
42 node_name: Optional[str] = "",
43 node_selector: Optional[Dict[str, Any]] = None,
44 os: Optional[Dict[str, Any]] = None,
45 overhead: Optional[Dict[str, Any]] = None,
46 preemption_policy: Optional[str] = "",
47 priority: Optional[int] = None,
48 priority_class_name: Optional[str] = "",
49 readiness_gates: Optional[List[Any]] = None,
50 resource_claims: Optional[List[Any]] = None,
51 restart_policy: Optional[str] = "",
52 runtime_class_name: Optional[str] = "",
53 scheduler_name: Optional[str] = "",
54 scheduling_gates: Optional[List[Any]] = None,
55 security_context: Optional[Dict[str, Any]] = None,
56 service_account: Optional[str] = "",
57 service_account_name: Optional[str] = "",
58 set_hostname_as_fqdn: Optional[bool] = None,
59 share_process_namespace: Optional[bool] = None,
60 subdomain: Optional[str] = "",
61 termination_grace_period_seconds: Optional[int] = None,
62 tolerations: Optional[List[Any]] = None,
63 topology_spread_constraints: Optional[List[Any]] = None,
64 volumes: Optional[List[Any]] = None,
65 **kwargs: Any,
66 ) -> None:
67 """
68 Args:
69 active_deadline_seconds (int): Optional duration in seconds the pod may be active on the node
70 relative to StartTime before the system will actively try to mark
71 it failed and kill associated containers. Value must be a positive
72 integer.
74 affinity (Dict[str, Any]): Affinity is a group of affinity scheduling rules.
76 automount_service_account_token (bool): AutomountServiceAccountToken indicates whether a service account token
77 should be automatically mounted.
79 containers (List[Any]): List of containers belonging to the pod. Containers cannot currently
80 be added or removed. There must be at least one container in a
81 Pod. Cannot be updated.
83 dns_config (Dict[str, Any]): PodDNSConfig defines the DNS parameters of a pod in addition to those
84 generated from DNSPolicy.
86 dns_policy (str): Set DNS policy for the pod. Defaults to "ClusterFirst". Valid values
87 are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or
88 'None'. DNS parameters given in DNSConfig will be merged with the
89 policy selected with DNSPolicy. To have DNS options set along with
90 hostNetwork, you have to specify DNS policy explicitly to
91 'ClusterFirstWithHostNet'. Possible enum values: -
92 `"ClusterFirst"` indicates that the pod should use cluster DNS
93 first unless hostNetwork is true, if it is available, then fall
94 back on the default (as determined by kubelet) DNS settings. -
95 `"ClusterFirstWithHostNet"` indicates that the pod should use
96 cluster DNS first, if it is available, then fall back on the
97 default (as determined by kubelet) DNS settings. - `"Default"`
98 indicates that the pod should use the default (as determined by
99 kubelet) DNS settings. - `"None"` indicates that the pod should
100 use empty DNS settings. DNS parameters such as nameservers and
101 search paths should be defined via DNSConfig.
103 enable_service_links (bool): EnableServiceLinks indicates whether information about services should
104 be injected into pod's environment variables, matching the syntax
105 of Docker links. Optional: Defaults to true.
107 ephemeral_containers (List[Any]): List of ephemeral containers run in this pod. Ephemeral containers may
108 be run in an existing pod to perform user-initiated actions such
109 as debugging. This list cannot be specified when creating a pod,
110 and it cannot be modified by updating the pod spec. In order to
111 add an ephemeral container to an existing pod, use the pod's
112 ephemeralcontainers subresource.
114 host_aliases (List[Any]): HostAliases is an optional list of hosts and IPs that will be injected
115 into the pod's hosts file if specified.
117 host_ipc (bool): Use the host's ipc namespace. Optional: Default to false.
119 host_network (bool): Host networking requested for this pod. Use the host's network
120 namespace. If this option is set, the ports that will be used must
121 be specified. Default to false.
123 host_pid (bool): Use the host's pid namespace. Optional: Default to false.
125 host_users (bool): Use the host's user namespace. Optional: Default to true. If set to
126 true or not present, the pod will be run in the host user
127 namespace, useful for when the pod needs a feature only available
128 to the host user namespace, such as loading a kernel module with
129 CAP_SYS_MODULE. When set to false, a new userns is created for the
130 pod. Setting false is useful for mitigating container breakout
131 vulnerabilities even allowing users to run their containers as
132 root without actually having root privileges on the host. This
133 field is alpha-level and is only honored by servers that enable
134 the UserNamespacesSupport feature.
136 hostname (str): Specifies the hostname of the Pod If not specified, the pod's hostname
137 will be set to a system-defined value.
139 image_pull_secrets (List[Any]): ImagePullSecrets is an optional list of references to secrets in the
140 same namespace to use for pulling any of the images used by this
141 PodSpec. If specified, these secrets will be passed to individual
142 puller implementations for them to use. More info:
143 https://kubernetes.io/docs/concepts/containers/images#specifying-
144 imagepullsecrets-on-a-pod
146 init_containers (List[Any]): List of initialization containers belonging to the pod. Init
147 containers are executed in order prior to containers being
148 started. If any init container fails, the pod is considered to
149 have failed and is handled according to its restartPolicy. The
150 name for an init container or normal container must be unique
151 among all containers. Init containers may not have Lifecycle
152 actions, Readiness probes, Liveness probes, or Startup probes. The
153 resourceRequirements of an init container are taken into account
154 during scheduling by finding the highest request/limit for each
155 resource type, and then using the max of of that value or the sum
156 of the normal containers. Limits are applied to init containers in
157 a similar fashion. Init containers cannot currently be added or
158 removed. Cannot be updated. More info:
159 https://kubernetes.io/docs/concepts/workloads/pods/init-
160 containers/
162 node_name (str): NodeName is a request to schedule this pod onto a specific node. If it
163 is non-empty, the scheduler simply schedules this pod onto that
164 node, assuming that it fits resource requirements.
166 node_selector (Dict[str, Any]): NodeSelector is a selector which must be true for the pod to fit on a
167 node. Selector which must match a node's labels for the pod to be
168 scheduled on that node. More info:
169 https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
171 os (Dict[str, Any]): PodOS defines the OS parameters of a pod.
173 overhead (Dict[str, Any]): Overhead represents the resource overhead associated with running a
174 pod for a given RuntimeClass. This field will be autopopulated at
175 admission time by the RuntimeClass admission controller. If the
176 RuntimeClass admission controller is enabled, overhead must not be
177 set in Pod create requests. The RuntimeClass admission controller
178 will reject Pod create requests which have the overhead already
179 set. If RuntimeClass is configured and selected in the PodSpec,
180 Overhead will be set to the value defined in the corresponding
181 RuntimeClass, otherwise it will remain unset and treated as zero.
182 More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-
183 overhead/README.md
185 preemption_policy (str): PreemptionPolicy is the Policy for preempting pods with lower
186 priority. One of Never, PreemptLowerPriority. Defaults to
187 PreemptLowerPriority if unset. Possible enum values: - `"Never"`
188 means that pod never preempts other pods with lower priority. -
189 `"PreemptLowerPriority"` means that pod can preempt other pods
190 with lower priority.
192 priority (int): The priority value. Various system components use this field to find
193 the priority of the pod. When Priority Admission Controller is
194 enabled, it prevents users from setting this field. The admission
195 controller populates this field from PriorityClassName. The higher
196 the value, the higher the priority.
198 priority_class_name (str): If specified, indicates the pod's priority. "system-node-critical" and
199 "system-cluster-critical" are two special keywords which indicate
200 the highest priorities with the former being the highest priority.
201 Any other name must be defined by creating a PriorityClass object
202 with that name. If not specified, the pod priority will be default
203 or zero if there is no default.
205 readiness_gates (List[Any]): If specified, all readiness gates will be evaluated for pod readiness.
206 A pod is ready when all its containers are ready AND all
207 conditions specified in the readiness gates have status equal to
208 "True" More info: https://git.k8s.io/enhancements/keps/sig-
209 network/580-pod-readiness-gates
211 resource_claims (List[Any]): ResourceClaims defines which ResourceClaims must be allocated and
212 reserved before the Pod is allowed to start. The resources will be
213 made available to those containers which consume them by name.
214 This is an alpha field and requires enabling the
215 DynamicResourceAllocation feature gate. This field is immutable.
217 restart_policy (str): Restart policy for all containers within the pod. One of Always,
218 OnFailure, Never. In some contexts, only a subset of those values
219 may be permitted. Default to Always. More info:
220 https://kubernetes.io/docs/concepts/workloads/pods/pod-
221 lifecycle/#restart-policy Possible enum values: - `"Always"` -
222 `"Never"` - `"OnFailure"`
224 runtime_class_name (str): RuntimeClassName refers to a RuntimeClass object in the node.k8s.io
225 group, which should be used to run this pod. If no RuntimeClass
226 resource matches the named class, the pod will not be run. If
227 unset or empty, the "legacy" RuntimeClass will be used, which is
228 an implicit class with an empty definition that uses the default
229 runtime handler. More info:
230 https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class
232 scheduler_name (str): If specified, the pod will be dispatched by specified scheduler. If
233 not specified, the pod will be dispatched by default scheduler.
235 scheduling_gates (List[Any]): SchedulingGates is an opaque list of values that if specified will
236 block scheduling the pod. If schedulingGates is not empty, the pod
237 will stay in the SchedulingGated state and the scheduler will not
238 attempt to schedule the pod. SchedulingGates can only be set at
239 pod creation time, and be removed only afterwards.
241 security_context (Dict[str, Any]): PodSecurityContext holds pod-level security attributes and common
242 container settings. Some fields are also present in
243 container.securityContext. Field values of
244 container.securityContext take precedence over field values of
245 PodSecurityContext.
247 service_account (str): DeprecatedServiceAccount is a deprecated alias for ServiceAccountName.
248 Deprecated: Use serviceAccountName instead.
250 service_account_name (str): ServiceAccountName is the name of the ServiceAccount to use to run
251 this pod. More info: https://kubernetes.io/docs/tasks/configure-
252 pod-container/configure-service-account/
254 set_hostname_as_fqdn (bool): If true the pod's hostname will be configured as the pod's FQDN,
255 rather than the leaf name (the default). In Linux containers, this
256 means setting the FQDN in the hostname field of the kernel (the
257 nodename field of struct utsname). In Windows containers, this
258 means setting the registry value of hostname for the registry key
259 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Paramet
260 ers to FQDN. If a pod does not have FQDN, this has no effect.
261 Default to false.
263 share_process_namespace (bool): Share a single process namespace between all of the containers in a
264 pod. When this is set containers will be able to view and signal
265 processes from other containers in the same pod, and the first
266 process in each container will not be assigned PID 1. HostPID and
267 ShareProcessNamespace cannot both be set. Optional: Default to
268 false.
270 subdomain (str): If specified, the fully qualified Pod hostname will be
271 "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>". If
272 not specified, the pod will not have a domainname at all.
274 termination_grace_period_seconds (int): Optional duration in seconds the pod needs to terminate gracefully.
275 May be decreased in delete request. Value must be non-negative
276 integer. The value zero indicates stop immediately via the kill
277 signal (no opportunity to shut down). If this value is nil, the
278 default grace period will be used instead. The grace period is the
279 duration in seconds after the processes running in the pod are
280 sent a termination signal and the time when the processes are
281 forcibly halted with a kill signal. Set this value longer than the
282 expected cleanup time for your process. Defaults to 30 seconds.
284 tolerations (List[Any]): If specified, the pod's tolerations.
286 topology_spread_constraints (List[Any]): TopologySpreadConstraints describes how a group of pods ought to
287 spread across topology domains. Scheduler will schedule pods in a
288 way which abides by the constraints. All topologySpreadConstraints
289 are ANDed.
291 volumes (List[Any]): List of volumes that can be mounted by containers belonging to the
292 pod. More info:
293 https://kubernetes.io/docs/concepts/storage/volumes
295 """
296 super().__init__(**kwargs)
298 self.active_deadline_seconds = active_deadline_seconds
299 self.affinity = affinity
300 self.automount_service_account_token = automount_service_account_token
301 self.containers = containers
302 self.dns_config = dns_config
303 self.dns_policy = dns_policy
304 self.enable_service_links = enable_service_links
305 self.ephemeral_containers = ephemeral_containers
306 self.host_aliases = host_aliases
307 self.host_ipc = host_ipc
308 self.host_network = host_network
309 self.host_pid = host_pid
310 self.host_users = host_users
311 self.hostname = hostname
312 self.image_pull_secrets = image_pull_secrets
313 self.init_containers = init_containers
314 self.node_name = node_name
315 self.node_selector = node_selector
316 self.os = os
317 self.overhead = overhead
318 self.preemption_policy = preemption_policy
319 self.priority = priority
320 self.priority_class_name = priority_class_name
321 self.readiness_gates = readiness_gates
322 self.resource_claims = resource_claims
323 self.restart_policy = restart_policy
324 self.runtime_class_name = runtime_class_name
325 self.scheduler_name = scheduler_name
326 self.scheduling_gates = scheduling_gates
327 self.security_context = security_context
328 self.service_account = service_account
329 self.service_account_name = service_account_name
330 self.set_hostname_as_fqdn = set_hostname_as_fqdn
331 self.share_process_namespace = share_process_namespace
332 self.subdomain = subdomain
333 self.termination_grace_period_seconds = termination_grace_period_seconds
334 self.tolerations = tolerations
335 self.topology_spread_constraints = topology_spread_constraints
336 self.volumes = volumes
338 def to_dict(self) -> None:
339 super().to_dict()
341 if not self.kind_dict and not self.yaml_file:
342 if not self.containers:
343 raise MissingRequiredArgumentError(argument="self.containers")
345 self.res["spec"] = {}
346 _spec = self.res["spec"]
348 _spec["containers"] = self.containers
350 if self.active_deadline_seconds:
351 _spec["activeDeadlineSeconds"] = self.active_deadline_seconds
353 if self.affinity:
354 _spec["affinity"] = self.affinity
356 if self.automount_service_account_token is not None:
357 _spec["automountServiceAccountToken"] = self.automount_service_account_token
359 if self.dns_config:
360 _spec["dnsConfig"] = self.dns_config
362 if self.dns_policy:
363 _spec["dnsPolicy"] = self.dns_policy
365 if self.enable_service_links is not None:
366 _spec["enableServiceLinks"] = self.enable_service_links
368 if self.ephemeral_containers:
369 _spec["ephemeralContainers"] = self.ephemeral_containers
371 if self.host_aliases:
372 _spec["hostAliases"] = self.host_aliases
374 if self.host_ipc is not None:
375 _spec["hostIPC"] = self.host_ipc
377 if self.host_network is not None:
378 _spec["hostNetwork"] = self.host_network
380 if self.host_pid is not None:
381 _spec["hostPID"] = self.host_pid
383 if self.host_users is not None:
384 _spec["hostUsers"] = self.host_users
386 if self.hostname:
387 _spec["hostname"] = self.hostname
389 if self.image_pull_secrets:
390 _spec["imagePullSecrets"] = self.image_pull_secrets
392 if self.init_containers:
393 _spec["initContainers"] = self.init_containers
395 if self.node_name:
396 _spec["nodeName"] = self.node_name
398 if self.node_selector:
399 _spec["nodeSelector"] = self.node_selector
401 if self.os:
402 _spec["os"] = self.os
404 if self.overhead:
405 _spec["overhead"] = self.overhead
407 if self.preemption_policy:
408 _spec["preemptionPolicy"] = self.preemption_policy
410 if self.priority:
411 _spec["priority"] = self.priority
413 if self.priority_class_name:
414 _spec["priorityClassName"] = self.priority_class_name
416 if self.readiness_gates:
417 _spec["readinessGates"] = self.readiness_gates
419 if self.resource_claims:
420 _spec["resourceClaims"] = self.resource_claims
422 if self.restart_policy:
423 _spec["restartPolicy"] = self.restart_policy
425 if self.runtime_class_name:
426 _spec["runtimeClassName"] = self.runtime_class_name
428 if self.scheduler_name:
429 _spec["schedulerName"] = self.scheduler_name
431 if self.scheduling_gates:
432 _spec["schedulingGates"] = self.scheduling_gates
434 if self.security_context:
435 _spec["securityContext"] = self.security_context
437 if self.service_account:
438 _spec["serviceAccount"] = self.service_account
440 if self.service_account_name:
441 _spec["serviceAccountName"] = self.service_account_name
443 if self.set_hostname_as_fqdn is not None:
444 _spec["setHostnameAsFQDN"] = self.set_hostname_as_fqdn
446 if self.share_process_namespace is not None:
447 _spec["shareProcessNamespace"] = self.share_process_namespace
449 if self.subdomain:
450 _spec["subdomain"] = self.subdomain
452 if self.termination_grace_period_seconds:
453 _spec["terminationGracePeriodSeconds"] = self.termination_grace_period_seconds
455 if self.tolerations:
456 _spec["tolerations"] = self.tolerations
458 if self.topology_spread_constraints:
459 _spec["topologySpreadConstraints"] = self.topology_spread_constraints
461 if self.volumes:
462 _spec["volumes"] = self.volumes
464 # End of generated code
466 def execute(self, command: List[str], timeout: int = 60, container: str = "", ignore_rc: bool = False) -> str:
467 """
468 Run command on Pod
470 Args:
471 command (list): Command to run.
472 timeout (int): Time to wait for the command.
473 container (str): Container name where to exec the command.
474 ignore_rc (bool): If True ignore error rc from the shell and return out.
476 Returns:
477 str: Command output.
479 Raises:
480 ExecOnPodError: If the command failed.
481 """
482 error_channel: Dict[Any, Any] = {}
483 stream_closed_error: str = "stream resp is closed"
484 self.logger.info(f"Execute {command} on {self.name} ({self.node.name})")
485 resp = kubernetes.stream.stream(
486 api_method=self._kube_v1_api.connect_get_namespaced_pod_exec,
487 name=self.name,
488 namespace=self.namespace,
489 command=command,
490 container=container or self.instance.spec.containers[0].name,
491 stderr=True,
492 stdin=False,
493 stdout=True,
494 tty=False,
495 _preload_content=False,
496 )
498 timeout_watch = TimeoutWatch(timeout=timeout)
499 while resp.is_open():
500 resp.run_forever(timeout=2)
501 try:
502 error_channel = json.loads(resp.read_channel(kubernetes.stream.ws_client.ERROR_CHANNEL))
503 break
504 except json.decoder.JSONDecodeError:
505 # Check remaining time, in order to throw exception
506 # if remaining time reached zero
507 if timeout_watch.remaining_time() <= 0:
508 raise ExecOnPodError(command=command, rc=-1, out="", err=stream_closed_error)
510 rcstring = error_channel.get("status")
511 if rcstring is None:
512 raise ExecOnPodError(command=command, rc=-1, out="", err=stream_closed_error)
514 stdout = resp.read_stdout(timeout=TIMEOUT_5SEC)
515 stderr = resp.read_stderr(timeout=TIMEOUT_5SEC)
517 if rcstring == "Success" or ignore_rc:
518 return stdout
520 if rcstring == "Failure":
521 raise ExecOnPodError(command=command, rc=-1, out="", err=error_channel)
523 returncode = [
524 int(cause["message"]) for cause in error_channel["details"]["causes"] if cause["reason"] == "ExitCode"
525 ][0]
527 raise ExecOnPodError(command=command, rc=returncode, out=stdout, err=stderr)
529 def log(self, **kwargs: Any) -> str:
530 """
531 Get Pod logs
533 Returns:
534 str: Pod logs.
535 """
536 return self._kube_v1_api.read_namespaced_pod_log(name=self.name, namespace=self.namespace, **kwargs)
538 @property
539 def node(self) -> Node:
540 """
541 Get the node name where the Pod is running
543 Returns:
544 Node: Node
545 """
546 node_name = self.instance.spec.nodeName
547 assert node_name, f"Node not found for pod {self.name}"
548 return Node(
549 client=self.client,
550 name=node_name,
551 )
553 @property
554 def ip(self) -> str:
555 return self.instance.status.podIP