apache-airflow-providers-cncf-kubernetes 8.1.1rc1__tar.gz → 8.2.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of apache-airflow-providers-cncf-kubernetes might be problematic. Click here for more details.

Files changed (57) hide show
  1. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/PKG-INFO +8 -8
  2. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/README.rst +4 -4
  3. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/__init__.py +3 -3
  4. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/backcompat/backwards_compat_converters.py +12 -2
  5. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/get_provider_info.py +3 -2
  6. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py +2 -3
  7. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/pod.py +35 -5
  8. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_generator.py +4 -4
  9. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_generator_deprecated.py +2 -2
  10. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_launcher_deprecated.py +3 -3
  11. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/triggers/pod.py +2 -0
  12. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/utils/pod_manager.py +5 -1
  13. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/pyproject.toml +4 -4
  14. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/LICENSE +0 -0
  15. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/backcompat/__init__.py +0 -0
  16. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/callbacks.py +0 -0
  17. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/decorators/__init__.py +0 -0
  18. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/decorators/kubernetes.py +0 -0
  19. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/executors/__init__.py +0 -0
  20. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/executors/kubernetes_executor.py +0 -0
  21. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/executors/kubernetes_executor_types.py +0 -0
  22. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/executors/kubernetes_executor_utils.py +0 -0
  23. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/executors/local_kubernetes_executor.py +0 -0
  24. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/hooks/__init__.py +0 -0
  25. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/hooks/kubernetes.py +0 -0
  26. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/k8s_model.py +0 -0
  27. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/kube_client.py +0 -0
  28. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/kube_config.py +0 -0
  29. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/kubernetes_executor_templates/__init__.py +0 -0
  30. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/kubernetes_executor_templates/basic_template.yaml +0 -0
  31. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/kubernetes_helper_functions.py +0 -0
  32. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/__init__.py +0 -0
  33. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/job.py +0 -0
  34. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/kubernetes_pod.py +0 -0
  35. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/resource.py +0 -0
  36. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py +0 -0
  37. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_template_file_examples/__init__.py +0 -0
  38. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_image_template.yaml +0 -0
  39. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_volume_template.yaml +0 -0
  40. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/pod_template_file_examples/git_sync_template.yaml +0 -0
  41. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/python_kubernetes_script.jinja2 +0 -0
  42. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/python_kubernetes_script.py +0 -0
  43. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/resource_convert/__init__.py +0 -0
  44. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/resource_convert/configmap.py +0 -0
  45. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/resource_convert/env_variable.py +0 -0
  46. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/resource_convert/secret.py +0 -0
  47. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/secret.py +0 -0
  48. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/sensors/__init__.py +0 -0
  49. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/sensors/spark_kubernetes.py +0 -0
  50. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/template_rendering.py +0 -0
  51. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/triggers/__init__.py +0 -0
  52. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/triggers/job.py +0 -0
  53. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/triggers/kubernetes_pod.py +0 -0
  54. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/utils/__init__.py +0 -0
  55. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/utils/delete_from.py +0 -0
  56. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/utils/k8s_resource_iterator.py +0 -0
  57. {apache_airflow_providers_cncf_kubernetes-8.1.1rc1 → apache_airflow_providers_cncf_kubernetes-8.2.0rc1}/airflow/providers/cncf/kubernetes/utils/xcom_sidecar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apache-airflow-providers-cncf-kubernetes
3
- Version: 8.1.1rc1
3
+ Version: 8.2.0rc1
4
4
  Summary: Provider package apache-airflow-providers-cncf-kubernetes for Apache Airflow
5
5
  Keywords: airflow-provider,cncf.kubernetes,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -22,15 +22,15 @@ Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
23
  Classifier: Topic :: System :: Monitoring
24
24
  Requires-Dist: aiofiles>=23.2.0
25
- Requires-Dist: apache-airflow>=2.6.0rc0
25
+ Requires-Dist: apache-airflow>=2.7.0rc0
26
26
  Requires-Dist: asgiref>=3.5.2
