apache-airflow-providers-cncf-kubernetes 3.1.0__py3-none-any.whl → 10.10.0rc1__py3-none-any.whl
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.
- airflow/providers/cncf/kubernetes/__init__.py +18 -23
- airflow/providers/cncf/kubernetes/backcompat/__init__.py +17 -0
- airflow/providers/cncf/kubernetes/backcompat/backwards_compat_converters.py +31 -49
- airflow/providers/cncf/kubernetes/callbacks.py +200 -0
- airflow/providers/cncf/kubernetes/cli/__init__.py +16 -0
- airflow/providers/cncf/kubernetes/cli/kubernetes_command.py +195 -0
- airflow/providers/cncf/kubernetes/decorators/kubernetes.py +163 -0
- airflow/providers/cncf/kubernetes/decorators/kubernetes_cmd.py +118 -0
- airflow/providers/cncf/kubernetes/exceptions.py +37 -0
- airflow/providers/cncf/kubernetes/executors/__init__.py +17 -0
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor.py +831 -0
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor_types.py +91 -0
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor_utils.py +736 -0
- airflow/providers/cncf/kubernetes/executors/local_kubernetes_executor.py +306 -0
- airflow/providers/cncf/kubernetes/get_provider_info.py +249 -50
- airflow/providers/cncf/kubernetes/hooks/kubernetes.py +846 -112
- airflow/providers/cncf/kubernetes/k8s_model.py +62 -0
- airflow/providers/cncf/kubernetes/kube_client.py +156 -0
- airflow/providers/cncf/kubernetes/kube_config.py +125 -0
- airflow/providers/cncf/kubernetes/kubernetes_executor_templates/__init__.py +16 -0
- airflow/providers/cncf/kubernetes/kubernetes_executor_templates/basic_template.yaml +79 -0
- airflow/providers/cncf/kubernetes/kubernetes_helper_functions.py +165 -0
- airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py +368 -0
- airflow/providers/cncf/kubernetes/operators/job.py +646 -0
- airflow/providers/cncf/kubernetes/operators/kueue.py +132 -0
- airflow/providers/cncf/kubernetes/operators/pod.py +1417 -0
- airflow/providers/cncf/kubernetes/operators/resource.py +191 -0
- airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py +336 -35
- airflow/providers/cncf/kubernetes/pod_generator.py +592 -0
- airflow/providers/cncf/kubernetes/pod_template_file_examples/__init__.py +16 -0
- airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_image_template.yaml +68 -0
- airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_volume_template.yaml +74 -0
- airflow/providers/cncf/kubernetes/pod_template_file_examples/git_sync_template.yaml +95 -0
- airflow/providers/cncf/kubernetes/python_kubernetes_script.jinja2 +51 -0
- airflow/providers/cncf/kubernetes/python_kubernetes_script.py +92 -0
- airflow/providers/cncf/kubernetes/resource_convert/__init__.py +16 -0
- airflow/providers/cncf/kubernetes/resource_convert/configmap.py +52 -0
- airflow/providers/cncf/kubernetes/resource_convert/env_variable.py +39 -0
- airflow/providers/cncf/kubernetes/resource_convert/secret.py +40 -0
- airflow/providers/cncf/kubernetes/secret.py +128 -0
- airflow/providers/cncf/kubernetes/sensors/spark_kubernetes.py +30 -14
- airflow/providers/cncf/kubernetes/template_rendering.py +81 -0
- airflow/providers/cncf/kubernetes/triggers/__init__.py +16 -0
- airflow/providers/cncf/kubernetes/triggers/job.py +176 -0
- airflow/providers/cncf/kubernetes/triggers/pod.py +344 -0
- airflow/providers/cncf/kubernetes/utils/__init__.py +3 -0
- airflow/providers/cncf/kubernetes/utils/container.py +118 -0
- airflow/providers/cncf/kubernetes/utils/delete_from.py +154 -0
- airflow/providers/cncf/kubernetes/utils/k8s_resource_iterator.py +46 -0
- airflow/providers/cncf/kubernetes/utils/pod_manager.py +887 -152
- airflow/providers/cncf/kubernetes/utils/xcom_sidecar.py +25 -16
- airflow/providers/cncf/kubernetes/version_compat.py +38 -0
- apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info/METADATA +125 -0
- apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info/RECORD +62 -0
- {apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info}/WHEEL +1 -2
- apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info/entry_points.txt +3 -0
- apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info/licenses/NOTICE +5 -0
- airflow/providers/cncf/kubernetes/backcompat/pod.py +0 -119
- airflow/providers/cncf/kubernetes/backcompat/pod_runtime_info_env.py +0 -56
- airflow/providers/cncf/kubernetes/backcompat/volume.py +0 -62
- airflow/providers/cncf/kubernetes/backcompat/volume_mount.py +0 -58
- airflow/providers/cncf/kubernetes/example_dags/example_kubernetes.py +0 -163
- airflow/providers/cncf/kubernetes/example_dags/example_spark_kubernetes.py +0 -66
- airflow/providers/cncf/kubernetes/example_dags/example_spark_kubernetes_spark_pi.yaml +0 -57
- airflow/providers/cncf/kubernetes/operators/kubernetes_pod.py +0 -622
- apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info/METADATA +0 -452
- apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info/NOTICE +0 -6
- apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info/RECORD +0 -29
- apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info/entry_points.txt +0 -3
- apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info/top_level.txt +0 -1
- /airflow/providers/cncf/kubernetes/{example_dags → decorators}/__init__.py +0 -0
- {apache_airflow_providers_cncf_kubernetes-3.1.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.10.0rc1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import base64
|
|
20
|
+
import os
|
|
21
|
+
import pickle
|
|
22
|
+
from collections.abc import Callable, Sequence
|
|
23
|
+
from shlex import quote
|
|
24
|
+
from tempfile import TemporaryDirectory
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
import dill
|
|
28
|
+
from kubernetes.client import models as k8s
|
|
29
|
+
|
|
30
|
+
from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
|
|
31
|
+
from airflow.providers.cncf.kubernetes.python_kubernetes_script import (
|
|
32
|
+
write_python_script,
|
|
33
|
+
)
|
|
34
|
+
from airflow.providers.common.compat.sdk import (
|
|
35
|
+
DecoratedOperator,
|
|
36
|
+
TaskDecorator,
|
|
37
|
+
task_decorator_factory,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from airflow.utils.context import Context
|
|
42
|
+
|
|
43
|
+
_PYTHON_SCRIPT_ENV = "__PYTHON_SCRIPT"
|
|
44
|
+
_PYTHON_INPUT_ENV = "__PYTHON_INPUT"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _generate_decoded_command(env_var: str, file: str) -> str:
|
|
48
|
+
return (
|
|
49
|
+
f'python -c "import base64, os;'
|
|
50
|
+
rf"x = base64.b64decode(os.environ[\"{env_var}\"]);"
|
|
51
|
+
rf'f = open(\"{file}\", \"wb\"); f.write(x); f.close()"'
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _read_file_contents(filename: str) -> str:
|
|
56
|
+
with open(filename, "rb") as script_file:
|
|
57
|
+
return base64.b64encode(script_file.read()).decode("utf-8")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class _KubernetesDecoratedOperator(DecoratedOperator, KubernetesPodOperator):
|
|
61
|
+
custom_operator_name = "@task.kubernetes"
|
|
62
|
+
|
|
63
|
+
# `cmds` and `arguments` are used internally by the operator
|
|
64
|
+
template_fields: Sequence[str] = tuple(
|
|
65
|
+
{"op_args", "op_kwargs", *KubernetesPodOperator.template_fields} - {"cmds", "arguments"}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Since we won't mutate the arguments, we should just do the shallow copy
|
|
69
|
+
# there are some cases we can't deepcopy the objects (e.g protobuf).
|
|
70
|
+
shallow_copy_attrs: Sequence[str] = ("python_callable",)
|
|
71
|
+
|
|
72
|
+
def __init__(self, namespace: str | None = None, use_dill: bool = False, **kwargs) -> None:
|
|
73
|
+
self.use_dill = use_dill
|
|
74
|
+
|
|
75
|
+
# If the name was not provided, we generate operator name from the python_callable
|
|
76
|
+
# we also instruct operator to add a random suffix to avoid collisions by default
|
|
77
|
+
op_name = kwargs.pop("name", f"k8s-airflow-pod-{kwargs['python_callable'].__name__}")
|
|
78
|
+
random_name_suffix = kwargs.pop("random_name_suffix", True)
|
|
79
|
+
super().__init__(
|
|
80
|
+
namespace=namespace,
|
|
81
|
+
name=op_name,
|
|
82
|
+
random_name_suffix=random_name_suffix,
|
|
83
|
+
cmds=["placeholder-command"],
|
|
84
|
+
**kwargs,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def _generate_cmds(self) -> list[str]:
|
|
88
|
+
script_filename = "/tmp/script.py"
|
|
89
|
+
input_filename = "/tmp/script.in"
|
|
90
|
+
output_filename = "/airflow/xcom/return.json"
|
|
91
|
+
|
|
92
|
+
write_local_script_file_cmd = (
|
|
93
|
+
f"{_generate_decoded_command(quote(_PYTHON_SCRIPT_ENV), quote(script_filename))}"
|
|
94
|
+
)
|
|
95
|
+
write_local_input_file_cmd = (
|
|
96
|
+
f"{_generate_decoded_command(quote(_PYTHON_INPUT_ENV), quote(input_filename))}"
|
|
97
|
+
)
|
|
98
|
+
make_xcom_dir_cmd = "mkdir -p /airflow/xcom"
|
|
99
|
+
exec_python_cmd = f"python {script_filename} {input_filename} {output_filename}"
|
|
100
|
+
return [
|
|
101
|
+
"bash",
|
|
102
|
+
"-cx",
|
|
103
|
+
(
|
|
104
|
+
f"{write_local_script_file_cmd} && "
|
|
105
|
+
f"{write_local_input_file_cmd} && "
|
|
106
|
+
f"{make_xcom_dir_cmd} && "
|
|
107
|
+
f"{exec_python_cmd}"
|
|
108
|
+
),
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
def execute(self, context: Context):
|
|
112
|
+
with TemporaryDirectory(prefix="venv") as tmp_dir:
|
|
113
|
+
pickling_library = dill if self.use_dill else pickle
|
|
114
|
+
script_filename = os.path.join(tmp_dir, "script.py")
|
|
115
|
+
input_filename = os.path.join(tmp_dir, "script.in")
|
|
116
|
+
|
|
117
|
+
with open(input_filename, "wb") as file:
|
|
118
|
+
pickling_library.dump({"args": self.op_args, "kwargs": self.op_kwargs}, file)
|
|
119
|
+
|
|
120
|
+
py_source = self.get_python_source()
|
|
121
|
+
jinja_context = {
|
|
122
|
+
"op_args": self.op_args,
|
|
123
|
+
"op_kwargs": self.op_kwargs,
|
|
124
|
+
"pickling_library": pickling_library.__name__,
|
|
125
|
+
"python_callable": self.python_callable.__name__,
|
|
126
|
+
"python_callable_source": py_source,
|
|
127
|
+
"string_args_global": False,
|
|
128
|
+
}
|
|
129
|
+
write_python_script(jinja_context=jinja_context, filename=script_filename)
|
|
130
|
+
|
|
131
|
+
self.env_vars: list[k8s.V1EnvVar] = [
|
|
132
|
+
*self.env_vars,
|
|
133
|
+
k8s.V1EnvVar(name=_PYTHON_SCRIPT_ENV, value=_read_file_contents(script_filename)),
|
|
134
|
+
k8s.V1EnvVar(name=_PYTHON_INPUT_ENV, value=_read_file_contents(input_filename)),
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
self.cmds = self._generate_cmds()
|
|
138
|
+
return super().execute(context)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def kubernetes_task(
|
|
142
|
+
python_callable: Callable | None = None,
|
|
143
|
+
multiple_outputs: bool | None = None,
|
|
144
|
+
**kwargs,
|
|
145
|
+
) -> TaskDecorator:
|
|
146
|
+
"""
|
|
147
|
+
Kubernetes operator decorator.
|
|
148
|
+
|
|
149
|
+
This wraps a function to be executed in K8s using KubernetesPodOperator.
|
|
150
|
+
Also accepts any argument that KubernetesPodOperator will via ``kwargs``. Can be
|
|
151
|
+
reused in a single DAG.
|
|
152
|
+
|
|
153
|
+
:param python_callable: Function to decorate
|
|
154
|
+
:param multiple_outputs: if set, function return value will be
|
|
155
|
+
unrolled to multiple XCom values. Dict will unroll to xcom values with
|
|
156
|
+
keys as XCom keys. Defaults to False.
|
|
157
|
+
"""
|
|
158
|
+
return task_decorator_factory(
|
|
159
|
+
python_callable=python_callable,
|
|
160
|
+
multiple_outputs=multiple_outputs,
|
|
161
|
+
decorated_operator_class=_KubernetesDecoratedOperator,
|
|
162
|
+
**kwargs,
|
|
163
|
+
)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import warnings
|
|
20
|
+
from collections.abc import Callable, Sequence
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
22
|
+
|
|
23
|
+
from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
|
|
24
|
+
from airflow.providers.common.compat.sdk import (
|
|
25
|
+
DecoratedOperator,
|
|
26
|
+
TaskDecorator,
|
|
27
|
+
context_merge,
|
|
28
|
+
task_decorator_factory,
|
|
29
|
+
)
|
|
30
|
+
from airflow.utils.operator_helpers import determine_kwargs
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from airflow.utils.context import Context
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class _KubernetesCmdDecoratedOperator(DecoratedOperator, KubernetesPodOperator):
|
|
37
|
+
custom_operator_name = "@task.kubernetes_cmd"
|
|
38
|
+
|
|
39
|
+
template_fields: Sequence[str] = KubernetesPodOperator.template_fields
|
|
40
|
+
overwrite_rtif_after_execution: bool = True
|
|
41
|
+
|
|
42
|
+
def __init__(self, *, python_callable: Callable, args_only: bool = False, **kwargs) -> None:
|
|
43
|
+
self.args_only = args_only
|
|
44
|
+
|
|
45
|
+
cmds = kwargs.pop("cmds", None)
|
|
46
|
+
arguments = kwargs.pop("arguments", None)
|
|
47
|
+
|
|
48
|
+
if cmds is not None or arguments is not None:
|
|
49
|
+
warnings.warn(
|
|
50
|
+
f"The `cmds` and `arguments` are unused in {self.custom_operator_name} decorator. "
|
|
51
|
+
"You should return a list of commands or image entrypoint arguments with "
|
|
52
|
+
"args_only=True from the python_callable.",
|
|
53
|
+
UserWarning,
|
|
54
|
+
stacklevel=3,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# If the name was not provided, we generate operator name from the python_callable
|
|
58
|
+
# we also instruct operator to add a random suffix to avoid collisions by default
|
|
59
|
+
op_name = kwargs.pop("name", f"k8s-airflow-pod-{python_callable.__name__}")
|
|
60
|
+
random_name_suffix = kwargs.pop("random_name_suffix", True)
|
|
61
|
+
|
|
62
|
+
super().__init__(
|
|
63
|
+
python_callable=python_callable,
|
|
64
|
+
name=op_name,
|
|
65
|
+
random_name_suffix=random_name_suffix,
|
|
66
|
+
cmds=None,
|
|
67
|
+
arguments=None,
|
|
68
|
+
**kwargs,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def execute(self, context: Context):
|
|
72
|
+
generated = self._generate_cmds(context)
|
|
73
|
+
if self.args_only:
|
|
74
|
+
self.cmds = []
|
|
75
|
+
self.arguments = generated
|
|
76
|
+
else:
|
|
77
|
+
self.cmds = generated
|
|
78
|
+
self.arguments = []
|
|
79
|
+
context["ti"].render_templates() # type: ignore[attr-defined]
|
|
80
|
+
return super().execute(context)
|
|
81
|
+
|
|
82
|
+
def _generate_cmds(self, context: Context) -> list[str]:
|
|
83
|
+
context_merge(context, self.op_kwargs)
|
|
84
|
+
kwargs = determine_kwargs(self.python_callable, self.op_args, context)
|
|
85
|
+
generated_cmds = self.python_callable(*self.op_args, **kwargs)
|
|
86
|
+
func_name = self.python_callable.__name__
|
|
87
|
+
if not isinstance(generated_cmds, list):
|
|
88
|
+
raise TypeError(
|
|
89
|
+
f"Expected python_callable to return a list of strings, but got {type(generated_cmds)}"
|
|
90
|
+
)
|
|
91
|
+
if not all(isinstance(cmd, str) for cmd in generated_cmds):
|
|
92
|
+
raise TypeError(f"Expected {func_name} to return a list of strings, but got {generated_cmds}")
|
|
93
|
+
if not generated_cmds:
|
|
94
|
+
raise ValueError(f"The {func_name} returned an empty list of commands")
|
|
95
|
+
|
|
96
|
+
return generated_cmds
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def kubernetes_cmd_task(
|
|
100
|
+
python_callable: Callable | None = None,
|
|
101
|
+
**kwargs,
|
|
102
|
+
) -> TaskDecorator:
|
|
103
|
+
"""
|
|
104
|
+
Kubernetes cmd operator decorator.
|
|
105
|
+
|
|
106
|
+
This wraps a function which should return command to be executed
|
|
107
|
+
in K8s using KubernetesPodOperator. The function should return a list of strings.
|
|
108
|
+
If args_only is set to True, the function should return a list of arguments for
|
|
109
|
+
container default command. Also accepts any argument that KubernetesPodOperator
|
|
110
|
+
will via ``kwargs``. Can be reused in a single DAG.
|
|
111
|
+
|
|
112
|
+
:param python_callable: Function to decorate
|
|
113
|
+
"""
|
|
114
|
+
return task_decorator_factory(
|
|
115
|
+
python_callable=python_callable,
|
|
116
|
+
decorated_operator_class=_KubernetesCmdDecoratedOperator,
|
|
117
|
+
**kwargs,
|
|
118
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from airflow.exceptions import (
|
|
20
|
+
AirflowException,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PodMutationHookException(AirflowException):
|
|
25
|
+
"""Raised when exception happens during Pod Mutation Hook execution."""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PodReconciliationError(AirflowException):
|
|
29
|
+
"""Raised when an error is encountered while trying to merge pod configs."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class KubernetesApiError(AirflowException):
|
|
33
|
+
"""Raised when an error is encountered while trying access Kubernetes API."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class KubernetesApiPermissionError(AirflowException):
|
|
37
|
+
"""Raised when an error is encountered while trying access Kubernetes API."""
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
|
4
|
+
# distributed with this work for additional information
|
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
|
7
|
+
# "License"); you may not use this file except in compliance
|
|
8
|
+
# with the License. You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
|
13
|
+
# software distributed under the License is distributed on an
|
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
# KIND, either express or implied. See the License for the
|
|
16
|
+
# specific language governing permissions and limitations
|
|
17
|
+
# under the License.
|