27
27
  Requires-Dist: cryptography>=2.0.0
28
28
  Requires-Dist: google-re2>=1.0
29
29
  Requires-Dist: kubernetes>=28.1.0,<=29.0.0
30
30
  Requires-Dist: kubernetes_asyncio>=28.1.0,<=29.0.0
31
31
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
32
- Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/changelog.html
33
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1
32
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/changelog.html
33
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0
34
34
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
35
35
  Project-URL: Source Code, https://github.com/apache/airflow
36
36
  Project-URL: Twitter, https://twitter.com/ApacheAirflow
@@ -80,7 +80,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
80
80
 
81
81
  Package ``apache-airflow-providers-cncf-kubernetes``
82
82
 
83
- Release: ``8.1.1.rc1``
83
+ Release: ``8.2.0.rc1``
84
84
 
85
85
 
86
86
  `Kubernetes <https://kubernetes.io/>`__
@@ -93,7 +93,7 @@ This is a provider package for ``cncf.kubernetes`` provider. All classes for thi
93
93
  are in ``airflow.providers.cncf.kubernetes`` python package.
94
94
 
95
95
  You can find package information and changelog for the provider
96
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/>`_.
96
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/>`_.
97
97
 
98
98
  Installation
99
99
  ------------
@@ -111,7 +111,7 @@ Requirements
111
111
  PIP package Version required
112
112
  ====================== =====================
113
113
  ``aiofiles`` ``>=23.2.0``
114
- ``apache-airflow`` ``>=2.6.0``
114
+ ``apache-airflow`` ``>=2.7.0``
115
115
  ``asgiref`` ``>=3.5.2``
116
116
  ``cryptography`` ``>=2.0.0``
117
117
  ``kubernetes`` ``>=28.1.0,<=29.0.0``
@@ -120,4 +120,4 @@ PIP package Version required
120
120
  ====================== =====================
121
121
 
122
122
  The changelog for the provider package can be found in the
123
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/changelog.html>`_.
123
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/changelog.html>`_.
@@ -42,7 +42,7 @@
42
42
 
43
43
  Package ``apache-airflow-providers-cncf-kubernetes``
44
44
 
45
- Release: ``8.1.1.rc1``
45
+ Release: ``8.2.0.rc1``
46
46
 
47
47
 
48
48
  `Kubernetes <https://kubernetes.io/>`__
@@ -55,7 +55,7 @@ This is a provider package for ``cncf.kubernetes`` provider. All classes for thi
55
55
  are in ``airflow.providers.cncf.kubernetes`` python package.
56
56
 
57
57
  You can find package information and changelog for the provider
58
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/>`_.
58
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/>`_.
59
59
 
60
60
  Installation
61
61
  ------------
@@ -73,7 +73,7 @@ Requirements
73
73
  PIP package Version required
74
74
  ====================== =====================
75
75
  ``aiofiles`` ``>=23.2.0``
76
- ``apache-airflow`` ``>=2.6.0``
76
+ ``apache-airflow`` ``>=2.7.0``
77
77
  ``asgiref`` ``>=3.5.2``
78
78
  ``cryptography`` ``>=2.0.0``
79
79
  ``kubernetes`` ``>=28.1.0,<=29.0.0``
@@ -82,4 +82,4 @@ PIP package Version required
82
82
  ====================== =====================
83
83
 
84
84
  The changelog for the provider package can be found in the
85
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/changelog.html>`_.
85
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/changelog.html>`_.
@@ -27,7 +27,7 @@ import packaging.version
27
27
 
28
28
  __all__ = ["__version__"]
29
29
 
30
- __version__ = "8.1.1"
30
+ __version__ = "8.2.0"
31
31
 
32
32
  try:
33
33
  from airflow import __version__ as airflow_version
@@ -35,8 +35,8 @@ except ImportError:
35
35
  from airflow.version import version as airflow_version
36
36
 
37
37
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
38
- "2.6.0"
38
+ "2.7.0"
39
39
  ):
40
40
  raise RuntimeError(
41
- f"The package `apache-airflow-providers-cncf-kubernetes:{__version__}` needs Apache Airflow 2.6.0+"
41
+ f"The package `apache-airflow-providers-cncf-kubernetes:{__version__}` needs Apache Airflow 2.7.0+"
42
42
  )
@@ -76,10 +76,20 @@ def convert_env_vars(env_vars: list[k8s.V1EnvVar] | dict[str, str]) -> list[k8s.
76
76
 
77
77
  If the collection is a str-str dict, convert it into a list of ``V1EnvVar``s.
78
78
  """
79
- if isinstance(env_vars, list):
80
- return env_vars
81
79
  if isinstance(env_vars, dict):
82
80
  return [k8s.V1EnvVar(name=k, value=v) for k, v in env_vars.items()]
81
+ return env_vars
82
+
83
+
84
+ def convert_env_vars_or_raise_error(env_vars: list[k8s.V1EnvVar] | dict[str, str]) -> list[k8s.V1EnvVar]:
85
+ """
86
+ Separate function to convert env var collection for kubernetes and then raise an error if it is still the wrong type.
87
+
88
+ This is used after the template strings have been rendered.
89
+ """
90
+ env_vars = convert_env_vars(env_vars)
91
+ if isinstance(env_vars, list):
92
+ return env_vars
83
93
  raise AirflowException(f"Expected dict or list, got {type(env_vars)}")
84
94
 
85
95
 
@@ -28,8 +28,9 @@ def get_provider_info():
28
28
  "name": "Kubernetes",
29
29
  "description": "`Kubernetes <https://kubernetes.io/>`__\n",
30
30
  "state": "ready",
31
- "source-date-epoch": 1713253055,
31
+ "source-date-epoch": 1714476004,
32
32
  "versions": [
33
+ "8.2.0",
33
34
  "8.1.1",
34
35
  "8.1.0",
35
36
  "8.0.1",
@@ -88,7 +89,7 @@ def get_provider_info():
88
89
  ],
89
90
  "dependencies": [
90
91
  "aiofiles>=23.2.0",
91
- "apache-airflow>=2.6.0",
92
+ "apache-airflow>=2.7.0",
92
93
  "asgiref>=3.5.2",
93
94
  "cryptography>=2.0.0",
94
95
  "kubernetes>=28.1.0,<=29.0.0",
@@ -60,12 +60,11 @@ class SparkJobSpec:
60
60
  if self.spec.get("dynamicAllocation", {}).get("enabled"):
61
61
  if not all(
62
62
  [
63
- self.spec["dynamicAllocation"].get("initialExecutors"),
64
63
  self.spec["dynamicAllocation"].get("minExecutors"),
65
64
  self.spec["dynamicAllocation"].get("maxExecutors"),
66
65
  ]
67
66
  ):
68
- raise AirflowException("Make sure initial/min/max value for dynamic allocation is passed")
67
+ raise AirflowException("Make sure min/max value for dynamic allocation is passed")
69
68
 
70
69
  def update_resources(self):
71
70
  if self.spec["driver"].get("container_resources"):
@@ -345,7 +344,7 @@ class CustomObjectLauncher(LoggingMixin):
345
344
  waiting_message = waiting_status.message
346
345
  except Exception:
347
346
  return
348
- if waiting_reason != "ContainerCreating":
347
+ if waiting_reason not in ("ContainerCreating", "PodInitializing"):
349
348
  raise AirflowException(f"Spark Job Failed. Status: {waiting_reason}, Error: {waiting_message}")
350
349
 
351
350
  def delete_spark_job(self, spark_job_name=None):
@@ -33,6 +33,7 @@ from functools import cached_property
33
33
  from typing import TYPE_CHECKING, Any, Callable, Iterable, Sequence
34
34
 
35
35
  import kubernetes
36
+ import tenacity
36
37
  from deprecated import deprecated
37
38
  from kubernetes.client import CoreV1Api, V1Pod, models as k8s
38
39
  from kubernetes.stream import stream
@@ -51,6 +52,7 @@ from airflow.providers.cncf.kubernetes.backcompat.backwards_compat_converters im
51
52
  convert_affinity,
52
53
  convert_configmap,
53
54
  convert_env_vars,
55
+ convert_env_vars_or_raise_error,
54
56
  convert_image_pull_secrets,
55
57
  convert_pod_runtime_info_env,
56
58
  convert_port,
@@ -76,6 +78,7 @@ from airflow.providers.cncf.kubernetes.utils.pod_manager import (
76
78
  PodNotFoundException,
77
79
  PodOperatorHookProtocol,
78
80
  PodPhase,
81
+ check_exception_is_kubernetes_api_unauthorized,
79
82
  container_is_succeeded,
80
83
  get_container_termination_message,
81
84
  )
@@ -332,8 +335,10 @@ class KubernetesPodOperator(BaseOperator):
332
335
  self.startup_check_interval_seconds = startup_check_interval_seconds
333
336
  env_vars = convert_env_vars(env_vars) if env_vars else []
334
337
  self.env_vars = env_vars
335
- if pod_runtime_info_envs:
336
- self.env_vars.extend([convert_pod_runtime_info_env(p) for p in pod_runtime_info_envs])
338
+ pod_runtime_info_envs = (
339
+ [convert_pod_runtime_info_env(p) for p in pod_runtime_info_envs] if pod_runtime_info_envs else []
340
+ )
341
+ self.pod_runtime_info_envs = pod_runtime_info_envs
337
342
  self.env_from = env_from or []
338
343
  if configmaps:
339
344
  self.env_from.extend([convert_configmap(c) for c in configmaps])
@@ -615,9 +620,7 @@ class KubernetesPodOperator(BaseOperator):
615
620
  if not self.get_logs or (
616
621
  self.container_logs is not True and self.base_container_name not in self.container_logs
617
622
  ):
618
- self.pod_manager.await_container_completion(
619
- pod=self.pod, container_name=self.base_container_name
620
- )
623
+ self.await_container_completion(pod=self.pod, container_name=self.base_container_name)
621
624
  if self.callbacks:
622
625
  self.callbacks.on_pod_completion(
623
626
  pod=self.find_pod(self.pod.metadata.namespace, context=context),
@@ -644,6 +647,28 @@ class KubernetesPodOperator(BaseOperator):
644
647
  if self.do_xcom_push:
645
648
  return result
646
649
 
650
+ @tenacity.retry(
651
+ stop=tenacity.stop_after_attempt(3),
652
+ wait=tenacity.wait_exponential(max=15),
653
+ retry=tenacity.retry_if_exception(lambda exc: check_exception_is_kubernetes_api_unauthorized(exc)),
654
+ reraise=True,
655
+ )
656
+ def await_container_completion(self, pod: k8s.V1Pod, container_name: str):
657
+ try:
658
+ self.pod_manager.await_container_completion(pod=pod, container_name=container_name)
659
+ except kubernetes.client.exceptions.ApiException as exc:
660
+ if exc.status and str(exc.status) == "401":
661
+ self.log.warning(
662
+ "Failed to check container status due to permission error. Refreshing credentials and retrying."
663
+ )
664
+ self._refresh_cached_properties()
665
+ raise exc
666
+
667
+ def _refresh_cached_properties(self):
668
+ del self.hook
669
+ del self.client
670
+ del self.pod_manager
671
+
647
672
  def execute_async(self, context: Context):
648
673
  self.pod_request_obj = self.build_pod_request_obj(context)
649
674
  self.pod = self.get_or_create_pod( # must set `self.pod` for `on_kill`
@@ -985,6 +1010,11 @@ class KubernetesPodOperator(BaseOperator):
985
1010
  template file.
986
1011
  """
987
1012
  self.log.debug("Creating pod for KubernetesPodOperator task %s", self.task_id)
1013
+
1014
+ self.env_vars = convert_env_vars_or_raise_error(self.env_vars) if self.env_vars else []
1015
+ if self.pod_runtime_info_envs:
1016
+ self.env_vars.extend(self.pod_runtime_info_envs)
1017
+
988
1018
  if self.pod_template_file:
989
1019
  self.log.debug("Pod template file found, will parse for base pod")
990
1020
  pod_template = pod_generator.PodGenerator.deserialize_model_file(self.pod_template_file)
@@ -50,7 +50,7 @@ from airflow.providers.cncf.kubernetes.kubernetes_helper_functions import (
50
50
  rand_str,
51
51
  )
52
52
  from airflow.providers.cncf.kubernetes.pod_generator_deprecated import (
53
- PodDefaults,
53
+ PodDefaults as PodDefaultsDeprecated,
54
54
  PodGenerator as PodGeneratorDeprecated,
55
55
  )
56
56
  from airflow.utils import yaml
@@ -180,10 +180,10 @@ class PodGenerator:
180
180
  """Add sidecar."""
181
181
  pod_cp = copy.deepcopy(pod)
182
182
  pod_cp.spec.volumes = pod.spec.volumes or []
183
- pod_cp.spec.volumes.insert(0, PodDefaults.VOLUME)
183
+ pod_cp.spec.volumes.insert(0, PodDefaultsDeprecated.VOLUME)
184
184
  pod_cp.spec.containers[0].volume_mounts = pod_cp.spec.containers[0].volume_mounts or []
185
- pod_cp.spec.containers[0].volume_mounts.insert(0, PodDefaults.VOLUME_MOUNT)
186
- pod_cp.spec.containers.append(PodDefaults.SIDECAR_CONTAINER)
185
+ pod_cp.spec.containers[0].volume_mounts.insert(0, PodDefaultsDeprecated.VOLUME_MOUNT)
186
+ pod_cp.spec.containers.append(PodDefaultsDeprecated.SIDECAR_CONTAINER)
187
187
 
188
188
  return pod_cp
189
189
 
@@ -31,8 +31,6 @@ import uuid
31
31
  import re2
32
32
  from kubernetes.client import models as k8s
33
33
 
34
- from airflow.utils.hashlib_wrapper import md5
35
-
36
34
  MAX_POD_ID_LEN = 253
37
35
 
38
36
  MAX_LABEL_LEN = 63
@@ -71,6 +69,8 @@ def make_safe_label_value(string):
71
69
  way from the original value sent to this function, then we need to truncate to
72
70
  53 chars, and append it with a unique hash.
73
71
  """
72
+ from airflow.utils.hashlib_wrapper import md5
73
+
74
74
  safe_label = re2.sub(r"^[^a-z0-9A-Z]*|[^a-zA-Z0-9_\-\.]|[^a-z0-9A-Z]*$", "", string)
75
75
 
76
76
  if len(safe_label) > MAX_LABEL_LEN or string != safe_label:
@@ -33,7 +33,7 @@ from requests.exceptions import HTTPError
33
33
 
34
34
  from airflow.exceptions import AirflowException, RemovedInAirflow3Warning
35
35
  from airflow.providers.cncf.kubernetes.kube_client import get_kube_client
36
- from airflow.providers.cncf.kubernetes.pod_generator import PodDefaults
36
+ from airflow.providers.cncf.kubernetes.pod_generator import PodDefaultsDeprecated
37
37
  from airflow.settings import pod_mutation_hook
38
38
  from airflow.utils.log.logging_mixin import LoggingMixin
39
39
  from airflow.utils.state import State
@@ -272,7 +272,7 @@ class PodLauncher(LoggingMixin):
272
272
  self._client.connect_get_namespaced_pod_exec,
273
273
  pod.metadata.name,
274
274
  pod.metadata.namespace,
275
- container=PodDefaults.SIDECAR_CONTAINER_NAME,
275
+ container=PodDefaultsDeprecated.SIDECAR_CONTAINER_NAME,
276
276
  command=["/bin/sh"],
277
277
  stdin=True,
278
278
  stdout=True,
@@ -281,7 +281,7 @@ class PodLauncher(LoggingMixin):
281
281
  _preload_content=False,
282
282
  )
283
283
  try:
284
- result = self._exec_pod_command(resp, f"cat {PodDefaults.XCOM_MOUNT_PATH}/return.json")
284
+ result = self._exec_pod_command(resp, f"cat {PodDefaultsDeprecated.XCOM_MOUNT_PATH}/return.json")
285
285
  self._exec_pod_command(resp, "kill -s SIGINT 1")
286
286
  finally:
287
287
  resp.close()
@@ -262,6 +262,7 @@ class KubernetesPodTrigger(BaseTrigger):
262
262
  "last_log_time": self.last_log_time,
263
263
  }
264
264
  )
265
+ self.log.debug("Container is not completed and still working.")
265
266
  if time_get_more_logs and datetime.datetime.now(tz=datetime.timezone.utc) > time_get_more_logs:
266
267
  return TriggerEvent(
267
268
  {
@@ -271,6 +272,7 @@ class KubernetesPodTrigger(BaseTrigger):
271
272
  "name": self.pod_name,
272
273
  }
273
274
  )
275
+ self.log.debug("Sleeping for %s seconds.", self.poll_interval)
274
276
  await asyncio.sleep(self.poll_interval)
275
277
 
276
278
  def _get_async_hook(self) -> AsyncKubernetesHook:
@@ -42,7 +42,7 @@ from urllib3.exceptions import HTTPError, TimeoutError
42
42
 
43
43
  from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
44
44
  from airflow.providers.cncf.kubernetes.callbacks import ExecutionMode, KubernetesPodOperatorCallback
45
- from airflow.providers.cncf.kubernetes.pod_generator import PodDefaults
45
+ from airflow.providers.cncf.kubernetes.utils.xcom_sidecar import PodDefaults
46
46
  from airflow.utils.log.logging_mixin import LoggingMixin
47
47
  from airflow.utils.timezone import utcnow
48
48
 
@@ -190,6 +190,10 @@ def get_container_termination_message(pod: V1Pod, container_name: str):
190
190
  return container_status.state.terminated.message if container_status else None
191
191
 
192
192
 
193
+ def check_exception_is_kubernetes_api_unauthorized(exc: BaseException):
194
+ return isinstance(exc, ApiException) and exc.status and str(exc.status) == "401"
195
+
196
+
193
197
  class PodLaunchTimeoutException(AirflowException):
194
198
  """When pod does not leave the ``Pending`` phase within specified timeout."""
195
199
 
@@ -28,7 +28,7 @@ build-backend = "flit_core.buildapi"
28
28
 
29
29
  [project]
30
30
  name = "apache-airflow-providers-cncf-kubernetes"
31
- version = "8.1.1.rc1"
31
+ version = "8.2.0.rc1"
32
32
  description = "Provider package apache-airflow-providers-cncf-kubernetes for Apache Airflow"
33
33
  readme = "README.rst"
34
34
  authors = [
@@ -57,7 +57,7 @@ classifiers = [
57
57
  requires-python = "~=3.8"
58
58
  dependencies = [
59
59
  "aiofiles>=23.2.0",
60
- "apache-airflow>=2.6.0rc0",
60
+ "apache-airflow>=2.7.0rc0",
61
61
  "asgiref>=3.5.2",
62
62
  "cryptography>=2.0.0",
63
63
  "google-re2>=1.0",
@@ -66,8 +66,8 @@ dependencies = [
66
66
  ]
67
67
 
68
68
  [project.urls]
69
- "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1"
70
- "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.1.1/changelog.html"
69
+ "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0"
70
+ "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/8.2.0/changelog.html"
71
71
  "Bug Tracker" = "https://github.com/apache/airflow/issues"
72
72
  "Source Code" = "https://github.com/apache/airflow"
73
73
  "Slack Chat" = "https://s.apache.org/airflow-slack"