You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ka...@apache.org on 2022/12/21 22:53:51 UTC
[airflow] branch main updated: Add Flink on K8s Operator (#28512)
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 681835a67c Add Flink on K8s Operator (#28512)
681835a67c is described below
commit 681835a67c89784944f41fce86099bcb2c3a0614
Author: Xinbin Huang <bi...@gmail.com>
AuthorDate: Wed Dec 21 14:53:44 2022 -0800
Add Flink on K8s Operator (#28512)
* Port https://github.com/apache/airflow/pull/26664
Co-Authored-By: chethanuk-plutoflume <16...@users.noreply.github.com>
---
.../airflow_providers_bug_report.yml | 1 +
CONTRIBUTING.rst | 23 +-
INSTALL | 23 +-
airflow/providers/apache/flink/CHANGELOG.rst | 30 +
airflow/providers/apache/flink/__init__.py | 17 +
airflow/providers/apache/flink/hooks/__init__.py | 17 +
.../providers/apache/flink/operators/__init__.py | 17 +
.../apache/flink/operators/flink_kubernetes.py | 118 ++
airflow/providers/apache/flink/provider.yaml | 56 +
airflow/providers/apache/flink/sensors/__init__.py | 17 +
.../apache/flink/sensors/flink_kubernetes.py | 135 +++
.../providers/cncf/kubernetes/hooks/kubernetes.py | 27 +-
.../commits.rst | 40 +
.../index.rst | 86 ++
.../installing-providers-from-sources.rst | 18 +
.../operators.rst | 39 +
docs/apache-airflow/extra-packages-ref.rst | 2 +
docs/integration-logos/kubernetes/FlinkOnK8s.png | Bin 0 -> 222367 bytes
docs/spelling_wordlist.txt | 2 +
generated/provider_dependencies.json | 10 +
images/breeze/output-commands-hash.txt | 10 +-
images/breeze/output-commands.svg | 88 +-
images/breeze/output_build-docs.svg | 72 +-
images/breeze/output_release-management.svg | 30 +-
...t_release-management_generate-issue-content.svg | 54 +-
...e-management_prepare-provider-documentation.svg | 68 +-
...elease-management_prepare-provider-packages.svg | 16 +-
tests/providers/apache/flink/__init__.py | 17 +
tests/providers/apache/flink/operators/__init__.py | 17 +
.../flink/operators/test_flink_kubernetes.py | 345 ++++++
tests/providers/apache/flink/sensors/__init__.py | 17 +
.../apache/flink/sensors/test_flink_kubernetes.py | 1193 ++++++++++++++++++++
32 files changed, 2415 insertions(+), 190 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
index 198c11e284..4b8f1881bf 100644
--- a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
@@ -30,6 +30,7 @@ body:
- apache-cassandra
- apache-drill
- apache-druid
+ - apache-flink
- apache-hdfs
- apache-hive
- apache-kylin
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 96f491b4fc..e7590dea53 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -611,17 +611,18 @@ This is the full list of those extras:
.. START EXTRAS HERE
airbyte, alibaba, all, all_dbs, amazon, apache.atlas, apache.beam, apache.cassandra, apache.drill,
-apache.druid, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig, apache.pinot,
-apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas, atlassian.jira, aws,
-azure, cassandra, celery, cgroups, cloudant, cncf.kubernetes, common.sql, crypto, dask, databricks,
-datadog, dbt.cloud, deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord,
-doc, doc_gen, docker, druid, elasticsearch, exasol, facebook, ftp, gcp, gcp_api, github,
-github_enterprise, google, google_auth, grpc, hashicorp, hdfs, hive, http, imap, influxdb, jdbc,
-jenkins, kerberos, kubernetes, ldap, leveldb, microsoft.azure, microsoft.mssql, microsoft.psrp,
-microsoft.winrm, mongo, mssql, mysql, neo4j, odbc, openfaas, opsgenie, oracle, pagerduty, pandas,
-papermill, password, pinot, plexus, postgres, presto, qds, qubole, rabbitmq, redis, s3, salesforce,
-samba, segment, sendgrid, sentry, sftp, singularity, slack, snowflake, spark, sqlite, ssh, statsd,
-tableau, tabular, telegram, trino, vertica, virtualenv, webhdfs, winrm, yandex, zendesk
+apache.druid, apache.flink, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig,
+apache.pinot, apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas,
+atlassian.jira, aws, azure, cassandra, celery, cgroups, cloudant, cncf.kubernetes, common.sql,
+crypto, dask, databricks, datadog, dbt.cloud, deprecated_api, devel, devel_all, devel_ci,
+devel_hadoop, dingding, discord, doc, doc_gen, docker, druid, elasticsearch, exasol, facebook, ftp,
+gcp, gcp_api, github, github_enterprise, google, google_auth, grpc, hashicorp, hdfs, hive, http,
+imap, influxdb, jdbc, jenkins, kerberos, kubernetes, ldap, leveldb, microsoft.azure,
+microsoft.mssql, microsoft.psrp, microsoft.winrm, mongo, mssql, mysql, neo4j, odbc, openfaas,
+opsgenie, oracle, pagerduty, pandas, papermill, password, pinot, plexus, postgres, presto, qds,
+qubole, rabbitmq, redis, s3, salesforce, samba, segment, sendgrid, sentry, sftp, singularity, slack,
+snowflake, spark, sqlite, ssh, statsd, tableau, tabular, telegram, trino, vertica, virtualenv,
+webhdfs, winrm, yandex, zendesk
.. END EXTRAS HERE
Provider packages
diff --git a/INSTALL b/INSTALL
index d1721a3a71..90feb919e8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -95,17 +95,18 @@ The list of available extras:
# START EXTRAS HERE
airbyte, alibaba, all, all_dbs, amazon, apache.atlas, apache.beam, apache.cassandra, apache.drill,
-apache.druid, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig, apache.pinot,
-apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas, atlassian.jira, aws,
-azure, cassandra, celery, cgroups, cloudant, cncf.kubernetes, common.sql, crypto, dask, databricks,
-datadog, dbt.cloud, deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord,
-doc, doc_gen, docker, druid, elasticsearch, exasol, facebook, ftp, gcp, gcp_api, github,
-github_enterprise, google, google_auth, grpc, hashicorp, hdfs, hive, http, imap, influxdb, jdbc,
-jenkins, kerberos, kubernetes, ldap, leveldb, microsoft.azure, microsoft.mssql, microsoft.psrp,
-microsoft.winrm, mongo, mssql, mysql, neo4j, odbc, openfaas, opsgenie, oracle, pagerduty, pandas,
-papermill, password, pinot, plexus, postgres, presto, qds, qubole, rabbitmq, redis, s3, salesforce,
-samba, segment, sendgrid, sentry, sftp, singularity, slack, snowflake, spark, sqlite, ssh, statsd,
-tableau, tabular, telegram, trino, vertica, virtualenv, webhdfs, winrm, yandex, zendesk
+apache.druid, apache.flink, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig,
+apache.pinot, apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas,
+atlassian.jira, aws, azure, cassandra, celery, cgroups, cloudant, cncf.kubernetes, common.sql,
+crypto, dask, databricks, datadog, dbt.cloud, deprecated_api, devel, devel_all, devel_ci,
+devel_hadoop, dingding, discord, doc, doc_gen, docker, druid, elasticsearch, exasol, facebook, ftp,
+gcp, gcp_api, github, github_enterprise, google, google_auth, grpc, hashicorp, hdfs, hive, http,
+imap, influxdb, jdbc, jenkins, kerberos, kubernetes, ldap, leveldb, microsoft.azure,
+microsoft.mssql, microsoft.psrp, microsoft.winrm, mongo, mssql, mysql, neo4j, odbc, openfaas,
+opsgenie, oracle, pagerduty, pandas, papermill, password, pinot, plexus, postgres, presto, qds,
+qubole, rabbitmq, redis, s3, salesforce, samba, segment, sendgrid, sentry, sftp, singularity, slack,
+snowflake, spark, sqlite, ssh, statsd, tableau, tabular, telegram, trino, vertica, virtualenv,
+webhdfs, winrm, yandex, zendesk
# END EXTRAS HERE
# For installing Airflow in development environments - see CONTRIBUTING.rst
diff --git a/airflow/providers/apache/flink/CHANGELOG.rst b/airflow/providers/apache/flink/CHANGELOG.rst
new file mode 100644
index 0000000000..58638fcd9b
--- /dev/null
+++ b/airflow/providers/apache/flink/CHANGELOG.rst
@@ -0,0 +1,30 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+
+.. NOTE TO CONTRIBUTORS:
+ Please, only add notes to the Changelog just below the "Changelog" header when there are some breaking changes
+ and you want to add an explanation to the users on how they are supposed to deal with them.
+ The changelog is updated and maintained semi-automatically by release manager.
+
+Changelog
+---------
+
+1.0.0
+.....
+
+Initial version of the Flink provider.
diff --git a/airflow/providers/apache/flink/__init__.py b/airflow/providers/apache/flink/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/airflow/providers/apache/flink/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/airflow/providers/apache/flink/hooks/__init__.py b/airflow/providers/apache/flink/hooks/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/airflow/providers/apache/flink/hooks/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/airflow/providers/apache/flink/operators/__init__.py b/airflow/providers/apache/flink/operators/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/airflow/providers/apache/flink/operators/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/airflow/providers/apache/flink/operators/flink_kubernetes.py b/airflow/providers/apache/flink/operators/flink_kubernetes.py
new file mode 100644
index 0000000000..3d365f40be
--- /dev/null
+++ b/airflow/providers/apache/flink/operators/flink_kubernetes.py
@@ -0,0 +1,118 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Sequence
+
+from kubernetes.client import CoreV1Api
+
+from airflow.compat.functools import cached_property
+from airflow.models import BaseOperator
+from airflow.providers.cncf.kubernetes.hooks.kubernetes import KubernetesHook
+
+if TYPE_CHECKING:
+ from airflow.utils.context import Context
+
+
+class FlinkKubernetesOperator(BaseOperator):
+ """
+ Creates flinkDeployment object in kubernetes cluster:
+
+ .. seealso::
+ For more information on how to use this operator, take a look at the guide:
+ :ref:`howto/operator:FlinkKubernetesOperator`
+
+ .. seealso::
+ For more detail about Flink Deployment Object have a look at the reference:
+ https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-main/docs/custom-resource/reference/#flinkdeployment
+
+ :param application_file: Defines Kubernetes 'custom_resource_definition' of 'flinkDeployment' as either a
+ path to a '.yaml' file, '.json' file, YAML string or JSON string.
+ :param namespace: kubernetes namespace to put flinkDeployment
+ :param kubernetes_conn_id: The :ref:`kubernetes connection id <howto/connection:kubernetes>`
+ for the to Kubernetes cluster.
+ :param api_group: kubernetes api group of flinkDeployment
+ :param api_version: kubernetes api version of flinkDeployment
+ :param in_cluster: run kubernetes client with in_cluster configuration.
+ :param cluster_context: context that points to kubernetes cluster.
+ Ignored when in_cluster is True. If None, current-context is used.
+ :param config_file: The path to the Kubernetes config file. (templated)
+ If not specified, default value is ``~/.kube/config``
+ """
+
+ template_fields: Sequence[str] = ("application_file", "namespace")
+ template_ext: Sequence[str] = (".yaml", ".yml", ".json")
+ ui_color = "#f4a460"
+
+ def __init__(
+ self,
+ *,
+ application_file: str,
+ namespace: str | None = None,
+ kubernetes_conn_id: str = "kubernetes_default",
+ api_group: str = "flink.apache.org",
+ api_version: str = "v1beta1",
+ in_cluster: bool | None = None,
+ cluster_context: str | None = None,
+ config_file: str | None = None,
+ plural: str = "flinkdeployments",
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.application_file = application_file
+ self.namespace = namespace
+ self.kubernetes_conn_id = kubernetes_conn_id
+ self.api_group = api_group
+ self.api_version = api_version
+ self.plural = plural
+ self.in_cluster = in_cluster
+ self.cluster_context = cluster_context
+ self.config_file = config_file
+
+ @cached_property
+ def hook(self) -> KubernetesHook:
+ hook = KubernetesHook(
+ conn_id=self.kubernetes_conn_id,
+ in_cluster=self.in_cluster,
+ config_file=self.config_file,
+ cluster_context=self.cluster_context,
+ )
+ return hook
+
+ @cached_property
+ def client(self) -> CoreV1Api:
+ return self.hook.core_v1_client
+
+ def execute(self, context: Context):
+
+ self.log.info(
+ "Creating flinkApplication with Context: %s and op_context: %s", self.cluster_context, context
+ )
+
+ self.hook.custom_object_client.list_cluster_custom_object(
+ group=self.api_group, version=self.api_version, plural=self.plural
+ )
+ self.log.info("body=self.application_file: %s", self.application_file)
+ response = self.hook.create_custom_object(
+ group=self.api_group,
+ version=self.api_version,
+ plural=self.plural,
+ body=self.application_file,
+ namespace=self.namespace,
+ )
+ return response
diff --git a/airflow/providers/apache/flink/provider.yaml b/airflow/providers/apache/flink/provider.yaml
new file mode 100644
index 0000000000..cca3de40c2
--- /dev/null
+++ b/airflow/providers/apache/flink/provider.yaml
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+---
+package-name: apache-airflow-providers-apache-flink
+name: Apache Flink
+description: |
+ `Apache Flink <https://flink.apache.org/>`__
+
+versions:
+ - 1.0.0
+
+dependencies:
+ - apache-airflow>=2.3.0
+ - cryptography>=2.0.0
+ # The Kubernetes API is known to introduce problems when upgraded to a MAJOR version. Airflow Core
+ # Uses Kubernetes for Kubernetes executor, and we also know that Kubernetes Python client follows SemVer
+ # (https://github.com/kubernetes-client/python#compatibility). This is a crucial component of Airflow
+ # So we should limit it to the next MAJOR version and only deliberately bump the version when we
+ # tested it, and we know it can be bumped. Bumping this version should also be connected with
+ # limiting minimum airflow version supported in cncf.kubernetes provider, due to the
+ # potential breaking changes in Airflow Core as well (kubernetes is added as extra, so Airflow
+ # core is not hard-limited via install-requirements, only by extra).
+ - kubernetes>=21.7.0,<24
+
+integrations:
+ - integration-name: Apache Flink
+ external-doc-url: https://github.com/apache/flink-kubernetes-operator
+ how-to-guide:
+ - /docs/apache-airflow-providers-apache-flink/operators.rst # TODO
+ logo: /integration-logos/kubernetes/FlinkOnK8s.png
+ tags: [apache]
+
+operators:
+ - integration-name: Apache Flink
+ python-modules:
+ - airflow.providers.apache.flink.operators.flink_kubernetes
+
+sensors:
+ - integration-name: Apache Flink
+ python-modules:
+ - airflow.providers.apache.flink.sensors.flink_kubernetes
diff --git a/airflow/providers/apache/flink/sensors/__init__.py b/airflow/providers/apache/flink/sensors/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/airflow/providers/apache/flink/sensors/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/airflow/providers/apache/flink/sensors/flink_kubernetes.py b/airflow/providers/apache/flink/sensors/flink_kubernetes.py
new file mode 100644
index 0000000000..3151a63ec5
--- /dev/null
+++ b/airflow/providers/apache/flink/sensors/flink_kubernetes.py
@@ -0,0 +1,135 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Sequence
+
+from kubernetes import client
+
+from airflow.exceptions import AirflowException
+from airflow.providers.cncf.kubernetes.hooks.kubernetes import KubernetesHook
+from airflow.sensors.base import BaseSensorOperator
+
+if TYPE_CHECKING:
+ from airflow.utils.context import Context
+
+
+class FlinkKubernetesSensor(BaseSensorOperator):
+ """
+ Checks flinkDeployment object in kubernetes cluster:
+
+ .. seealso::
+ For more detail about Flink Deployment Object have a look at the reference:
+ https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-main/docs/custom-resource/reference/#flinkdeployment
+
+ :param application_name: flink Application resource name
+ :param namespace: the kubernetes namespace where the flinkDeployment reside in
+ :param kubernetes_conn_id: The :ref:`kubernetes connection<howto/connection:kubernetes>`
+ to Kubernetes cluster
+ :param attach_log: determines whether logs for driver pod should be appended to the sensor log
+ :param api_group: kubernetes api group of flinkDeployment
+ :param api_version: kubernetes api version of flinkDeployment
+ :param plural: kubernetes api custom object plural
+ """
+
+ template_fields: Sequence[str] = ("application_name", "namespace")
+ FAILURE_STATES = ("MISSING", "ERROR")
+ SUCCESS_STATES = ("READY",)
+
+ def __init__(
+ self,
+ *,
+ application_name: str,
+ attach_log: bool = False,
+ namespace: str | None = None,
+ kubernetes_conn_id: str = "kubernetes_default",
+ api_group: str = "flink.apache.org",
+ api_version: str = "v1beta1",
+ plural: str = "flinkdeployments",
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.application_name = application_name
+ self.attach_log = attach_log
+ self.namespace = namespace
+ self.kubernetes_conn_id = kubernetes_conn_id
+ self.hook = KubernetesHook(conn_id=self.kubernetes_conn_id)
+ self.api_group = api_group
+ self.api_version = api_version
+ self.plural = plural
+
+ def _log_driver(self, application_state: str, response: dict) -> None:
+ log_method = self.log.error if application_state in self.FAILURE_STATES else self.log.info
+ if not self.attach_log:
+ return
+ status_info = response["status"]
+ if "jobStatus" in status_info:
+ job_status = status_info["jobStatus"]
+ job_state = job_status["state"] if "state" in job_status else "StateFetchError"
+ self.log.info("Flink Job status is %s", job_state)
+ else:
+ return
+
+ task_manager_labels = status_info["taskManager"]["labelSelector"]
+ all_pods = self.hook.get_namespaced_pod_list(
+ namespace="default", watch=False, label_selector=task_manager_labels
+ )
+
+ namespace = response["metadata"]["namespace"]
+ if len(all_pods.items) > 0:
+ for task_manager in all_pods.items:
+ task_manager_pod_name = task_manager.metadata.name
+
+ self.log.info("Starting logging of task manager pod %s ", task_manager_pod_name)
+ try:
+ log = ""
+ for line in self.hook.get_pod_logs(task_manager_pod_name, namespace=namespace):
+ log += line.decode()
+ log_method(log)
+ except client.rest.ApiException as e:
+ self.log.warning(
+ "Could not read logs for pod %s. It may have been disposed.\n"
+ "Make sure timeToLiveSeconds is set on your flinkDeployment spec.\n"
+ "underlying exception: %s",
+ task_manager_pod_name,
+ e,
+ )
+
+ def poke(self, context: Context) -> bool:
+ self.log.info("Poking: %s", self.application_name)
+ response = self.hook.get_custom_object(
+ group=self.api_group,
+ version=self.api_version,
+ plural=self.plural,
+ name=self.application_name,
+ namespace=self.namespace,
+ )
+ try:
+ application_state = response["status"]["jobManagerDeploymentStatus"]
+ except KeyError:
+ return False
+ if self.attach_log and application_state in self.FAILURE_STATES + self.SUCCESS_STATES:
+ self._log_driver(application_state, response)
+ if application_state in self.FAILURE_STATES:
+ raise AirflowException(f"Flink application failed with state: {application_state}")
+ elif application_state in self.SUCCESS_STATES:
+ self.log.info("Flink application ended successfully")
+ return True
+ else:
+ self.log.info("Flink application is still in state: %s", application_state)
+ return False
diff --git a/airflow/providers/cncf/kubernetes/hooks/kubernetes.py b/airflow/providers/cncf/kubernetes/hooks/kubernetes.py
index 85b76d5f52..1d317a5cdb 100644
--- a/airflow/providers/cncf/kubernetes/hooks/kubernetes.py
+++ b/airflow/providers/cncf/kubernetes/hooks/kubernetes.py
@@ -249,6 +249,10 @@ class KubernetesHook(BaseHook):
def core_v1_client(self) -> client.CoreV1Api:
return client.CoreV1Api(api_client=self.api_client)
+ @cached_property
+ def custom_object_client(self) -> client.CustomObjectsApi:
+ return client.CustomObjectsApi(api_client=self.api_client)
+
def create_custom_object(
self, group: str, version: str, plural: str, body: str | dict, namespace: str | None = None
):
@@ -260,7 +264,7 @@ class KubernetesHook(BaseHook):
:param body: crd object definition
:param namespace: kubernetes namespace
"""
- api = client.CustomObjectsApi(self.api_client)
+ api: client.CustomObjectsApi = self.custom_object_client
namespace = namespace or self._get_namespace() or self.DEFAULT_NAMESPACE
if isinstance(body, str):
@@ -392,6 +396,27 @@ class KubernetesHook(BaseHook):
namespace=namespace or self._get_namespace() or self.DEFAULT_NAMESPACE,
)
+ def get_namespaced_pod_list(
+ self,
+ label_selector: str | None = "",
+ namespace: str | None = None,
+ watch: bool = False,
+ **kwargs,
+ ):
+ """
+ Retrieves a list of Kind pod which belong default kubernetes namespace
+ :param label_selector: A selector to restrict the list of returned objects by their labels
+ :param namespace: kubernetes namespace
+ :param watch: Watch for changes to the described resources and return them as a stream
+ """
+ return self.core_v1_client.list_namespaced_pod(
+ namespace=namespace or self._get_namespace() or self.DEFAULT_NAMESPACE,
+ watch=watch,
+ label_selector=label_selector,
+ _preload_content=False,
+ **kwargs,
+ )
+
def _get_bool(val) -> bool | None:
"""
diff --git a/docs/apache-airflow-providers-apache-flink/commits.rst b/docs/apache-airflow-providers-apache-flink/commits.rst
new file mode 100644
index 0000000000..803131f7ae
--- /dev/null
+++ b/docs/apache-airflow-providers-apache-flink/commits.rst
@@ -0,0 +1,40 @@
+
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+
+Package apache-airflow-providers-apache-flink
+------------------------------------------------------
+
+`Apache Flink <https://flink.apache.org/>`__
+
+
+This is detailed commit list of changes for versions provider package: ``apache.flink``.
+For high-level changelog, see :doc:`package information including changelog <index>`.
+
+
+1.0.0
+.....
+
+Latest change: 2020-12-09
+
+======================================================= =========== ======================================================
+Commit Committed Subject
+======================================================= =========== ======================================================
+`TODO <https://github.com/apache/airflow/commit/TODO>`_ 2020-12-09 ``Initial version providers versions to 1.0.0``
+
+======================================================= =========== ======================================================
diff --git a/docs/apache-airflow-providers-apache-flink/index.rst b/docs/apache-airflow-providers-apache-flink/index.rst
new file mode 100644
index 0000000000..0767205b29
--- /dev/null
+++ b/docs/apache-airflow-providers-apache-flink/index.rst
@@ -0,0 +1,86 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+``apache-airflow-providers-apache-flink``
+=========================================
+
+Content
+-------
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Guides
+
+ Operators <operators>
+
+.. toctree::
+ :maxdepth: 1
+ :caption: References
+
+ Python API <_api/airflow/providers/apache/flink/index>
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Resources
+
+ Example DAGs <https://github.com/apache/airflow/tree/providers-apache-flink/|version|/tests/system/providers/apache/flink>
+ PyPI Repository <https://pypi.org/project/apache-airflow-providers-apache-flink/>
+ Installing from sources <installing-providers-from-sources>
+
+.. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN AT RELEASE TIME!
+
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Commits
+
+ Detailed list of commits <commits>
+
+
+Package apache-airflow-providers-apache-flink
+------------------------------------------------------
+
+`Apache Flink <https://flink.apache.org/>`__
+
+
+Release: 1.0.0
+
+Provider package
+----------------
+
+This is a provider package for ``apache.flink`` provider. All classes for this provider package
+are in ``airflow.providers.apache.flink`` python package.
+
+Installation
+------------
+
+You can install this package on top of an existing Airflow 2 installation (see ``Requirements`` below)
+for the minimum Airflow version supported) via
+``pip install apache-airflow-providers-apache-flink``
+
+Requirements
+------------
+
+================== ==================
+PIP package Version required
+================== ==================
+``apache-airflow`` ``>=2.3.0``
+``cryptography`` ``>=2.0.0``
+``kubernetes`` ``>=21.7.0,<24``
+================== ==================
+
+.. include:: ../../airflow/providers/apache/flink/CHANGELOG.rst
diff --git a/docs/apache-airflow-providers-apache-flink/installing-providers-from-sources.rst b/docs/apache-airflow-providers-apache-flink/installing-providers-from-sources.rst
new file mode 100644
index 0000000000..1c90205d15
--- /dev/null
+++ b/docs/apache-airflow-providers-apache-flink/installing-providers-from-sources.rst
@@ -0,0 +1,18 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. include:: ../installing-providers-from-sources.rst
diff --git a/docs/apache-airflow-providers-apache-flink/operators.rst b/docs/apache-airflow-providers-apache-flink/operators.rst
new file mode 100644
index 0000000000..f8c9ab74ec
--- /dev/null
+++ b/docs/apache-airflow-providers-apache-flink/operators.rst
@@ -0,0 +1,39 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+
+Apache Flink Operators
+======================
+
+.. _howto/operator:FlinkKubernetesOperator:
+
+FlinkKubernetesOperator
+-----------------------
+
+Launches spark applications on a Kubernetes cluster
+
+For parameter definition take a look at :class:`~airflow.providers.apache.flink.operators.flink_kubernetes.FlinkKubernetesOperator`.
+
+
+Reference
+"""""""""
+
+For further information, look at:
+
+* `Flink Kubernetes Operator Documentation <https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-main/>`__
+* `Kubernetes Documentation <https://kubernetes.io/docs/home/>`__
+* `Pull an Image from a Private Registry <https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/>`__
diff --git a/docs/apache-airflow/extra-packages-ref.rst b/docs/apache-airflow/extra-packages-ref.rst
index e9f4bfb399..5787c72d40 100644
--- a/docs/apache-airflow/extra-packages-ref.rst
+++ b/docs/apache-airflow/extra-packages-ref.rst
@@ -122,6 +122,8 @@ custom bash/python providers).
+---------------------+-----------------------------------------------------+------------------------------------------------+
| apache.druid | ``pip install 'apache-airflow[apache.druid]'`` | Druid related operators & hooks |
+---------------------+-----------------------------------------------------+------------------------------------------------+
+| apache.flink | ``pip install 'apache-airflow[apache.flink]'`` | Flink related operators & hooks |
++---------------------+-----------------------------------------------------+------------------------------------------------+
| apache.hdfs | ``pip install 'apache-airflow[apache.hdfs]'`` | HDFS hooks and operators |
+---------------------+-----------------------------------------------------+------------------------------------------------+
| apache.hive | ``pip install 'apache-airflow[apache.hive]'`` | All Hive related operators |
diff --git a/docs/integration-logos/kubernetes/FlinkOnK8s.png b/docs/integration-logos/kubernetes/FlinkOnK8s.png
new file mode 100644
index 0000000000..fe63b93891
Binary files /dev/null and b/docs/integration-logos/kubernetes/FlinkOnK8s.png differ
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 72b8999dab..4e147bbb43 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -565,6 +565,8 @@ Firestore
firestore
firstname
Flink
+flink
+flinkDeployment
FluentD
fluentd
fmt
diff --git a/generated/provider_dependencies.json b/generated/provider_dependencies.json
index 5d538cfaf7..95f212444e 100644
--- a/generated/provider_dependencies.json
+++ b/generated/provider_dependencies.json
@@ -78,6 +78,16 @@
"common.sql"
]
},
+ "apache.flink": {
+ "deps": [
+ "apache-airflow>=2.3.0",
+ "cryptography>=2.0.0",
+ "kubernetes>=21.7.0,<24"
+ ],
+ "cross-providers-deps": [
+ "cncf.kubernetes"
+ ]
+ },
"apache.hdfs": {
"deps": [
"apache-airflow>=2.3.0",
diff --git a/images/breeze/output-commands-hash.txt b/images/breeze/output-commands-hash.txt
index c500e49fad..09056dcac0 100644
--- a/images/breeze/output-commands-hash.txt
+++ b/images/breeze/output-commands-hash.txt
@@ -2,7 +2,7 @@
# Please do not solve it but run `breeze setup regenerate-command-images`.
# This command should fix the conflict and regenerate help images that you have conflict with.
main:50fe93e07fbe182f6d374ea305841240
-build-docs:80555245ea1142991ce1d63c3bf8ce74
+build-docs:903fcf1600e1348d33614d8bec816a09
ci:find-newer-dependencies:8fa2b57f5f0523c928743b235ee3ab5a
ci:fix-ownership:fee2c9ec9ef19686792002ae054fecdd
ci:free-space:47234aa0a60b0efd84972e6e797379f8
@@ -36,13 +36,13 @@ prod-image:pull:e3c89dd908fc44adf6e159c2950ebdd0
prod-image:verify:31bc5efada1d70a0a31990025db1a093
prod-image:4f98deab35e53ebddbdc9950a50555a4
release-management:generate-constraints:ae30d6ad49a1b2c15b61cb29080fd957
-release-management:generate-issue-content:24218438f9e85e7c92258aadebbb19de
+release-management:generate-issue-content:c144f114ddfc859f60da6b7b4987116a
release-management:prepare-airflow-package:3ac14ea6d2b09614959c0ec4fd564789
-release-management:prepare-provider-documentation:3fe5ead9887c518d1b397d1103dc0025
-release-management:prepare-provider-packages:40144cb01afc56f6a4f92d9e117e546e
+release-management:prepare-provider-documentation:ae873854b47240fa36019a14ccc0b705
+release-management:prepare-provider-packages:45d22c47b1d5e09a08d2a7218fe7a8a6
release-management:release-prod-images:c9bc40938e0efad49e51ef66e83f9527
release-management:verify-provider-packages:88bd609aff6d09d52ab8d80d6e055e7b
-release-management:eafd13da512a5a7c0fb1499cf7ff1d63
+release-management:5e44515494c7fd719ddbdb95e5f15514
setup:autocomplete:03343478bf1d0cf9c101d454cdb63b68
setup:config:3ffcd35dd24b486ddf1d08b797e3d017
setup:regenerate-command-images:ab2d83c339fa3a42b0c819b6b6cc88ae
diff --git a/images/breeze/output-commands.svg b/images/breeze/output-commands.svg
index c8763961ad..22001729e6 100644
--- a/images/breeze/output-commands.svg
+++ b/images/breeze/output-commands.svg
@@ -35,8 +35,8 @@
.breeze-help-r1 { fill: #c5c8c6;font-weight: bold }
.breeze-help-r2 { fill: #c5c8c6 }
.breeze-help-r3 { fill: #d0b344;font-weight: bold }
-.breeze-help-r4 { fill: #868887 }
-.breeze-help-r5 { fill: #68a0b3;font-weight: bold }
+.breeze-help-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-help-r5 { fill: #868887 }
.breeze-help-r6 { fill: #98a84b;font-weight: bold }
.breeze-help-r7 { fill: #8d7b39 }
</style>
@@ -187,49 +187,49 @@
<g class="breeze-help-matrix">
<text class="breeze-help-r2" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-help-line-0)">
-</text><text class="breeze-help-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-help-line-1)">Usage: </text><text class="breeze-help-r1" x="97.6" y="44.4" textLength="414.8" clip-path="url(#breeze-help-line-1)">breeze [OPTIONS] COMMAND [ARGS]...</text><text class="breeze-help-r2" x="1464" y="44.4" textLength="12.2" clip-path="url(#breeze-help-line-1)">
+</text><text class="breeze-help-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-help-line-1)">Usage: </text><text class="breeze-help-r1" x="97.6" y="44.4" textLength="97.6" clip-path="url(#breeze-help-line-1)">breeze [</text><text class="breeze-help-r4" x="195.2" y="44.4" textLength="85.4" clip-path="url(#breeze-help-line-1)">OPTIONS</text><text class="breeze-help-r1" x="280.6" y="44.4" textLength="24.4" clip-path="url(#breeze-help-line-1)">] </text><text cl [...]
</text><text class="breeze-help-r2" x="1464" y="68.8" textLength="12.2" clip-path="url(#breeze-help-line-2)">
-</text><text class="breeze-help-r4" x="0" y="93.2" textLength="24.4" clip-path="url(#breeze-help-line-3)">╭─</text><text class="breeze-help-r4" x="24.4" y="93.2" textLength="158.6" clip-path="url(#breeze-help-line-3)"> Basic flags </text><text class="breeze-help-r4" x="183" y="93.2" textLength="1256.6" clip-path="url(#breeze-help-line-3)">───────────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze-help-r [...]
-</text><text class="breeze-help-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#breeze-help-line-4)">│</text><text class="breeze-help-r5" x="24.4" y="117.6" textLength="12.2" clip-path="url(#breeze-help-line-4)">-</text><text class="breeze-help-r5" x="36.6" y="117.6" textLength="85.4" clip-path="url(#breeze-help-line-4)">-python</text><text class="breeze-help-r6" x="305" y="117.6" textLength="24.4" clip-path="url(#breeze-help-line-4)">-p</text><text class="breeze-help-r2" x="353.8" [...]
-</text><text class="breeze-help-r4" x="0" y="142" textLength="12.2" clip-path="url(#breeze-help-line-5)">│</text><text class="breeze-help-r4" x="353.8" y="142" textLength="732" clip-path="url(#breeze-help-line-5)">[default: 3.7]                                           & [...]
-</text><text class="breeze-help-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-help-line-6)">│</text><text class="breeze-help-r5" x="24.4" y="166.4" textLength="12.2" clip-path="url(#breeze-help-line-6)">-</text><text class="breeze-help-r5" x="36.6" y="166.4" textLength="97.6" clip-path="url(#breeze-help-line-6)">-backend</text><text class="breeze-help-r6" x="305" y="166.4" textLength="24.4" clip-path="url(#breeze-help-line-6)">-b</text><text class="breeze-help-r2" x="353.8 [...]
-</text><text class="breeze-help-r4" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-help-line-7)">│</text><text class="breeze-help-r5" x="24.4" y="190.8" textLength="12.2" clip-path="url(#breeze-help-line-7)">-</text><text class="breeze-help-r5" x="36.6" y="190.8" textLength="109.8" clip-path="url(#breeze-help-line-7)">-postgres</text><text class="breeze-help-r5" x="146.4" y="190.8" textLength="97.6" clip-path="url(#breeze-help-line-7)">-version</text><text class="breeze-help-r6 [...]
-</text><text class="breeze-help-r4" x="0" y="215.2" textLength="12.2" clip-path="url(#breeze-help-line-8)">│</text><text class="breeze-help-r5" x="24.4" y="215.2" textLength="12.2" clip-path="url(#breeze-help-line-8)">-</text><text class="breeze-help-r5" x="36.6" y="215.2" textLength="73.2" clip-path="url(#breeze-help-line-8)">-mysql</text><text class="breeze-help-r5" x="109.8" y="215.2" textLength="97.6" clip-path="url(#breeze-help-line-8)">-version</text><text class="breeze-help-r6" x= [...]
-</text><text class="breeze-help-r4" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-help-line-9)">│</text><text class="breeze-help-r5" x="24.4" y="239.6" textLength="12.2" clip-path="url(#breeze-help-line-9)">-</text><text class="breeze-help-r5" x="36.6" y="239.6" textLength="73.2" clip-path="url(#breeze-help-line-9)">-mssql</text><text class="breeze-help-r5" x="109.8" y="239.6" textLength="97.6" clip-path="url(#breeze-help-line-9)">-version</text><text class="breeze-help-r6" x= [...]
-</text><text class="breeze-help-r4" x="0" y="264" textLength="12.2" clip-path="url(#breeze-help-line-10)">│</text><text class="breeze-help-r5" x="24.4" y="264" textLength="12.2" clip-path="url(#breeze-help-line-10)">-</text><text class="breeze-help-r5" x="36.6" y="264" textLength="146.4" clip-path="url(#breeze-help-line-10)">-integration</text><text class="breeze-help-r2" x="353.8" y="264" textLength="744.2" clip-path="url(#breeze-help-line-10)">Integration(s) to enable wh [...]
-</text><text class="breeze-help-r4" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r7" x="353.8" y="288.4" textLength="744.2" clip-path="url(#breeze-help-line-11)">(cassandra | kerberos | mongo | pinot | celery | trino | all)</text><text class="breeze-help-r4" x="1451.8" y="288.4" textLength="12.2" clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r2" [...]
-</text><text class="breeze-help-r4" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r5" x="24.4" y="312.8" textLength="12.2" clip-path="url(#breeze-help-line-12)">-</text><text class="breeze-help-r5" x="36.6" y="312.8" textLength="97.6" clip-path="url(#breeze-help-line-12)">-forward</text><text class="breeze-help-r5" x="134.2" y="312.8" textLength="146.4" clip-path="url(#breeze-help-line-12)">-credentials</text><text class="breeze- [...]
-</text><text class="breeze-help-r4" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-help-line-13)">│</text><text class="breeze-help-r5" x="24.4" y="337.2" textLength="12.2" clip-path="url(#breeze-help-line-13)">-</text><text class="breeze-help-r5" x="36.6" y="337.2" textLength="36.6" clip-path="url(#breeze-help-line-13)">-db</text><text class="breeze-help-r5" x="73.2" y="337.2" textLength="73.2" clip-path="url(#breeze-help-line-13)">-reset</text><text class="breeze-help-r6" x="3 [...]
-</text><text class="breeze-help-r4" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-help-line-14)">│</text><text class="breeze-help-r5" x="24.4" y="361.6" textLength="12.2" clip-path="url(#breeze-help-line-14)">-</text><text class="breeze-help-r5" x="36.6" y="361.6" textLength="48.8" clip-path="url(#breeze-help-line-14)">-max</text><text class="breeze-help-r5" x="85.4" y="361.6" textLength="61" clip-path="url(#breeze-help-line-14)">-time</text><text class="breeze-help-r2" x="353 [...]
-</text><text class="breeze-help-r4" x="0" y="386" textLength="12.2" clip-path="url(#breeze-help-line-15)">│</text><text class="breeze-help-r7" x="353.8" y="386" textLength="1049.2" clip-path="url(#breeze-help-line-15)">(INTEGER RANGE)                                          & [...]
-</text><text class="breeze-help-r4" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-help-line-16)">│</text><text class="breeze-help-r5" x="24.4" y="410.4" textLength="12.2" clip-path="url(#breeze-help-line-16)">-</text><text class="breeze-help-r5" x="36.6" y="410.4" textLength="85.4" clip-path="url(#breeze-help-line-16)">-github</text><text class="breeze-help-r5" x="122" y="410.4" textLength="134.2" clip-path="url(#breeze-help-line-16)">-repository</text><text class="breeze-help [...]
-</text><text class="breeze-help-r4" x="0" y="434.8" textLength="1464" clip-path="url(#breeze-help-line-17)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="434.8" textLength="12.2" clip-path="url(#breeze-help-line-17)">
-</text><text class="breeze-help-r4" x="0" y="459.2" textLength="24.4" clip-path="url(#breeze-help-line-18)">╭─</text><text class="breeze-help-r4" x="24.4" y="459.2" textLength="195.2" clip-path="url(#breeze-help-line-18)"> Common options </text><text class="breeze-help-r4" x="219.6" y="459.2" textLength="1220" clip-path="url(#breeze-help-line-18)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze- [...]
-</text><text class="breeze-help-r4" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-help-line-19)">│</text><text class="breeze-help-r5" x="24.4" y="483.6" textLength="12.2" clip-path="url(#breeze-help-line-19)">-</text><text class="breeze-help-r5" x="36.6" y="483.6" textLength="97.6" clip-path="url(#breeze-help-line-19)">-verbose</text><text class="breeze-help-r6" x="158.6" y="483.6" textLength="24.4" clip-path="url(#breeze-help-line-19)">-v</text><text class="breeze-help-r2" x= [...]
-</text><text class="breeze-help-r4" x="0" y="508" textLength="12.2" clip-path="url(#breeze-help-line-20)">│</text><text class="breeze-help-r5" x="24.4" y="508" textLength="12.2" clip-path="url(#breeze-help-line-20)">-</text><text class="breeze-help-r5" x="36.6" y="508" textLength="48.8" clip-path="url(#breeze-help-line-20)">-dry</text><text class="breeze-help-r5" x="85.4" y="508" textLength="48.8" clip-path="url(#breeze-help-line-20)">-run</text><text class="breeze-help-r6" x="158.6" y=" [...]
-</text><text class="breeze-help-r4" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-help-line-21)">│</text><text class="breeze-help-r5" x="24.4" y="532.4" textLength="12.2" clip-path="url(#breeze-help-line-21)">-</text><text class="breeze-help-r5" x="36.6" y="532.4" textLength="85.4" clip-path="url(#breeze-help-line-21)">-answer</text><text class="breeze-help-r6" x="158.6" y="532.4" textLength="24.4" clip-path="url(#breeze-help-line-21)">-a</text><text class="breeze-help-r2" x=" [...]
-</text><text class="breeze-help-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-help-line-22)">│</text><text class="breeze-help-r5" x="24.4" y="556.8" textLength="12.2" clip-path="url(#breeze-help-line-22)">-</text><text class="breeze-help-r5" x="36.6" y="556.8" textLength="61" clip-path="url(#breeze-help-line-22)">-help</text><text class="breeze-help-r6" x="158.6" y="556.8" textLength="24.4" clip-path="url(#breeze-help-line-22)">-h</text><text class="breeze-help-r2" x="207. [...]
-</text><text class="breeze-help-r4" x="0" y="581.2" textLength="1464" clip-path="url(#breeze-help-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="581.2" textLength="12.2" clip-path="url(#breeze-help-line-23)">
-</text><text class="breeze-help-r4" x="0" y="605.6" textLength="24.4" clip-path="url(#breeze-help-line-24)">╭─</text><text class="breeze-help-r4" x="24.4" y="605.6" textLength="317.2" clip-path="url(#breeze-help-line-24)"> Basic developer commands </text><text class="breeze-help-r4" x="341.6" y="605.6" textLength="1098" clip-path="url(#breeze-help-line-24)">──────────────────────────────────────────────────────────────────────────────────────────</text><text class="br [...]
-</text><text class="breeze-help-r4" x="0" y="630" textLength="12.2" clip-path="url(#breeze-help-line-25)">│</text><text class="breeze-help-r5" x="24.4" y="630" textLength="219.6" clip-path="url(#breeze-help-line-25)">start-airflow     </text><text class="breeze-help-r2" x="268.4" y="630" textLength="1171.2" clip-path="url(#breeze-help-line-25)">Enter breeze environment and starts all Airflow components in the tmux [...]
-</text><text class="breeze-help-r4" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-help-line-26)">│</text><text class="breeze-help-r2" x="268.4" y="654.4" textLength="1171.2" clip-path="url(#breeze-help-line-26)">if contents of www directory changed.                                   [...]
-</text><text class="breeze-help-r4" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-help-line-27)">│</text><text class="breeze-help-r5" x="24.4" y="678.8" textLength="219.6" clip-path="url(#breeze-help-line-27)">static-checks     </text><text class="breeze-help-r2" x="268.4" y="678.8" textLength="1171.2" clip-path="url(#breeze-help-line-27)">Run static checks.              &# [...]
-</text><text class="breeze-help-r4" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-help-line-28)">│</text><text class="breeze-help-r5" x="24.4" y="703.2" textLength="219.6" clip-path="url(#breeze-help-line-28)">build-docs        </text><text class="breeze-help-r2" x="268.4" y="703.2" textLength="1171.2" clip-path="url(#breeze-help-line-28)">Build documentation in the container.        [...]
-</text><text class="breeze-help-r4" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-help-line-29)">│</text><text class="breeze-help-r5" x="24.4" y="727.6" textLength="219.6" clip-path="url(#breeze-help-line-29)">stop              </text><text class="breeze-help-r2" x="268.4" y="727.6" textLength="1171.2" clip-path="url(#breeze-help-line-29)">Stop running breeze environment.    [...]
-</text><text class="breeze-help-r4" x="0" y="752" textLength="12.2" clip-path="url(#breeze-help-line-30)">│</text><text class="breeze-help-r5" x="24.4" y="752" textLength="219.6" clip-path="url(#breeze-help-line-30)">shell             </text><text class="breeze-help-r2" x="268.4" y="752" textLength="1171.2" clip-path="url(#breeze-help-line-30)">Enter breeze environment. this is the default  [...]
-</text><text class="breeze-help-r4" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-help-line-31)">│</text><text class="breeze-help-r5" x="24.4" y="776.4" textLength="219.6" clip-path="url(#breeze-help-line-31)">exec              </text><text class="breeze-help-r2" x="268.4" y="776.4" textLength="1171.2" clip-path="url(#breeze-help-line-31)">Joins the interactive shell of running  [...]
-</text><text class="breeze-help-r4" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-help-line-32)">│</text><text class="breeze-help-r5" x="24.4" y="800.8" textLength="219.6" clip-path="url(#breeze-help-line-32)">compile-www-assets</text><text class="breeze-help-r2" x="268.4" y="800.8" textLength="1171.2" clip-path="url(#breeze-help-line-32)">Compiles www assets.                  & [...]
-</text><text class="breeze-help-r4" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-help-line-33)">│</text><text class="breeze-help-r5" x="24.4" y="825.2" textLength="219.6" clip-path="url(#breeze-help-line-33)">cleanup           </text><text class="breeze-help-r2" x="268.4" y="825.2" textLength="1171.2" clip-path="url(#breeze-help-line-33)">Cleans the cache of parameters, docker cache and& [...]
-</text><text class="breeze-help-r4" x="0" y="849.6" textLength="1464" clip-path="url(#breeze-help-line-34)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="849.6" textLength="12.2" clip-path="url(#breeze-help-line-34)">
-</text><text class="breeze-help-r4" x="0" y="874" textLength="24.4" clip-path="url(#breeze-help-line-35)">╭─</text><text class="breeze-help-r4" x="24.4" y="874" textLength="305" clip-path="url(#breeze-help-line-35)"> Advanced command groups </text><text class="breeze-help-r4" x="329.4" y="874" textLength="1110.2" clip-path="url(#breeze-help-line-35)">───────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze-h [...]
-</text><text class="breeze-help-r4" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-help-line-36)">│</text><text class="breeze-help-r5" x="24.4" y="898.4" textLength="280.6" clip-path="url(#breeze-help-line-36)">testing                </text><text class="breeze-help-r2" x="329.4" y="898.4" textLength="1110.2" clip-path="url(#breeze-help-line-36)">Tools that developers can use  [...]
-</text><text class="breeze-help-r4" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-help-line-37)">│</text><text class="breeze-help-r5" x="24.4" y="922.8" textLength="280.6" clip-path="url(#breeze-help-line-37)">ci-image               </text><text class="breeze-help-r2" x="329.4" y="922.8" textLength="1110.2" clip-path="url(#breeze-help-line-37)">Tools that developers can use to&# [...]
-</text><text class="breeze-help-r4" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-help-line-38)">│</text><text class="breeze-help-r5" x="24.4" y="947.2" textLength="280.6" clip-path="url(#breeze-help-line-38)">k8s                    </text><text class="breeze-help-r2" x="329.4" y="947.2" textLength="1110.2" clip-path="url(#breeze-help-line-38)">Tools that developers [...]
-</text><text class="breeze-help-r4" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-help-line-39)">│</text><text class="breeze-help-r5" x="24.4" y="971.6" textLength="280.6" clip-path="url(#breeze-help-line-39)">prod-image             </text><text class="breeze-help-r2" x="329.4" y="971.6" textLength="1110.2" clip-path="url(#breeze-help-line-39)">Tools that developers can use to manual [...]
-</text><text class="breeze-help-r4" x="0" y="996" textLength="12.2" clip-path="url(#breeze-help-line-40)">│</text><text class="breeze-help-r5" x="24.4" y="996" textLength="280.6" clip-path="url(#breeze-help-line-40)">setup                  </text><text class="breeze-help-r2" x="329.4" y="996" textLength="1110.2" clip-path="url(#breeze-help-line-40)">Tools that developers can use& [...]
-</text><text class="breeze-help-r4" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-help-line-41)">│</text><text class="breeze-help-r5" x="24.4" y="1020.4" textLength="280.6" clip-path="url(#breeze-help-line-41)">release-management     </text><text class="breeze-help-r2" x="329.4" y="1020.4" textLength="1110.2" clip-path="url(#breeze-help-line-41)">Tools that release managers can use to prepare and manage [...]
-</text><text class="breeze-help-r4" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-help-line-42)">│</text><text class="breeze-help-r5" x="24.4" y="1044.8" textLength="280.6" clip-path="url(#breeze-help-line-42)">ci                     </text><text class="breeze-help-r2" x="329.4" y="1044.8" textLength="1110.2" clip-path="url(#breeze-help-line-42)">Tools that CI [...]
-</text><text class="breeze-help-r4" x="0" y="1069.2" textLength="1464" clip-path="url(#breeze-help-line-43)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="1069.2" textLength="12.2" clip-path="url(#breeze-help-line-43)">
+</text><text class="breeze-help-r5" x="0" y="93.2" textLength="24.4" clip-path="url(#breeze-help-line-3)">╭─</text><text class="breeze-help-r5" x="24.4" y="93.2" textLength="158.6" clip-path="url(#breeze-help-line-3)"> Basic flags </text><text class="breeze-help-r5" x="183" y="93.2" textLength="1256.6" clip-path="url(#breeze-help-line-3)">───────────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze-help-r [...]
+</text><text class="breeze-help-r5" x="0" y="117.6" textLength="12.2" clip-path="url(#breeze-help-line-4)">│</text><text class="breeze-help-r4" x="24.4" y="117.6" textLength="12.2" clip-path="url(#breeze-help-line-4)">-</text><text class="breeze-help-r4" x="36.6" y="117.6" textLength="85.4" clip-path="url(#breeze-help-line-4)">-python</text><text class="breeze-help-r6" x="305" y="117.6" textLength="24.4" clip-path="url(#breeze-help-line-4)">-p</text><text class="breeze-help-r2" x="353.8" [...]
+</text><text class="breeze-help-r5" x="0" y="142" textLength="12.2" clip-path="url(#breeze-help-line-5)">│</text><text class="breeze-help-r5" x="353.8" y="142" textLength="732" clip-path="url(#breeze-help-line-5)">[default: 3.7]                                           & [...]
+</text><text class="breeze-help-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-help-line-6)">│</text><text class="breeze-help-r4" x="24.4" y="166.4" textLength="12.2" clip-path="url(#breeze-help-line-6)">-</text><text class="breeze-help-r4" x="36.6" y="166.4" textLength="97.6" clip-path="url(#breeze-help-line-6)">-backend</text><text class="breeze-help-r6" x="305" y="166.4" textLength="24.4" clip-path="url(#breeze-help-line-6)">-b</text><text class="breeze-help-r2" x="353.8 [...]
+</text><text class="breeze-help-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-help-line-7)">│</text><text class="breeze-help-r4" x="24.4" y="190.8" textLength="12.2" clip-path="url(#breeze-help-line-7)">-</text><text class="breeze-help-r4" x="36.6" y="190.8" textLength="109.8" clip-path="url(#breeze-help-line-7)">-postgres</text><text class="breeze-help-r4" x="146.4" y="190.8" textLength="97.6" clip-path="url(#breeze-help-line-7)">-version</text><text class="breeze-help-r6 [...]
+</text><text class="breeze-help-r5" x="0" y="215.2" textLength="12.2" clip-path="url(#breeze-help-line-8)">│</text><text class="breeze-help-r4" x="24.4" y="215.2" textLength="12.2" clip-path="url(#breeze-help-line-8)">-</text><text class="breeze-help-r4" x="36.6" y="215.2" textLength="73.2" clip-path="url(#breeze-help-line-8)">-mysql</text><text class="breeze-help-r4" x="109.8" y="215.2" textLength="97.6" clip-path="url(#breeze-help-line-8)">-version</text><text class="breeze-help-r6" x= [...]
+</text><text class="breeze-help-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-help-line-9)">│</text><text class="breeze-help-r4" x="24.4" y="239.6" textLength="12.2" clip-path="url(#breeze-help-line-9)">-</text><text class="breeze-help-r4" x="36.6" y="239.6" textLength="73.2" clip-path="url(#breeze-help-line-9)">-mssql</text><text class="breeze-help-r4" x="109.8" y="239.6" textLength="97.6" clip-path="url(#breeze-help-line-9)">-version</text><text class="breeze-help-r6" x= [...]
+</text><text class="breeze-help-r5" x="0" y="264" textLength="12.2" clip-path="url(#breeze-help-line-10)">│</text><text class="breeze-help-r4" x="24.4" y="264" textLength="12.2" clip-path="url(#breeze-help-line-10)">-</text><text class="breeze-help-r4" x="36.6" y="264" textLength="146.4" clip-path="url(#breeze-help-line-10)">-integration</text><text class="breeze-help-r2" x="353.8" y="264" textLength="744.2" clip-path="url(#breeze-help-line-10)">Integration(s) to enable wh [...]
+</text><text class="breeze-help-r5" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r7" x="353.8" y="288.4" textLength="744.2" clip-path="url(#breeze-help-line-11)">(cassandra | kerberos | mongo | pinot | celery | trino | all)</text><text class="breeze-help-r5" x="1451.8" y="288.4" textLength="12.2" clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r2" [...]
+</text><text class="breeze-help-r5" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r4" x="24.4" y="312.8" textLength="12.2" clip-path="url(#breeze-help-line-12)">-</text><text class="breeze-help-r4" x="36.6" y="312.8" textLength="97.6" clip-path="url(#breeze-help-line-12)">-forward</text><text class="breeze-help-r4" x="134.2" y="312.8" textLength="146.4" clip-path="url(#breeze-help-line-12)">-credentials</text><text class="breeze- [...]
+</text><text class="breeze-help-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-help-line-13)">│</text><text class="breeze-help-r4" x="24.4" y="337.2" textLength="12.2" clip-path="url(#breeze-help-line-13)">-</text><text class="breeze-help-r4" x="36.6" y="337.2" textLength="36.6" clip-path="url(#breeze-help-line-13)">-db</text><text class="breeze-help-r4" x="73.2" y="337.2" textLength="73.2" clip-path="url(#breeze-help-line-13)">-reset</text><text class="breeze-help-r6" x="3 [...]
+</text><text class="breeze-help-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-help-line-14)">│</text><text class="breeze-help-r4" x="24.4" y="361.6" textLength="12.2" clip-path="url(#breeze-help-line-14)">-</text><text class="breeze-help-r4" x="36.6" y="361.6" textLength="48.8" clip-path="url(#breeze-help-line-14)">-max</text><text class="breeze-help-r4" x="85.4" y="361.6" textLength="61" clip-path="url(#breeze-help-line-14)">-time</text><text class="breeze-help-r2" x="353 [...]
+</text><text class="breeze-help-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-help-line-15)">│</text><text class="breeze-help-r7" x="353.8" y="386" textLength="1049.2" clip-path="url(#breeze-help-line-15)">(INTEGER RANGE)                                          & [...]
+</text><text class="breeze-help-r5" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-help-line-16)">│</text><text class="breeze-help-r4" x="24.4" y="410.4" textLength="12.2" clip-path="url(#breeze-help-line-16)">-</text><text class="breeze-help-r4" x="36.6" y="410.4" textLength="85.4" clip-path="url(#breeze-help-line-16)">-github</text><text class="breeze-help-r4" x="122" y="410.4" textLength="134.2" clip-path="url(#breeze-help-line-16)">-repository</text><text class="breeze-help [...]
+</text><text class="breeze-help-r5" x="0" y="434.8" textLength="1464" clip-path="url(#breeze-help-line-17)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="434.8" textLength="12.2" clip-path="url(#breeze-help-line-17)">
+</text><text class="breeze-help-r5" x="0" y="459.2" textLength="24.4" clip-path="url(#breeze-help-line-18)">╭─</text><text class="breeze-help-r5" x="24.4" y="459.2" textLength="195.2" clip-path="url(#breeze-help-line-18)"> Common options </text><text class="breeze-help-r5" x="219.6" y="459.2" textLength="1220" clip-path="url(#breeze-help-line-18)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze- [...]
+</text><text class="breeze-help-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-help-line-19)">│</text><text class="breeze-help-r4" x="24.4" y="483.6" textLength="12.2" clip-path="url(#breeze-help-line-19)">-</text><text class="breeze-help-r4" x="36.6" y="483.6" textLength="97.6" clip-path="url(#breeze-help-line-19)">-verbose</text><text class="breeze-help-r6" x="158.6" y="483.6" textLength="24.4" clip-path="url(#breeze-help-line-19)">-v</text><text class="breeze-help-r2" x= [...]
+</text><text class="breeze-help-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-help-line-20)">│</text><text class="breeze-help-r4" x="24.4" y="508" textLength="12.2" clip-path="url(#breeze-help-line-20)">-</text><text class="breeze-help-r4" x="36.6" y="508" textLength="48.8" clip-path="url(#breeze-help-line-20)">-dry</text><text class="breeze-help-r4" x="85.4" y="508" textLength="48.8" clip-path="url(#breeze-help-line-20)">-run</text><text class="breeze-help-r6" x="158.6" y=" [...]
+</text><text class="breeze-help-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-help-line-21)">│</text><text class="breeze-help-r4" x="24.4" y="532.4" textLength="12.2" clip-path="url(#breeze-help-line-21)">-</text><text class="breeze-help-r4" x="36.6" y="532.4" textLength="85.4" clip-path="url(#breeze-help-line-21)">-answer</text><text class="breeze-help-r6" x="158.6" y="532.4" textLength="24.4" clip-path="url(#breeze-help-line-21)">-a</text><text class="breeze-help-r2" x=" [...]
+</text><text class="breeze-help-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-help-line-22)">│</text><text class="breeze-help-r4" x="24.4" y="556.8" textLength="12.2" clip-path="url(#breeze-help-line-22)">-</text><text class="breeze-help-r4" x="36.6" y="556.8" textLength="61" clip-path="url(#breeze-help-line-22)">-help</text><text class="breeze-help-r6" x="158.6" y="556.8" textLength="24.4" clip-path="url(#breeze-help-line-22)">-h</text><text class="breeze-help-r2" x="207. [...]
+</text><text class="breeze-help-r5" x="0" y="581.2" textLength="1464" clip-path="url(#breeze-help-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="581.2" textLength="12.2" clip-path="url(#breeze-help-line-23)">
+</text><text class="breeze-help-r5" x="0" y="605.6" textLength="24.4" clip-path="url(#breeze-help-line-24)">╭─</text><text class="breeze-help-r5" x="24.4" y="605.6" textLength="317.2" clip-path="url(#breeze-help-line-24)"> Basic developer commands </text><text class="breeze-help-r5" x="341.6" y="605.6" textLength="1098" clip-path="url(#breeze-help-line-24)">──────────────────────────────────────────────────────────────────────────────────────────</text><text class="br [...]
+</text><text class="breeze-help-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-help-line-25)">│</text><text class="breeze-help-r4" x="24.4" y="630" textLength="219.6" clip-path="url(#breeze-help-line-25)">start-airflow     </text><text class="breeze-help-r2" x="268.4" y="630" textLength="1171.2" clip-path="url(#breeze-help-line-25)">Enter breeze environment and starts all Airflow components in the tmux [...]
+</text><text class="breeze-help-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-help-line-26)">│</text><text class="breeze-help-r2" x="268.4" y="654.4" textLength="1171.2" clip-path="url(#breeze-help-line-26)">if contents of www directory changed.                                   [...]
+</text><text class="breeze-help-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-help-line-27)">│</text><text class="breeze-help-r4" x="24.4" y="678.8" textLength="219.6" clip-path="url(#breeze-help-line-27)">static-checks     </text><text class="breeze-help-r2" x="268.4" y="678.8" textLength="1171.2" clip-path="url(#breeze-help-line-27)">Run static checks.              &# [...]
+</text><text class="breeze-help-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-help-line-28)">│</text><text class="breeze-help-r4" x="24.4" y="703.2" textLength="219.6" clip-path="url(#breeze-help-line-28)">build-docs        </text><text class="breeze-help-r2" x="268.4" y="703.2" textLength="1171.2" clip-path="url(#breeze-help-line-28)">Build documentation in the container.        [...]
+</text><text class="breeze-help-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-help-line-29)">│</text><text class="breeze-help-r4" x="24.4" y="727.6" textLength="219.6" clip-path="url(#breeze-help-line-29)">stop              </text><text class="breeze-help-r2" x="268.4" y="727.6" textLength="1171.2" clip-path="url(#breeze-help-line-29)">Stop running breeze environment.    [...]
+</text><text class="breeze-help-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-help-line-30)">│</text><text class="breeze-help-r4" x="24.4" y="752" textLength="219.6" clip-path="url(#breeze-help-line-30)">shell             </text><text class="breeze-help-r2" x="268.4" y="752" textLength="1171.2" clip-path="url(#breeze-help-line-30)">Enter breeze environment. this is the default  [...]
+</text><text class="breeze-help-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-help-line-31)">│</text><text class="breeze-help-r4" x="24.4" y="776.4" textLength="219.6" clip-path="url(#breeze-help-line-31)">exec              </text><text class="breeze-help-r2" x="268.4" y="776.4" textLength="1171.2" clip-path="url(#breeze-help-line-31)">Joins the interactive shell of running  [...]
+</text><text class="breeze-help-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-help-line-32)">│</text><text class="breeze-help-r4" x="24.4" y="800.8" textLength="219.6" clip-path="url(#breeze-help-line-32)">compile-www-assets</text><text class="breeze-help-r2" x="268.4" y="800.8" textLength="1171.2" clip-path="url(#breeze-help-line-32)">Compiles www assets.                  & [...]
+</text><text class="breeze-help-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-help-line-33)">│</text><text class="breeze-help-r4" x="24.4" y="825.2" textLength="219.6" clip-path="url(#breeze-help-line-33)">cleanup           </text><text class="breeze-help-r2" x="268.4" y="825.2" textLength="805.2" clip-path="url(#breeze-help-line-33)">Cleans the cache of parameters, docker cache and&# [...]
+</text><text class="breeze-help-r5" x="0" y="849.6" textLength="1464" clip-path="url(#breeze-help-line-34)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="849.6" textLength="12.2" clip-path="url(#breeze-help-line-34)">
+</text><text class="breeze-help-r5" x="0" y="874" textLength="24.4" clip-path="url(#breeze-help-line-35)">╭─</text><text class="breeze-help-r5" x="24.4" y="874" textLength="305" clip-path="url(#breeze-help-line-35)"> Advanced command groups </text><text class="breeze-help-r5" x="329.4" y="874" textLength="1110.2" clip-path="url(#breeze-help-line-35)">───────────────────────────────────────────────────────────────────────────────────────────</text><text class="breeze-h [...]
+</text><text class="breeze-help-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-help-line-36)">│</text><text class="breeze-help-r4" x="24.4" y="898.4" textLength="280.6" clip-path="url(#breeze-help-line-36)">testing                </text><text class="breeze-help-r2" x="329.4" y="898.4" textLength="1110.2" clip-path="url(#breeze-help-line-36)">Tools that developers can use  [...]
+</text><text class="breeze-help-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-help-line-37)">│</text><text class="breeze-help-r4" x="24.4" y="922.8" textLength="280.6" clip-path="url(#breeze-help-line-37)">ci-image               </text><text class="breeze-help-r2" x="329.4" y="922.8" textLength="597.8" clip-path="url(#breeze-help-line-37)">Tools that developers can use to [...]
+</text><text class="breeze-help-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-help-line-38)">│</text><text class="breeze-help-r4" x="24.4" y="947.2" textLength="280.6" clip-path="url(#breeze-help-line-38)">k8s                    </text><text class="breeze-help-r2" x="329.4" y="947.2" textLength="1110.2" clip-path="url(#breeze-help-line-38)">Tools that developers [...]
+</text><text class="breeze-help-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-help-line-39)">│</text><text class="breeze-help-r4" x="24.4" y="971.6" textLength="280.6" clip-path="url(#breeze-help-line-39)">prod-image             </text><text class="breeze-help-r2" x="329.4" y="971.6" textLength="597.8" clip-path="url(#breeze-help-line-39)">Tools that developers can use to manuall [...]
+</text><text class="breeze-help-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-help-line-40)">│</text><text class="breeze-help-r4" x="24.4" y="996" textLength="280.6" clip-path="url(#breeze-help-line-40)">setup                  </text><text class="breeze-help-r2" x="329.4" y="996" textLength="1110.2" clip-path="url(#breeze-help-line-40)">Tools that developers can use& [...]
+</text><text class="breeze-help-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-help-line-41)">│</text><text class="breeze-help-r4" x="24.4" y="1020.4" textLength="280.6" clip-path="url(#breeze-help-line-41)">release-management     </text><text class="breeze-help-r2" x="329.4" y="1020.4" textLength="1110.2" clip-path="url(#breeze-help-line-41)">Tools that release managers can use to prepare and manage [...]
+</text><text class="breeze-help-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-help-line-42)">│</text><text class="breeze-help-r4" x="24.4" y="1044.8" textLength="280.6" clip-path="url(#breeze-help-line-42)">ci                     </text><text class="breeze-help-r2" x="329.4" y="1044.8" textLength="134.2" clip-path="url(#breeze-help-line-42)">Tools that </text [...]
+</text><text class="breeze-help-r5" x="0" y="1069.2" textLength="1464" clip-path="url(#breeze-help-line-43)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-help-r2" x="1464" y="1069.2" textLength="12.2" clip-path="url(#breeze-help-line-43)">
</text>
</g>
</g>
diff --git a/images/breeze/output_build-docs.svg b/images/breeze/output_build-docs.svg
index 693781f961..2b3d76f05a 100644
--- a/images/breeze/output_build-docs.svg
+++ b/images/breeze/output_build-docs.svg
@@ -247,42 +247,42 @@
</text><text class="breeze-build-docs-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-13)">│</text><text class="breeze-build-docs-r7" x="329.4" y="337.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-13)">(apache-airflow | apache-airflow-providers-airbyte | apache-airflow-providers-alibaba |    </text><text class="breeze-build-docs-r5" x="1451.8" y="337.2" textLength="12.2" clip-path="url(#breeze-build [...]
</text><text class="breeze-build-docs-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-14)">│</text><text class="breeze-build-docs-r7" x="329.4" y="361.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-14)">apache-airflow-providers-amazon | apache-airflow-providers-apache-beam |                   </text><text class="breeze-build-docs-r5" x= [...]
</text><text class="breeze-build-docs-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-build-docs-line-15)">│</text><text class="breeze-build-docs-r7" x="329.4" y="386" textLength="1110.2" clip-path="url(#breeze-build-docs-line-15)">apache-airflow-providers-apache-cassandra | apache-airflow-providers-apache-drill |        </text><text class="breeze-build-docs-r5" x="1451.8" y="386" textLength="12.2" clip-path="url(#breeze-b [...]
-</text><text class="breeze-build-docs-r5" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-16)">│</text><text class="breeze-build-docs-r7" x="329.4" y="410.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-16)">apache-airflow-providers-apache-druid | apache-airflow-providers-apache-hdfs |             </text><text class="breeze-build-docs-r5" x="1451.8" y="410.4" textLength= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-17)">│</text><text class="breeze-build-docs-r7" x="329.4" y="434.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-17)">apache-airflow-providers-apache-hive | apache-airflow-providers-apache-kylin |             </text><text class="breeze-build-docs-r5" x="1451.8" y="434.8" textLength= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-18)">│</text><text class="breeze-build-docs-r7" x="329.4" y="459.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-18)">apache-airflow-providers-apache-livy | apache-airflow-providers-apache-pig |               </text><text class="breeze-build-docs-r5" x="1451.8" y="459.2" t [...]
-</text><text class="breeze-build-docs-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-19)">│</text><text class="breeze-build-docs-r7" x="329.4" y="483.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-19)">apache-airflow-providers-apache-pinot | apache-airflow-providers-apache-spark |            </text><text class="breeze-build-docs-r5" x="1451.8" y="483.6" textLength="12.2 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-build-docs-line-20)">│</text><text class="breeze-build-docs-r7" x="329.4" y="508" textLength="1110.2" clip-path="url(#breeze-build-docs-line-20)">apache-airflow-providers-apache-sqoop | apache-airflow-providers-arangodb |                </text><text class="breeze-build-docs-r5" x="1451.8" y="508" te [...]
-</text><text class="breeze-build-docs-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-21)">│</text><text class="breeze-build-docs-r7" x="329.4" y="532.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-21)">apache-airflow-providers-asana | apache-airflow-providers-atlassian-jira |                 </text><text class="breeze-build-docs-r5" x="1451.8" y [...]
-</text><text class="breeze-build-docs-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-22)">│</text><text class="breeze-build-docs-r7" x="329.4" y="556.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-22)">apache-airflow-providers-celery | apache-airflow-providers-cloudant |                      </text><text class="breeze-bu [...]
-</text><text class="breeze-build-docs-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-23)">│</text><text class="breeze-build-docs-r7" x="329.4" y="581.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-23)">apache-airflow-providers-cncf-kubernetes | apache-airflow-providers-common-sql |           </text><text class="breeze-build-docs-r5" x="1451.8" y="581.2" textLength="12.2" cli [...]
-</text><text class="breeze-build-docs-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-24)">│</text><text class="breeze-build-docs-r7" x="329.4" y="605.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-24)">apache-airflow-providers-databricks | apache-airflow-providers-datadog |                   </text><text class="breeze-build-docs-r5" x= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-build-docs-line-25)">│</text><text class="breeze-build-docs-r7" x="329.4" y="630" textLength="1110.2" clip-path="url(#breeze-build-docs-line-25)">apache-airflow-providers-dbt-cloud | apache-airflow-providers-dingding |                   </text><text class="breeze-build-docs-r5" x="145 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-26)">│</text><text class="breeze-build-docs-r7" x="329.4" y="654.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-26)">apache-airflow-providers-discord | apache-airflow-providers-docker |                       </text><text class="bree [...]
-</text><text class="breeze-build-docs-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-27)">│</text><text class="breeze-build-docs-r7" x="329.4" y="678.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-27)">apache-airflow-providers-elasticsearch | apache-airflow-providers-exasol |                 </text><text class="breeze-build-docs-r5" x="1451.8" y [...]
-</text><text class="breeze-build-docs-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-28)">│</text><text class="breeze-build-docs-r7" x="329.4" y="703.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-28)">apache-airflow-providers-facebook | apache-airflow-providers-ftp |                         </text><text c [...]
-</text><text class="breeze-build-docs-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-29)">│</text><text class="breeze-build-docs-r7" x="329.4" y="727.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-29)">apache-airflow-providers-github | apache-airflow-providers-google |                        </text><text class= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-build-docs-line-30)">│</text><text class="breeze-build-docs-r7" x="329.4" y="752" textLength="1110.2" clip-path="url(#breeze-build-docs-line-30)">apache-airflow-providers-grpc | apache-airflow-providers-hashicorp |                       </text><text class="breeze-b [...]
-</text><text class="breeze-build-docs-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-31)">│</text><text class="breeze-build-docs-r7" x="329.4" y="776.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-31)">apache-airflow-providers-http | apache-airflow-providers-imap |                             [...]
-</text><text class="breeze-build-docs-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-32)">│</text><text class="breeze-build-docs-r7" x="329.4" y="800.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-32)">apache-airflow-providers-influxdb | apache-airflow-providers-jdbc |                        </text><text class= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-33)">│</text><text class="breeze-build-docs-r7" x="329.4" y="825.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-33)">apache-airflow-providers-jenkins | apache-airflow-providers-microsoft-azure |              </text><text class="breeze-build-docs-r5" x="1451.8" y="825.2" textLe [...]
-</text><text class="breeze-build-docs-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-34)">│</text><text class="breeze-build-docs-r7" x="329.4" y="849.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-34)">apache-airflow-providers-microsoft-mssql | apache-airflow-providers-microsoft-psrp |       </text><text class="breeze-build-docs-r5" x="1451.8" y="849.6" textLength="12.2" clip-path="url(#breeze- [...]
-</text><text class="breeze-build-docs-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-build-docs-line-35)">│</text><text class="breeze-build-docs-r7" x="329.4" y="874" textLength="1110.2" clip-path="url(#breeze-build-docs-line-35)">apache-airflow-providers-microsoft-winrm | apache-airflow-providers-mongo |                </text><text class="breeze-build-docs-r5" x="1451.8" y="874" te [...]
-</text><text class="breeze-build-docs-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-36)">│</text><text class="breeze-build-docs-r7" x="329.4" y="898.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-36)">apache-airflow-providers-mysql | apache-airflow-providers-neo4j |                          </text><t [...]
-</text><text class="breeze-build-docs-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-37)">│</text><text class="breeze-build-docs-r7" x="329.4" y="922.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-37)">apache-airflow-providers-odbc | apache-airflow-providers-openfaas |                        </text><text class= [...]
-</text><text class="breeze-build-docs-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-38)">│</text><text class="breeze-build-docs-r7" x="329.4" y="947.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-38)">apache-airflow-providers-opsgenie | apache-airflow-providers-oracle |                      </text><text class="breeze-bu [...]
-</text><text class="breeze-build-docs-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-39)">│</text><text class="breeze-build-docs-r7" x="329.4" y="971.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-39)">apache-airflow-providers-pagerduty | apache-airflow-providers-papermill |                  </text><text class="breeze-build-docs-r5" x="1451 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-build-docs-line-40)">│</text><text class="breeze-build-docs-r7" x="329.4" y="996" textLength="1110.2" clip-path="url(#breeze-build-docs-line-40)">apache-airflow-providers-plexus | apache-airflow-providers-postgres |                      </text><text class="breeze-build- [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-41)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1020.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-41)">apache-airflow-providers-presto | apache-airflow-providers-qubole |                        </text><text clas [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-42)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1044.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-42)">apache-airflow-providers-redis | apache-airflow-providers-salesforce |                     </text><text class="breeze-build [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-43)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1069.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-43)">apache-airflow-providers-samba | apache-airflow-providers-segment |                        </text><text clas [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1093.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-44)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1093.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-44)">apache-airflow-providers-sendgrid | apache-airflow-providers-sftp |                        </text><text clas [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1118" textLength="12.2" clip-path="url(#breeze-build-docs-line-45)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1118" textLength="1110.2" clip-path="url(#breeze-build-docs-line-45)">apache-airflow-providers-singularity | apache-airflow-providers-slack |                    </text><text class="breeze-build-docs-r5" [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-46)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1142.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-46)">apache-airflow-providers-snowflake | apache-airflow-providers-sqlite |                     </text><text class="breeze-build [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1166.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-47)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1166.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-47)">apache-airflow-providers-ssh | apache-airflow-providers-tableau |                          </text> [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-48)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1191.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-48)">apache-airflow-providers-tabular | apache-airflow-providers-telegram |                     </text><text class="breeze-build [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-49)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1215.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-49)">apache-airflow-providers-trino | apache-airflow-providers-vertica |                        </text><text clas [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-build-docs-line-50)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1240" textLength="1110.2" clip-path="url(#breeze-build-docs-line-50)">apache-airflow-providers-yandex | apache-airflow-providers-zendesk | docker-stack |        </text><text class="breeze-build-docs-r5" x="1451.8" y="1240" textLength="12.2" clip-path=" [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1264.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-51)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1264.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-51)">helm-chart)                                       [...]
+</text><text class="breeze-build-docs-r5" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-16)">│</text><text class="breeze-build-docs-r7" x="329.4" y="410.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-16)">apache-airflow-providers-apache-druid | apache-airflow-providers-apache-flink |            </text><text class="breeze-build-docs-r5" x="1451.8" y="410.4" textLength="12.2 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-17)">│</text><text class="breeze-build-docs-r7" x="329.4" y="434.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-17)">apache-airflow-providers-apache-hdfs | apache-airflow-providers-apache-hive |              </text><text class="breeze-build-docs-r5" x="1451.8" y="434.8" textLe [...]
+</text><text class="breeze-build-docs-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-18)">│</text><text class="breeze-build-docs-r7" x="329.4" y="459.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-18)">apache-airflow-providers-apache-kylin | apache-airflow-providers-apache-livy |             </text><text class="breeze-build-docs-r5" x="1451.8" y="459.2" textLength= [...]
+</text><text class="breeze-build-docs-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-19)">│</text><text class="breeze-build-docs-r7" x="329.4" y="483.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-19)">apache-airflow-providers-apache-pig | apache-airflow-providers-apache-pinot |              </text><text class="breeze-build-docs-r5" x="1451.8" y="483.6" textLe [...]
+</text><text class="breeze-build-docs-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-build-docs-line-20)">│</text><text class="breeze-build-docs-r7" x="329.4" y="508" textLength="1110.2" clip-path="url(#breeze-build-docs-line-20)">apache-airflow-providers-apache-spark | apache-airflow-providers-apache-sqoop |            </text><text class="breeze-build-docs-r5" x="1451.8" y="508" textLength="12.2" clip [...]
+</text><text class="breeze-build-docs-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-21)">│</text><text class="breeze-build-docs-r7" x="329.4" y="532.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-21)">apache-airflow-providers-arangodb | apache-airflow-providers-asana |                       </text><text class="bree [...]
+</text><text class="breeze-build-docs-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-22)">│</text><text class="breeze-build-docs-r7" x="329.4" y="556.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-22)">apache-airflow-providers-atlassian-jira | apache-airflow-providers-celery |                </text><text class="breeze-build-docs-r5" x="1451.8" y="556 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-23)">│</text><text class="breeze-build-docs-r7" x="329.4" y="581.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-23)">apache-airflow-providers-cloudant | apache-airflow-providers-cncf-kubernetes |             </text><text class="breeze-build-docs-r5" x="1451.8" y="581.2" textLength= [...]
+</text><text class="breeze-build-docs-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-24)">│</text><text class="breeze-build-docs-r7" x="329.4" y="605.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-24)">apache-airflow-providers-common-sql | apache-airflow-providers-databricks |                </text><text class="breeze-build-docs-r5" x="1451.8" y="605 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-build-docs-line-25)">│</text><text class="breeze-build-docs-r7" x="329.4" y="630" textLength="1110.2" clip-path="url(#breeze-build-docs-line-25)">apache-airflow-providers-datadog | apache-airflow-providers-dbt-cloud |                    </text><text class="breeze-build-docs-r5" x [...]
+</text><text class="breeze-build-docs-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-26)">│</text><text class="breeze-build-docs-r7" x="329.4" y="654.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-26)">apache-airflow-providers-dingding | apache-airflow-providers-discord |                     </text><text class="breeze-build-d [...]
+</text><text class="breeze-build-docs-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-27)">│</text><text class="breeze-build-docs-r7" x="329.4" y="678.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-27)">apache-airflow-providers-docker | apache-airflow-providers-elasticsearch |                 </text><text class="breeze-build-docs-r5" x="1451.8" y [...]
+</text><text class="breeze-build-docs-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-28)">│</text><text class="breeze-build-docs-r7" x="329.4" y="703.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-28)">apache-airflow-providers-exasol | apache-airflow-providers-facebook |                      </text><text class="breeze-bu [...]
+</text><text class="breeze-build-docs-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-29)">│</text><text class="breeze-build-docs-r7" x="329.4" y="727.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-29)">apache-airflow-providers-ftp | apache-airflow-providers-github |                           </te [...]
+</text><text class="breeze-build-docs-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-build-docs-line-30)">│</text><text class="breeze-build-docs-r7" x="329.4" y="752" textLength="1110.2" clip-path="url(#breeze-build-docs-line-30)">apache-airflow-providers-google | apache-airflow-providers-grpc |                          </text><text [...]
+</text><text class="breeze-build-docs-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-31)">│</text><text class="breeze-build-docs-r7" x="329.4" y="776.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-31)">apache-airflow-providers-hashicorp | apache-airflow-providers-http |                       </text><text class="bree [...]
+</text><text class="breeze-build-docs-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-32)">│</text><text class="breeze-build-docs-r7" x="329.4" y="800.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-32)">apache-airflow-providers-imap | apache-airflow-providers-influxdb |                        </text><text class= [...]
+</text><text class="breeze-build-docs-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-33)">│</text><text class="breeze-build-docs-r7" x="329.4" y="825.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-33)">apache-airflow-providers-jdbc | apache-airflow-providers-jenkins |                         </text><text c [...]
+</text><text class="breeze-build-docs-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-34)">│</text><text class="breeze-build-docs-r7" x="329.4" y="849.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-34)">apache-airflow-providers-microsoft-azure | apache-airflow-providers-microsoft-mssql |      </text><text class="breeze-build-docs-r5" x="1451.8" y="849.6" textLength="12.2" clip-path="url(#breeze-build [...]
+</text><text class="breeze-build-docs-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-build-docs-line-35)">│</text><text class="breeze-build-docs-r7" x="329.4" y="874" textLength="1110.2" clip-path="url(#breeze-build-docs-line-35)">apache-airflow-providers-microsoft-psrp | apache-airflow-providers-microsoft-winrm |       </text><text class="breeze-build-docs-r5" x="1451.8" y="874" textLength="12.2" clip-path="url(#breeze-build- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-36)">│</text><text class="breeze-build-docs-r7" x="329.4" y="898.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-36)">apache-airflow-providers-mongo | apache-airflow-providers-mysql |                          </text><t [...]
+</text><text class="breeze-build-docs-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-37)">│</text><text class="breeze-build-docs-r7" x="329.4" y="922.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-37)">apache-airflow-providers-neo4j | apache-airflow-providers-odbc |                           </te [...]
+</text><text class="breeze-build-docs-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-38)">│</text><text class="breeze-build-docs-r7" x="329.4" y="947.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-38)">apache-airflow-providers-openfaas | apache-airflow-providers-opsgenie |                    </text><text class="breeze-build-docs-r [...]
+</text><text class="breeze-build-docs-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-39)">│</text><text class="breeze-build-docs-r7" x="329.4" y="971.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-39)">apache-airflow-providers-oracle | apache-airflow-providers-pagerduty |                     </text><text class="breeze-build-d [...]
+</text><text class="breeze-build-docs-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-build-docs-line-40)">│</text><text class="breeze-build-docs-r7" x="329.4" y="996" textLength="1110.2" clip-path="url(#breeze-build-docs-line-40)">apache-airflow-providers-papermill | apache-airflow-providers-plexus |                     </text><text class="breeze-build-docs- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-41)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1020.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-41)">apache-airflow-providers-postgres | apache-airflow-providers-presto |                      </text><text class="breeze- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-42)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1044.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-42)">apache-airflow-providers-qubole | apache-airflow-providers-redis |                         </text><text [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-43)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1069.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-43)">apache-airflow-providers-salesforce | apache-airflow-providers-samba |                     </text><text class="breeze-build [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1093.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-44)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1093.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-44)">apache-airflow-providers-segment | apache-airflow-providers-sendgrid |                     </text><text class="breeze-build [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1118" textLength="12.2" clip-path="url(#breeze-build-docs-line-45)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1118" textLength="1110.2" clip-path="url(#breeze-build-docs-line-45)">apache-airflow-providers-sftp | apache-airflow-providers-singularity |                     </text><text class="breeze-build-doc [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-46)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1142.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-46)">apache-airflow-providers-slack | apache-airflow-providers-snowflake |                      </text><text class="breeze- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1166.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-47)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1166.8" textLength="1110.2" clip-path="url(#breeze-build-docs-line-47)">apache-airflow-providers-sqlite | apache-airflow-providers-ssh |                           </ [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-48)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1191.2" textLength="1110.2" clip-path="url(#breeze-build-docs-line-48)">apache-airflow-providers-tableau | apache-airflow-providers-tabular |                      </text><text class="breeze- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-build-docs-line-49)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1215.6" textLength="1110.2" clip-path="url(#breeze-build-docs-line-49)">apache-airflow-providers-telegram | apache-airflow-providers-trino |                       </text><text class="br [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-build-docs-line-50)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1240" textLength="1110.2" clip-path="url(#breeze-build-docs-line-50)">apache-airflow-providers-vertica | apache-airflow-providers-yandex |                       </text><text class="breeze [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1264.4" textLength="12.2" clip-path="url(#breeze-build-docs-line-51)">│</text><text class="breeze-build-docs-r7" x="329.4" y="1264.4" textLength="1110.2" clip-path="url(#breeze-build-docs-line-51)">apache-airflow-providers-zendesk | docker-stack | helm-chart)                            [...]
</text><text class="breeze-build-docs-r5" x="0" y="1288.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-52)">│</text><text class="breeze-build-docs-r4" x="24.4" y="1288.8" textLength="12.2" clip-path="url(#breeze-build-docs-line-52)">-</text><text class="breeze-build-docs-r4" x="36.6" y="1288.8" textLength="85.4" clip-path="url(#breeze-build-docs-line-52)">-github</text><text class="breeze-build-docs-r4" x="122" y="1288.8" textLength="134.2" clip-path="url(#breeze-build-docs- [...]
</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="1464" clip-path="url(#breeze-build-docs-line-53)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-build-docs-r2" x="1464" y="1313.2" textLength="12.2" clip-path="url(#breeze-build-docs-line-53)">
</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="24.4" clip-path="url(#breeze-build-docs-line-54)">╭─</text><text class="breeze-build-docs-r5" x="24.4" y="1337.6" textLength="195.2" clip-path="url(#breeze-build-docs-line-54)"> Common options </text><text class="breeze-build-docs-r5" x="219.6" y="1337.6" textLength="1220" clip-path="url(#breeze-build-docs-line-54)">──────────────────────────────────────────────────────────────────────────────────────── [...]
diff --git a/images/breeze/output_release-management.svg b/images/breeze/output_release-management.svg
index 5be8c4f4fa..22e76c65b0 100644
--- a/images/breeze/output_release-management.svg
+++ b/images/breeze/output_release-management.svg
@@ -35,8 +35,8 @@
.breeze-release-management-r1 { fill: #c5c8c6;font-weight: bold }
.breeze-release-management-r2 { fill: #c5c8c6 }
.breeze-release-management-r3 { fill: #d0b344;font-weight: bold }
-.breeze-release-management-r4 { fill: #868887 }
-.breeze-release-management-r5 { fill: #68a0b3;font-weight: bold }
+.breeze-release-management-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-release-management-r5 { fill: #868887 }
.breeze-release-management-r6 { fill: #98a84b;font-weight: bold }
</style>
@@ -105,22 +105,22 @@
<g class="breeze-release-management-matrix">
<text class="breeze-release-management-r2" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-release-management-line-0)">
-</text><text class="breeze-release-management-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-line-1)">Usage: </text><text class="breeze-release-management-r1" x="97.6" y="44.4" textLength="646.6" clip-path="url(#breeze-release-management-line-1)">breeze release-management [OPTIONS] COMMAND [ARGS]...</text><text class="breeze-release-management-r2" x="1464" y="44.4" textLength="12.2" clip-path="url(#breeze-release-management-line-1)">
+</text><text class="breeze-release-management-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-line-1)">Usage: </text><text class="breeze-release-management-r1" x="97.6" y="44.4" textLength="329.4" clip-path="url(#breeze-release-management-line-1)">breeze release-management [</text><text class="breeze-release-management-r4" x="427" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-line-1)">OPTIONS</text><text class="breez [...]
</text><text class="breeze-release-management-r2" x="1464" y="68.8" textLength="12.2" clip-path="url(#breeze-release-management-line-2)">
</text><text class="breeze-release-management-r2" x="12.2" y="93.2" textLength="902.8" clip-path="url(#breeze-release-management-line-3)">Tools that release managers can use to prepare and manage Airflow releases</text><text class="breeze-release-management-r2" x="1464" y="93.2" textLength="12.2" clip-path="url(#breeze-release-management-line-3)">
</text><text class="breeze-release-management-r2" x="1464" y="117.6" textLength="12.2" clip-path="url(#breeze-release-management-line-4)">
-</text><text class="breeze-release-management-r4" x="0" y="142" textLength="24.4" clip-path="url(#breeze-release-management-line-5)">╭─</text><text class="breeze-release-management-r4" x="24.4" y="142" textLength="195.2" clip-path="url(#breeze-release-management-line-5)"> Common options </text><text class="breeze-release-management-r4" x="219.6" y="142" textLength="1220" clip-path="url(#breeze-release-management-line-5)">──────────────────────────────────────────────────── [...]
-</text><text class="breeze-release-management-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-line-6)">│</text><text class="breeze-release-management-r5" x="24.4" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-line-6)">-</text><text class="breeze-release-management-r5" x="36.6" y="166.4" textLength="61" clip-path="url(#breeze-release-management-line-6)">-help</text><text class="breeze-release-management-r6" x="122" y="166.4" textLeng [...]
-</text><text class="breeze-release-management-r4" x="0" y="190.8" textLength="1464" clip-path="url(#breeze-release-management-line-7)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r2" x="1464" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-line-7)">
-</text><text class="breeze-release-management-r4" x="0" y="215.2" textLength="24.4" clip-path="url(#breeze-release-management-line-8)">╭─</text><text class="breeze-release-management-r4" x="24.4" y="215.2" textLength="122" clip-path="url(#breeze-release-management-line-8)"> Commands </text><text class="breeze-release-management-r4" x="146.4" y="215.2" textLength="1293.2" clip-path="url(#breeze-release-management-line-8)">───────────────────────────────────────────────────────── [...]
-</text><text class="breeze-release-management-r4" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-line-9)">│</text><text class="breeze-release-management-r5" x="24.4" y="239.6" textLength="402.6" clip-path="url(#breeze-release-management-line-9)">generate-constraints             </text><text class="breeze-release-management-r2" x="451.4" y="239.6" textLength="988.2" clip-path="url(#breeze-release [...]
-</text><text class="breeze-release-management-r4" x="0" y="264" textLength="12.2" clip-path="url(#breeze-release-management-line-10)">│</text><text class="breeze-release-management-r5" x="24.4" y="264" textLength="402.6" clip-path="url(#breeze-release-management-line-10)">generate-issue-content           </text><text class="breeze-release-management-r2" x="451.4" y="264" textLength="988.2" clip-path="url(#breeze-release-management-li [...]
-</text><text class="breeze-release-management-r4" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-release-management-line-11)">│</text><text class="breeze-release-management-r5" x="24.4" y="288.4" textLength="402.6" clip-path="url(#breeze-release-management-line-11)">prepare-airflow-package          </text><text class="breeze-release-management-r2" x="451.4" y="288.4" textLength="988.2" clip-path="url(#breeze-release-management-l [...]
-</text><text class="breeze-release-management-r4" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-line-12)">│</text><text class="breeze-release-management-r5" x="24.4" y="312.8" textLength="402.6" clip-path="url(#breeze-release-management-line-12)">prepare-provider-documentation   </text><text class="breeze-release-management-r2" x="451.4" y="312.8" textLength="988.2" clip-path="url(#breeze-release-management-line-12)">Prepare CHANGELOG, [...]
-</text><text class="breeze-release-management-r4" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-line-13)">│</text><text class="breeze-release-management-r5" x="24.4" y="337.2" textLength="402.6" clip-path="url(#breeze-release-management-line-13)">prepare-provider-packages        </text><text class="breeze-release-management-r2" x="451.4" y="337.2" textLength="988.2" clip-path="url(#breeze-release-management-line-13)">P [...]
-</text><text class="breeze-release-management-r4" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-line-14)">│</text><text class="breeze-release-management-r5" x="24.4" y="361.6" textLength="402.6" clip-path="url(#breeze-release-management-line-14)">release-prod-images              </text><text class="breeze-release-management-r2" x="451.4" y="361.6" textLength="988.2" clip-path="url(#breeze- [...]
-</text><text class="breeze-release-management-r4" x="0" y="386" textLength="12.2" clip-path="url(#breeze-release-management-line-15)">│</text><text class="breeze-release-management-r5" x="24.4" y="386" textLength="402.6" clip-path="url(#breeze-release-management-line-15)">verify-provider-packages         </text><text class="breeze-release-management-r2" x="451.4" y="386" textLength="988.2" clip-path="url(#breeze-release-management-line-15)">Ve [...]
-</text><text class="breeze-release-management-r4" x="0" y="410.4" textLength="1464" clip-path="url(#breeze-release-management-line-16)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r2" x="1464" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-line-16)">
+</text><text class="breeze-release-management-r5" x="0" y="142" textLength="24.4" clip-path="url(#breeze-release-management-line-5)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="142" textLength="195.2" clip-path="url(#breeze-release-management-line-5)"> Common options </text><text class="breeze-release-management-r5" x="219.6" y="142" textLength="1220" clip-path="url(#breeze-release-management-line-5)">──────────────────────────────────────────────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-line-6)">│</text><text class="breeze-release-management-r4" x="24.4" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-line-6)">-</text><text class="breeze-release-management-r4" x="36.6" y="166.4" textLength="61" clip-path="url(#breeze-release-management-line-6)">-help</text><text class="breeze-release-management-r6" x="122" y="166.4" textLeng [...]
+</text><text class="breeze-release-management-r5" x="0" y="190.8" textLength="1464" clip-path="url(#breeze-release-management-line-7)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r2" x="1464" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-line-7)">
+</text><text class="breeze-release-management-r5" x="0" y="215.2" textLength="24.4" clip-path="url(#breeze-release-management-line-8)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="215.2" textLength="122" clip-path="url(#breeze-release-management-line-8)"> Commands </text><text class="breeze-release-management-r5" x="146.4" y="215.2" textLength="1293.2" clip-path="url(#breeze-release-management-line-8)">───────────────────────────────────────────────────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-line-9)">│</text><text class="breeze-release-management-r4" x="24.4" y="239.6" textLength="402.6" clip-path="url(#breeze-release-management-line-9)">generate-constraints             </text><text class="breeze-release-management-r2" x="451.4" y="239.6" textLength="988.2" clip-path="url(#breeze-release [...]
+</text><text class="breeze-release-management-r5" x="0" y="264" textLength="12.2" clip-path="url(#breeze-release-management-line-10)">│</text><text class="breeze-release-management-r4" x="24.4" y="264" textLength="402.6" clip-path="url(#breeze-release-management-line-10)">generate-issue-content           </text><text class="breeze-release-management-r2" x="451.4" y="264" textLength="988.2" clip-path="url(#breeze-release-management-li [...]
+</text><text class="breeze-release-management-r5" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-release-management-line-11)">│</text><text class="breeze-release-management-r4" x="24.4" y="288.4" textLength="402.6" clip-path="url(#breeze-release-management-line-11)">prepare-airflow-package          </text><text class="breeze-release-management-r2" x="451.4" y="288.4" textLength="988.2" clip-path="url(#breeze-release-management-l [...]
+</text><text class="breeze-release-management-r5" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-line-12)">│</text><text class="breeze-release-management-r4" x="24.4" y="312.8" textLength="402.6" clip-path="url(#breeze-release-management-line-12)">prepare-provider-documentation   </text><text class="breeze-release-management-r2" x="451.4" y="312.8" textLength="97.6" clip-path="url(#breeze-release-management-line-12)">Prepare </text><text c [...]
+</text><text class="breeze-release-management-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-line-13)">│</text><text class="breeze-release-management-r4" x="24.4" y="337.2" textLength="402.6" clip-path="url(#breeze-release-management-line-13)">prepare-provider-packages        </text><text class="breeze-release-management-r2" x="451.4" y="337.2" textLength="988.2" clip-path="url(#breeze-release-management-line-13)">P [...]
+</text><text class="breeze-release-management-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-line-14)">│</text><text class="breeze-release-management-r4" x="24.4" y="361.6" textLength="402.6" clip-path="url(#breeze-release-management-line-14)">release-prod-images              </text><text class="breeze-release-management-r2" x="451.4" y="361.6" textLength="988.2" clip-path="url(#breeze- [...]
+</text><text class="breeze-release-management-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-release-management-line-15)">│</text><text class="breeze-release-management-r4" x="24.4" y="386" textLength="402.6" clip-path="url(#breeze-release-management-line-15)">verify-provider-packages         </text><text class="breeze-release-management-r2" x="451.4" y="386" textLength="988.2" clip-path="url(#breeze-release-management-line-15)">Ve [...]
+</text><text class="breeze-release-management-r5" x="0" y="410.4" textLength="1464" clip-path="url(#breeze-release-management-line-16)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r2" x="1464" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-line-16)">
</text>
</g>
</g>
diff --git a/images/breeze/output_release-management_generate-issue-content.svg b/images/breeze/output_release-management_generate-issue-content.svg
index 4dfa2f3649..d71282dbe9 100644
--- a/images/breeze/output_release-management_generate-issue-content.svg
+++ b/images/breeze/output_release-management_generate-issue-content.svg
@@ -35,8 +35,8 @@
.breeze-release-management-generate-issue-content-r1 { fill: #c5c8c6;font-weight: bold }
.breeze-release-management-generate-issue-content-r2 { fill: #c5c8c6 }
.breeze-release-management-generate-issue-content-r3 { fill: #d0b344;font-weight: bold }
-.breeze-release-management-generate-issue-content-r4 { fill: #868887 }
-.breeze-release-management-generate-issue-content-r5 { fill: #68a0b3;font-weight: bold }
+.breeze-release-management-generate-issue-content-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-release-management-generate-issue-content-r5 { fill: #868887 }
.breeze-release-management-generate-issue-content-r6 { fill: #8d7b39 }
.breeze-release-management-generate-issue-content-r7 { fill: #98a84b;font-weight: bold }
</style>
@@ -142,34 +142,34 @@
<g class="breeze-release-management-generate-issue-content-matrix">
<text class="breeze-release-management-generate-issue-content-r2" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-0)">
-</text><text class="breeze-release-management-generate-issue-content-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-generate-issue-content-line-1)">Usage: </text><text class="breeze-release-management-generate-issue-content-r1" x="97.6" y="44.4" textLength="1244.4" clip-path="url(#breeze-release-management-generate-issue-content-line-1)">breeze release-management generate-issue-content [OPTIONS] [airbyte | alibaba  [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="68.8" textLength="1439.6" clip-path="url(#breeze-release-management-generate-issue-content-line-2)">                                                   & [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="93.2" textLength="1354.2" clip-path="url(#breeze-release-management-generate-issue-content-line-3)">                                                   & [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="117.6" textLength="1427.4" clip-path="url(#breeze-release-management-generate-issue-content-line-4)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="142" textLength="1366.4" clip-path="url(#breeze-release-management-generate-issue-content-line-5)">                                                   &# [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="166.4" textLength="1390.8" clip-path="url(#breeze-release-management-generate-issue-content-line-6)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="190.8" textLength="1415.2" clip-path="url(#breeze-release-management-generate-issue-content-line-7)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="215.2" textLength="1427.4" clip-path="url(#breeze-release-management-generate-issue-content-line-8)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="239.6" textLength="1317.6" clip-path="url(#breeze-release-management-generate-issue-content-line-9)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="264" textLength="1390.8" clip-path="url(#breeze-release-management-generate-issue-content-line-10)">                                                   & [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="288.4" textLength="1427.4" clip-path="url(#breeze-release-management-generate-issue-content-line-11)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="312.8" textLength="1390.8" clip-path="url(#breeze-release-management-generate-issue-content-line-12)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="337.2" textLength="1378.6" clip-path="url(#breeze-release-management-generate-issue-content-line-13)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="361.6" textLength="1378.6" clip-path="url(#breeze-release-management-generate-issue-content-line-14)">                                                    [...]
-</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="386" textLength="1146.8" clip-path="url(#breeze-release-management-generate-issue-content-line-15)">                                                   & [...]
+</text><text class="breeze-release-management-generate-issue-content-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-generate-issue-content-line-1)">Usage: </text><text class="breeze-release-management-generate-issue-content-r1" x="97.6" y="44.4" textLength="610" clip-path="url(#breeze-release-management-generate-issue-content-line-1)">breeze release-management generate-issue-content [</text><text class="breeze-release-management-gene [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="68.8" textLength="1427.4" clip-path="url(#breeze-release-management-generate-issue-content-line-2)">                                                   & [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="93.2" textLength="1390.8" clip-path="url(#breeze-release-management-generate-issue-content-line-3)">                                                   & [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="117.6" textLength="1378.6" clip-path="url(#breeze-release-management-generate-issue-content-line-4)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="142" textLength="1354.2" clip-path="url(#breeze-release-management-generate-issue-content-line-5)">                                                   &# [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="166.4" textLength="1329.8" clip-path="url(#breeze-release-management-generate-issue-content-line-6)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="190.8" textLength="1378.6" clip-path="url(#breeze-release-management-generate-issue-content-line-7)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="215.2" textLength="1439.6" clip-path="url(#breeze-release-management-generate-issue-content-line-8)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="239.6" textLength="1403" clip-path="url(#breeze-release-management-generate-issue-content-line-9)">                                                   &# [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="264" textLength="1415.2" clip-path="url(#breeze-release-management-generate-issue-content-line-10)">                                                   & [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="288.4" textLength="1329.8" clip-path="url(#breeze-release-management-generate-issue-content-line-11)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="312.8" textLength="1427.4" clip-path="url(#breeze-release-management-generate-issue-content-line-12)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="337.2" textLength="1366.4" clip-path="url(#breeze-release-management-generate-issue-content-line-13)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="361.6" textLength="1390.8" clip-path="url(#breeze-release-management-generate-issue-content-line-14)">                                                    [...]
+</text><text class="breeze-release-management-generate-issue-content-r1" x="12.2" y="386" textLength="1403" clip-path="url(#breeze-release-management-generate-issue-content-line-15)">                                                    [...]
</text><text class="breeze-release-management-generate-issue-content-r2" x="1464" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-16)">
</text><text class="breeze-release-management-generate-issue-content-r2" x="12.2" y="434.8" textLength="585.6" clip-path="url(#breeze-release-management-generate-issue-content-line-17)">Generates content for issue to test the release.</text><text class="breeze-release-management-generate-issue-content-r2" x="1464" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-17)">
</text><text class="breeze-release-management-generate-issue-content-r2" x="1464" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-18)">
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="483.6" textLength="24.4" clip-path="url(#breeze-release-management-generate-issue-content-line-19)">╭─</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="483.6" textLength="195.2" clip-path="url(#breeze-release-management-generate-issue-content-line-19)"> Common options </text><text class="breeze-release-management-generate-issue-content-r4" x="219.6" y="483.6 [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-20)">│</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-20)">-</text><text class="breeze-release-management-generate-issue-content-r5" x="36.6" y="508" textLength="85.4" clip-path="url(#bre [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-21)">│</text><text class="breeze-release-management-generate-issue-content-r2" x="390.4" y="532.4" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-21)">variable set. Can be generated with:           [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-22)">│</text><text class="breeze-release-management-generate-issue-content-r2" x="390.4" y="556.8" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-22)">https://github.com/settings/tokens/new?description=Read%20sssues&scopes=repo:status   </text><text cla [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-23)">│</text><text class="breeze-release-management-generate-issue-content-r6" x="390.4" y="581.2" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-23)">(TEXT)                   & [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-24)">│</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-24)">-</text><text class="breeze-release-management-generate-issue-content-r5" x="36.6" y="605.6" textLength="85.4" clip-path="ur [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-25)">│</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="630" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-25)">-</text><text class="breeze-release-management-generate-issue-content-r5" x="36.6" y="630" textLength="61" clip-path="url(#breez [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-26)">│</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-26)">-</text><text class="breeze-release-management-generate-issue-content-r5" x="36.6" y="654.4" textLength="109.8" clip-path="u [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-27)">│</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-27)">-</text><text class="breeze-release-management-generate-issue-content-r5" x="36.6" y="678.8" textLength="61" clip-path="url( [...]
-</text><text class="breeze-release-management-generate-issue-content-r4" x="0" y="703.2" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-line-28)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-r2" x="1464" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-28)">
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="483.6" textLength="24.4" clip-path="url(#breeze-release-management-generate-issue-content-line-19)">╭─</text><text class="breeze-release-management-generate-issue-content-r5" x="24.4" y="483.6" textLength="195.2" clip-path="url(#breeze-release-management-generate-issue-content-line-19)"> Common options </text><text class="breeze-release-management-generate-issue-content-r5" x="219.6" y="483.6 [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-20)">│</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-20)">-</text><text class="breeze-release-management-generate-issue-content-r4" x="36.6" y="508" textLength="85.4" clip-path="url(#bre [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-21)">│</text><text class="breeze-release-management-generate-issue-content-r2" x="390.4" y="532.4" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-21)">variable set. Can be generated with:           [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-22)">│</text><text class="breeze-release-management-generate-issue-content-r2" x="390.4" y="556.8" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-22)">https://github.com/settings/tokens/new?description=Read%20sssues&scopes=repo:status   </text><text cla [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-23)">│</text><text class="breeze-release-management-generate-issue-content-r6" x="390.4" y="581.2" textLength="1049.2" clip-path="url(#breeze-release-management-generate-issue-content-line-23)">(TEXT)                   & [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-24)">│</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-24)">-</text><text class="breeze-release-management-generate-issue-content-r4" x="36.6" y="605.6" textLength="85.4" clip-path="ur [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-25)">│</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="630" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-25)">-</text><text class="breeze-release-management-generate-issue-content-r4" x="36.6" y="630" textLength="61" clip-path="url(#breez [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-26)">│</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-26)">-</text><text class="breeze-release-management-generate-issue-content-r4" x="36.6" y="654.4" textLength="109.8" clip-path="u [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-27)">│</text><text class="breeze-release-management-generate-issue-content-r4" x="24.4" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-27)">-</text><text class="breeze-release-management-generate-issue-content-r4" x="36.6" y="678.8" textLength="61" clip-path="url( [...]
+</text><text class="breeze-release-management-generate-issue-content-r5" x="0" y="703.2" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-line-28)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-r2" x="1464" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-line-28)">
</text>
</g>
</g>
diff --git a/images/breeze/output_release-management_prepare-provider-documentation.svg b/images/breeze/output_release-management_prepare-provider-documentation.svg
index 86dbeba6f7..3523409f38 100644
--- a/images/breeze/output_release-management_prepare-provider-documentation.svg
+++ b/images/breeze/output_release-management_prepare-provider-documentation.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 830.8" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 855.1999999999999" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-release-management-prepare-provider-documentation-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="779.8" />
+ <rect x="0" y="0" width="1463.0" height="804.1999999999999" />
</clipPath>
<clipPath id="breeze-release-management-prepare-provider-documentation-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -138,9 +138,12 @@
<clipPath id="breeze-release-management-prepare-provider-documentation-line-30">
<rect x="0" y="733.5" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-31">
+ <rect x="0" y="757.9" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="828.8" rx="8"/><text class="breeze-release-management-prepare-provider-documentation-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command: release-management prepare-provider-documentation</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="853.2" rx="8"/><text class="breeze-release-management-prepare-provider-documentation-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command: release-management prepare-provider-documentation</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -153,35 +156,36 @@
<text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-0)">
</text><text class="breeze-release-management-prepare-provider-documentation-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-1)">Usage: </text><text class="breeze-release-management-prepare-provider-documentation-r1" x="97.6" y="44.4" textLength="707.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-1)">breeze release-management prepare-provider-documentation [</text>< [...]
</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="68.8" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-2)">                                                 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="93.2" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-3)">                                                 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="117.6" textLength="1317.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-4)">                                                &# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="142" textLength="1390.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-5)">                                                 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="166.4" textLength="1390.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-6)">                                                &# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="190.8" textLength="1427.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-7)">                                                &# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="215.2" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-8)">                                                &# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="239.6" textLength="1390.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-9)">                                                &# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="264" textLength="1329.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-10)">                                                 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="288.4" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-11)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="312.8" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-12)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="337.2" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-13)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="361.6" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-14)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="386" textLength="1427.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-15)">                                                 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="410.4" textLength="1427.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="434.8" textLength="1146.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">                                                & [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">
-</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="12.2" y="483.6" textLength="97.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">Prepare </text><text class="breeze-release-management-prepare-provider-documentation-r4" x="109.8" y="483.6" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">CHANGELOG</text><text class="breeze-release-management-prepare-provider-doc [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="508" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="532.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="532.4" textLength="512.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)"> Provider documentation preparation flags </text><text class="bre [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="605.6" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provid [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="630" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="630" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)"> Common options </text><text class="breeze-release-management-prepare-provider- [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y="75 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="776.4" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provid [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="93.2" textLength="1293.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-3)">                                                 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="117.6" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-4)">                                                &# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="142" textLength="1390.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-5)">                                                 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="166.4" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-6)">                                                &# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="190.8" textLength="1354.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-7)">                                                &# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="215.2" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-8)">                                                &# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="239.6" textLength="1427.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-9)">                                                &# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="264" textLength="1281" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-10)">                                                  [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="288.4" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-11)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="312.8" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-12)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="337.2" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-13)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="361.6" textLength="1329.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-14)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="386" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-15)">                                                 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="410.4" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="434.8" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="459.2" textLength="1024.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">                                                & [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">
+</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="12.2" y="508" textLength="97.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">Prepare </text><text class="breeze-release-management-prepare-provider-documentation-r4" x="109.8" y="508" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">CHANGELOG</text><text class="breeze-release-management-prepare-provider-documen [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="556.8" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="556.8" textLength="512.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)"> Provider documentation preparation flags </text><text class="bre [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="630" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="630" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-d [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="654.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="654.4" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)"> Common options </text><text class="breeze-release-management-prepare-provi [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y="75 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">-</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="36.6" y [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="800.8" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r2" x="1464" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provid [...]
</text>
</g>
</g>
diff --git a/images/breeze/output_release-management_prepare-provider-packages.svg b/images/breeze/output_release-management_prepare-provider-packages.svg
index f09d7f0c2a..e8f3061ee1 100644
--- a/images/breeze/output_release-management_prepare-provider-packages.svg
+++ b/images/breeze/output_release-management_prepare-provider-packages.svg
@@ -153,14 +153,14 @@
<text class="breeze-release-management-prepare-provider-packages-r2" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-0)">
</text><text class="breeze-release-management-prepare-provider-packages-r3" x="12.2" y="44.4" textLength="85.4" clip-path="url(#breeze-release-management-prepare-provider-packages-line-1)">Usage: </text><text class="breeze-release-management-prepare-provider-packages-r1" x="97.6" y="44.4" textLength="646.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-1)">breeze release-management prepare-provider-packages [</text><text class="breeze-releas [...]
</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="68.8" textLength="1305.4" clip-path="url(#breeze-release-management-prepare-provider-packages-line-2)">                                                  & [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="93.2" textLength="1403" clip-path="url(#breeze-release-management-prepare-provider-packages-line-3)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="117.6" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-4)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="142" textLength="1390.8" clip-path="url(#breeze-release-management-prepare-provider-packages-line-5)">                                                  &# [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="166.4" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-packages-line-6)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="190.8" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-7)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="215.2" textLength="1329.8" clip-path="url(#breeze-release-management-prepare-provider-packages-line-8)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="239.6" textLength="1366.4" clip-path="url(#breeze-release-management-prepare-provider-packages-line-9)">                                                   [...]
-</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="264" textLength="1354.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-10)">                                                  & [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="93.2" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-3)">                                                  & [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="117.6" textLength="1403" clip-path="url(#breeze-release-management-prepare-provider-packages-line-4)">                                                  &# [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="142" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-5)">                                                  &# [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="166.4" textLength="1378.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-6)">                                                   [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="190.8" textLength="1342" clip-path="url(#breeze-release-management-prepare-provider-packages-line-7)">                                                  &# [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="215.2" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-8)">                                                   [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="239.6" textLength="1427.4" clip-path="url(#breeze-release-management-prepare-provider-packages-line-9)">                                                   [...]
+</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="264" textLength="1378.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-10)">                                                  & [...]
</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="288.4" textLength="1439.6" clip-path="url(#breeze-release-management-prepare-provider-packages-line-11)">                                                   [...]
</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="312.8" textLength="1354.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-12)">                                                   [...]
</text><text class="breeze-release-management-prepare-provider-packages-r1" x="12.2" y="337.2" textLength="1415.2" clip-path="url(#breeze-release-management-prepare-provider-packages-line-13)">                                                   [...]
diff --git a/tests/providers/apache/flink/__init__.py b/tests/providers/apache/flink/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/tests/providers/apache/flink/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/tests/providers/apache/flink/operators/__init__.py b/tests/providers/apache/flink/operators/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/tests/providers/apache/flink/operators/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/tests/providers/apache/flink/operators/test_flink_kubernetes.py b/tests/providers/apache/flink/operators/test_flink_kubernetes.py
new file mode 100644
index 0000000000..f660eabf98
--- /dev/null
+++ b/tests/providers/apache/flink/operators/test_flink_kubernetes.py
@@ -0,0 +1,345 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from __future__ import annotations
+
+import json
+import unittest
+from unittest.mock import patch
+
+from airflow import DAG
+from airflow.models import Connection
+from airflow.providers.apache.flink.operators.flink_kubernetes import FlinkKubernetesOperator
+from airflow.utils import db, timezone
+
+TEST_VALID_APPLICATION_YAML = """
+apiVersion: flink.apache.org/v1beta1
+kind: FlinkDeployment
+metadata:
+ name: flink-sm-ex
+ namespace: default
+spec:
+ image: flink:1.15
+ flinkVersion: v1_15
+ flinkConfiguration:
+ taskmanager.numberOfTaskSlots: "2"
+ state.savepoints.dir: file:///flink-data/savepoints
+ state.checkpoints.dir: file:///flink-data/checkpoints
+ high-availability: org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory
+ high-availability.storageDir: file:///flink-data/ha
+ ingress:
+ template: "{{name}}.{{namespace}}.flink.k8s.io"
+ serviceAccount: flink
+ jobManager:
+ resource:
+ memory: "2048m"
+ cpu: 1
+ taskManager:
+ resource:
+ memory: "2048m"
+ cpu: 1
+ podTemplate:
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ name: task-manager-pod-template
+ spec:
+ initContainers:
+ # Sample sidecar container
+ - name: busybox
+ image: busybox:latest
+ command: [ 'sh','-c','echo hello from task manager' ]
+ job:
+ jarURI: local:///opt/flink/examples/streaming/StateMachineExample.jar
+ parallelism: 2
+ upgradeMode: stateless
+ state: running
+ savepointTriggerNonce: 0
+"""
+
+TEST_VALID_APPLICATION_JSON = """
+{
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "name": "flink-sm-ex",
+ "namespace": "default"
+ },
+ "spec": {
+ "image": "flink:1.15",
+ "flinkVersion": "v1_15",
+ "flinkConfiguration": {
+ "taskmanager.numberOfTaskSlots": "2",
+ "state.savepoints.dir": "file:///flink-data/savepoints",
+ "state.checkpoints.dir": "file:///flink-data/checkpoints",
+ "high-availability": "org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory",
+ "high-availability.storageDir": "file:///flink-data/ha"
+ },
+ "ingress": {
+ "template": "{{name}}.{{namespace}}.flink.k8s.io"
+ },
+ "serviceAccount": "flink",
+ "jobManager": {
+ "resource": {
+ "memory": "2048m",
+ "cpu": 1
+ }
+ },
+ "taskManager": {
+ "resource": {
+ "memory": "2048m",
+ "cpu": 1
+ },
+ "podTemplate": {
+ "apiVersion": "v1",
+ "kind": "Pod",
+ "metadata": {
+ "name": "task-manager-pod-template"
+ },
+ "spec": {
+ "initContainers": [
+ {
+ "name": "busybox",
+ "image": "busybox:latest",
+ "command": [
+ "sh",
+ "-c",
+ "echo hello from task manager"
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "job": {
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "upgradeMode": "stateless",
+ "state": "running",
+ "savepointTriggerNonce": 0
+ }
+ }
+}
+"""
+TEST_APPLICATION_DICT = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {"name": "flink-sm-ex", "namespace": "default"},
+ "spec": {
+ "image": "flink:1.15",
+ "flinkVersion": "v1_15",
+ "flinkConfiguration": {
+ "taskmanager.numberOfTaskSlots": "2",
+ "state.savepoints.dir": "file:///flink-data/savepoints",
+ "state.checkpoints.dir": "file:///flink-data/checkpoints",
+ "high-availability": "org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory",
+ "high-availability.storageDir": "file:///flink-data/ha",
+ },
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "serviceAccount": "flink",
+ "jobManager": {"resource": {"memory": "2048m", "cpu": 1}},
+ "taskManager": {
+ "resource": {"memory": "2048m", "cpu": 1},
+ "podTemplate": {
+ "apiVersion": "v1",
+ "kind": "Pod",
+ "metadata": {"name": "task-manager-pod-template"},
+ "spec": {
+ "initContainers": [
+ {
+ "name": "busybox",
+ "image": "busybox:latest",
+ "command": ["sh", "-c", "echo hello from task manager"],
+ }
+ ]
+ },
+ },
+ },
+ "job": {
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "upgradeMode": "stateless",
+ "state": "running",
+ "savepointTriggerNonce": 0,
+ },
+ },
+}
+
+
+@patch("airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_conn")
+class TestFlinkKubernetesOperator(unittest.TestCase):
+ def setUp(self):
+ db.merge_conn(
+ Connection(conn_id="kubernetes_default_kube_config", conn_type="kubernetes", extra=json.dumps({}))
+ )
+ db.merge_conn(
+ Connection(
+ conn_id="kubernetes_with_namespace",
+ conn_type="kubernetes",
+ extra=json.dumps({"extra__kubernetes__namespace": "mock_namespace"}),
+ )
+ )
+ args = {"owner": "airflow", "start_date": timezone.datetime(2020, 2, 1)}
+ self.dag = DAG("test_dag_id", default_args=args)
+
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.delete_namespaced_custom_object")
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.create_namespaced_custom_object")
+ def test_create_application_from_yaml(
+ self, mock_create_namespaced_crd, mock_delete_namespaced_crd, mock_kubernetes_hook
+ ):
+ op = FlinkKubernetesOperator(
+ application_file=TEST_VALID_APPLICATION_YAML,
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_default_kube_config",
+ task_id="test_task_id",
+ )
+ op.execute(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_delete_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ name=TEST_APPLICATION_DICT["metadata"]["name"],
+ )
+ mock_create_namespaced_crd.assert_called_with(
+ body=TEST_APPLICATION_DICT,
+ group="flink.apache.org",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.delete_namespaced_custom_object")
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.create_namespaced_custom_object")
+ def test_create_application_from_json(
+ self, mock_create_namespaced_crd, mock_delete_namespaced_crd, mock_kubernetes_hook
+ ):
+ op = FlinkKubernetesOperator(
+ application_file=TEST_VALID_APPLICATION_JSON,
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_default_kube_config",
+ task_id="test_task_id",
+ )
+ op.execute(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_delete_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ name=TEST_APPLICATION_DICT["metadata"]["name"],
+ )
+ mock_create_namespaced_crd.assert_called_with(
+ body=TEST_APPLICATION_DICT,
+ group="flink.apache.org",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.delete_namespaced_custom_object")
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.create_namespaced_custom_object")
+ def test_create_application_from_json_with_api_group_and_version(
+ self, mock_create_namespaced_crd, mock_delete_namespaced_crd, mock_kubernetes_hook
+ ):
+ api_group = "flink.apache.org"
+ api_version = "v1beta1"
+ op = FlinkKubernetesOperator(
+ application_file=TEST_VALID_APPLICATION_JSON,
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_default_kube_config",
+ task_id="test_task_id",
+ api_group=api_group,
+ api_version=api_version,
+ )
+ op.execute(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_delete_namespaced_crd.assert_called_once_with(
+ group=api_group,
+ namespace="default",
+ plural="flinkdeployments",
+ version=api_version,
+ name=TEST_APPLICATION_DICT["metadata"]["name"],
+ )
+ mock_create_namespaced_crd.assert_called_with(
+ body=TEST_APPLICATION_DICT,
+ group=api_group,
+ namespace="default",
+ plural="flinkdeployments",
+ version=api_version,
+ )
+
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.delete_namespaced_custom_object")
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.create_namespaced_custom_object")
+ def test_namespace_from_operator(
+ self, mock_create_namespaced_crd, mock_delete_namespaced_crd, mock_kubernetes_hook
+ ):
+ op = FlinkKubernetesOperator(
+ application_file=TEST_VALID_APPLICATION_JSON,
+ dag=self.dag,
+ namespace="operator_namespace",
+ kubernetes_conn_id="kubernetes_with_namespace",
+ task_id="test_task_id",
+ )
+ op.execute(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_delete_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ namespace="operator_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ name=TEST_APPLICATION_DICT["metadata"]["name"],
+ )
+ mock_create_namespaced_crd.assert_called_with(
+ body=TEST_APPLICATION_DICT,
+ group="flink.apache.org",
+ namespace="operator_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.delete_namespaced_custom_object")
+ @patch("kubernetes.client.api.custom_objects_api.CustomObjectsApi.create_namespaced_custom_object")
+ def test_namespace_from_connection(
+ self, mock_create_namespaced_crd, mock_delete_namespaced_crd, mock_kubernetes_hook
+ ):
+ op = FlinkKubernetesOperator(
+ application_file=TEST_VALID_APPLICATION_JSON,
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_with_namespace",
+ task_id="test_task_id",
+ )
+ op.execute(None)
+
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_delete_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ namespace="mock_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ name=TEST_APPLICATION_DICT["metadata"]["name"],
+ )
+ mock_create_namespaced_crd.assert_called_with(
+ body=TEST_APPLICATION_DICT,
+ group="flink.apache.org",
+ namespace="mock_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
diff --git a/tests/providers/apache/flink/sensors/__init__.py b/tests/providers/apache/flink/sensors/__init__.py
new file mode 100644
index 0000000000..217e5db960
--- /dev/null
+++ b/tests/providers/apache/flink/sensors/__init__.py
@@ -0,0 +1,17 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/tests/providers/apache/flink/sensors/test_flink_kubernetes.py b/tests/providers/apache/flink/sensors/test_flink_kubernetes.py
new file mode 100644
index 0000000000..9978a7de6e
--- /dev/null
+++ b/tests/providers/apache/flink/sensors/test_flink_kubernetes.py
@@ -0,0 +1,1193 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from __future__ import annotations
+
+import json
+import unittest
+from unittest.mock import patch
+
+import pytest
+from kubernetes.client import V1ObjectMeta, V1Pod, V1PodList
+from kubernetes.client.rest import ApiException
+
+from airflow import DAG
+from airflow.exceptions import AirflowException
+from airflow.models import Connection
+from airflow.providers.apache.flink.sensors.flink_kubernetes import FlinkKubernetesSensor
+from airflow.utils import db, timezone
+
+TEST_NO_STATE_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T16:47:16Z",
+ "generation": 1,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:logConfiguration": {
+ ".": {},
+ "f:log4j-console.properties": {},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ }
+ ],
+ "name": "flink-stream-example",
+ "namespace": "default",
+ "resourceVersion": "140016",
+ "uid": "925eb6a0-f336-40e9-a08e-880481c73729",
+ },
+ "spec": {
+ "flinkConfiguration": {"taskmanager.numberOfTaskSlots": "2"},
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ "logConfiguration": {"log4j-console.properties": "rootLogger.level = DEBUG"},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+}
+
+TEST_DEPLOYING_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T16:47:16Z",
+ "finalizers": ["flinkdeployments.flink.apache.org/finalizer"],
+ "generation": 2,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:logConfiguration": {
+ ".": {},
+ "f:log4j-console.properties": {},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ },
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:metadata": {
+ "f:finalizers": {
+ ".": {},
+ 'v:"flinkdeployments.flink.apache.org/finalizer"': {},
+ }
+ },
+ "f:spec": {
+ "f:job": {"f:args": {}},
+ "f:jobManager": {"f:replicas": {}},
+ },
+ "f:status": {
+ ".": {},
+ "f:clusterInfo": {},
+ "f:error": {},
+ "f:jobManagerDeploymentStatus": {},
+ "f:jobStatus": {
+ ".": {},
+ "f:savepointInfo": {
+ ".": {},
+ "f:lastPeriodicSavepointTimestamp": {},
+ "f:savepointHistory": {},
+ "f:triggerId": {},
+ "f:triggerTimestamp": {},
+ "f:triggerType": {},
+ },
+ "f:state": {},
+ },
+ "f:reconciliationStatus": {
+ ".": {},
+ "f:lastReconciledSpec": {},
+ "f:reconciliationTimestamp": {},
+ "f:state": {},
+ },
+ "f:taskManager": {
+ ".": {},
+ "f:labelSelector": {},
+ "f:replicas": {},
+ },
+ },
+ },
+ "manager": "okhttp",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ },
+ ],
+ "name": "flink-stream-example",
+ "namespace": "default",
+ "resourceVersion": "140043",
+ "uid": "925eb6a0-f336-40e9-a08e-880481c73729",
+ },
+ "spec": {
+ "flinkConfiguration": {"taskmanager.numberOfTaskSlots": "2"},
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "args": [],
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"replicas": 1, "resource": {"cpu": 1, "memory": "2048m"}},
+ "logConfiguration": {"log4j-console.properties": "rootLogger.level = DEBUG"},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+ "status": {
+ "clusterInfo": {},
+ "error": "",
+ "jobManagerDeploymentStatus": "DEPLOYING",
+ "jobStatus": {
+ "savepointInfo": {
+ "lastPeriodicSavepointTimestamp": 0,
+ "savepointHistory": [],
+ "triggerId": "",
+ "triggerTimestamp": 0,
+ "triggerType": "UNKNOWN",
+ },
+ "state": "RECONCILING",
+ },
+ "reconciliationStatus": {
+ "lastReconciledSpec": '{"spec":{"job":{"jarURI":"local:///opt/flink/examples/streaming/StateMachineExample.jar","parallelism":2,"entryClass":null,"args":[],"state":"running","savepointTriggerNonce":null,"initialSavepointPath":null,"upgradeMode":"stateless","allowNonRestoredState":null},"restartNonce":null,"flinkConfiguration":{"taskmanager.numberOfTaskSlots":"2"},"image":"flink:1.15","imagePullPolicy":null,"serviceAccount":"flink","flinkVersion":"v1_15","ingress":{"template": [...]
+ "reconciliationTimestamp": 1664124436834,
+ "state": "DEPLOYED",
+ },
+ "taskManager": {
+ "labelSelector": "component=taskmanager,app=flink-stream-example",
+ "replicas": 1,
+ },
+ },
+}
+
+TEST_DEPLOYED_NOT_READY_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T16:47:16Z",
+ "finalizers": ["flinkdeployments.flink.apache.org/finalizer"],
+ "generation": 2,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:logConfiguration": {
+ ".": {},
+ "f:log4j-console.properties": {},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ },
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:metadata": {
+ "f:finalizers": {
+ ".": {},
+ 'v:"flinkdeployments.flink.apache.org/finalizer"': {},
+ }
+ },
+ "f:spec": {
+ "f:job": {"f:args": {}},
+ "f:jobManager": {"f:replicas": {}},
+ },
+ "f:status": {
+ ".": {},
+ "f:clusterInfo": {},
+ "f:error": {},
+ "f:jobManagerDeploymentStatus": {},
+ "f:jobStatus": {
+ ".": {},
+ "f:savepointInfo": {
+ ".": {},
+ "f:lastPeriodicSavepointTimestamp": {},
+ "f:savepointHistory": {},
+ "f:triggerId": {},
+ "f:triggerTimestamp": {},
+ "f:triggerType": {},
+ },
+ "f:state": {},
+ },
+ "f:reconciliationStatus": {
+ ".": {},
+ "f:lastReconciledSpec": {},
+ "f:reconciliationTimestamp": {},
+ "f:state": {},
+ },
+ "f:taskManager": {
+ ".": {},
+ "f:labelSelector": {},
+ "f:replicas": {},
+ },
+ },
+ },
+ "manager": "okhttp",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ },
+ ],
+ "name": "flink-stream-example",
+ "namespace": "default",
+ "resourceVersion": "140061",
+ "uid": "925eb6a0-f336-40e9-a08e-880481c73729",
+ },
+ "spec": {
+ "flinkConfiguration": {"taskmanager.numberOfTaskSlots": "2"},
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "args": [],
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"replicas": 1, "resource": {"cpu": 1, "memory": "2048m"}},
+ "logConfiguration": {"log4j-console.properties": "rootLogger.level = DEBUG"},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+ "status": {
+ "clusterInfo": {},
+ "error": "",
+ "jobManagerDeploymentStatus": "DEPLOYED_NOT_READY",
+ "jobStatus": {
+ "savepointInfo": {
+ "lastPeriodicSavepointTimestamp": 0,
+ "savepointHistory": [],
+ "triggerId": "",
+ "triggerTimestamp": 0,
+ "triggerType": "UNKNOWN",
+ },
+ "state": "RECONCILING",
+ },
+ "reconciliationStatus": {
+ "lastReconciledSpec": '{"spec":{"job":{"jarURI":"local:///opt/flink/examples/streaming/StateMachineExample.jar","parallelism":2,"entryClass":null,"args":[],"state":"running","savepointTriggerNonce":null,"initialSavepointPath":null,"upgradeMode":"stateless","allowNonRestoredState":null},"restartNonce":null,"flinkConfiguration":{"taskmanager.numberOfTaskSlots":"2"},"image":"flink:1.15","imagePullPolicy":null,"serviceAccount":"flink","flinkVersion":"v1_15","ingress":{"template": [...]
+ "reconciliationTimestamp": 1664124436834,
+ "state": "DEPLOYED",
+ },
+ "taskManager": {
+ "labelSelector": "component=taskmanager,app=flink-stream-example",
+ "replicas": 1,
+ },
+ },
+}
+
+TEST_ERROR_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T16:40:30Z",
+ "finalizers": ["flinkdeployments.flink.apache.org/finalizer"],
+ "generation": 2,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:high-availability": {},
+ "f:high-availability.storageDir": {},
+ "f:state.checkpoints.dir": {},
+ "f:state.savepoints.dir": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:savepointTriggerNonce": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T16:40:30Z",
+ },
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:metadata": {
+ "f:finalizers": {
+ ".": {},
+ 'v:"flinkdeployments.flink.apache.org/finalizer"': {},
+ }
+ },
+ "f:spec": {
+ "f:job": {"f:args": {}},
+ "f:jobManager": {"f:replicas": {}},
+ },
+ "f:status": {
+ ".": {},
+ "f:clusterInfo": {},
+ "f:error": {},
+ "f:jobManagerDeploymentStatus": {},
+ "f:jobStatus": {
+ ".": {},
+ "f:savepointInfo": {
+ ".": {},
+ "f:lastPeriodicSavepointTimestamp": {},
+ "f:savepointHistory": {},
+ "f:triggerId": {},
+ "f:triggerTimestamp": {},
+ "f:triggerType": {},
+ },
+ "f:state": {},
+ },
+ "f:reconciliationStatus": {
+ ".": {},
+ "f:lastReconciledSpec": {},
+ "f:reconciliationTimestamp": {},
+ "f:state": {},
+ },
+ "f:taskManager": {
+ ".": {},
+ "f:labelSelector": {},
+ "f:replicas": {},
+ },
+ },
+ },
+ "manager": "okhttp",
+ "operation": "Update",
+ "time": "2022-09-25T16:40:30Z",
+ },
+ ],
+ "name": "flink-stream-example",
+ "namespace": "default",
+ "resourceVersion": "139635",
+ "uid": "4b18c5c0-38a4-4a7a-8c8f-036e47774c12",
+ },
+ "spec": {
+ "flinkConfiguration": {
+ "high-availability": "org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory",
+ "high-availability.storageDir": "file:///flink-data/ha",
+ "state.checkpoints.dir": "file:///flink-data/checkpoints",
+ "state.savepoints.dir": "file:///flink-data/savepoints",
+ "taskmanager.numberOfTaskSlots": "2",
+ },
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "args": [],
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "savepointTriggerNonce": 0,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"replicas": 1, "resource": {"cpu": 1, "memory": "2048m"}},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+ "status": {
+ "clusterInfo": {},
+ "error": "back-off 20s restarting failed container=flink-main-container"
+ " pod=flink-stream-example-c6c65d85b-ffbs7_default(ff52c4fd-88b6-468f-9914-c2a22c11b7a9)",
+ "jobManagerDeploymentStatus": "ERROR",
+ "jobStatus": {
+ "savepointInfo": {
+ "lastPeriodicSavepointTimestamp": 0,
+ "savepointHistory": [],
+ "triggerId": "",
+ "triggerTimestamp": 0,
+ "triggerType": "UNKNOWN",
+ },
+ "state": "RECONCILING",
+ },
+ "reconciliationStatus": {
+ "lastReconciledSpec": '{"spec":{"job":{"jarURI":"local:///opt/flink/examples/streaming/StateMachineExample.jar","parallelism":2,"entryClass":null,"args":[],"state":"running","savepointTriggerNonce":0,"initialSavepointPath":null,"upgradeMode":"stateless","allowNonRestoredState":null},"restartNonce":null,"flinkConfiguration":{"high-availability":"org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory","high-availability.storageDir":"file:///flink-data/ha","sta [...]
+ "reconciliationTimestamp": 1664124030853,
+ "state": "DEPLOYED",
+ },
+ "taskManager": {
+ "labelSelector": "component=taskmanager,app=flink-stream-example",
+ "replicas": 1,
+ },
+ },
+}
+
+TEST_READY_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T16:47:16Z",
+ "finalizers": ["flinkdeployments.flink.apache.org/finalizer"],
+ "generation": 2,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:logConfiguration": {
+ ".": {},
+ "f:log4j-console.properties": {},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:16Z",
+ },
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:metadata": {
+ "f:finalizers": {
+ ".": {},
+ 'v:"flinkdeployments.flink.apache.org/finalizer"': {},
+ }
+ },
+ "f:spec": {
+ "f:job": {"f:args": {}},
+ "f:jobManager": {"f:replicas": {}},
+ },
+ "f:status": {
+ ".": {},
+ "f:clusterInfo": {
+ ".": {},
+ "f:flink-revision": {},
+ "f:flink-version": {},
+ },
+ "f:error": {},
+ "f:jobManagerDeploymentStatus": {},
+ "f:jobStatus": {
+ ".": {},
+ "f:jobId": {},
+ "f:jobName": {},
+ "f:savepointInfo": {
+ ".": {},
+ "f:lastPeriodicSavepointTimestamp": {},
+ "f:savepointHistory": {},
+ "f:triggerId": {},
+ "f:triggerTimestamp": {},
+ "f:triggerType": {},
+ },
+ "f:startTime": {},
+ "f:state": {},
+ "f:updateTime": {},
+ },
+ "f:reconciliationStatus": {
+ ".": {},
+ "f:lastReconciledSpec": {},
+ "f:reconciliationTimestamp": {},
+ "f:state": {},
+ },
+ "f:taskManager": {
+ ".": {},
+ "f:labelSelector": {},
+ "f:replicas": {},
+ },
+ },
+ },
+ "manager": "okhttp",
+ "operation": "Update",
+ "time": "2022-09-25T16:47:34Z",
+ },
+ ],
+ "name": "flink-stream-example",
+ "namespace": "default",
+ "resourceVersion": "140076",
+ "uid": "925eb6a0-f336-40e9-a08e-880481c73729",
+ },
+ "spec": {
+ "flinkConfiguration": {"taskmanager.numberOfTaskSlots": "2"},
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "args": [],
+ "jarURI": "local:///opt/flink/examples/streaming/StateMachineExample.jar",
+ "parallelism": 2,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"replicas": 1, "resource": {"cpu": 1, "memory": "2048m"}},
+ "logConfiguration": {"log4j-console.properties": "rootLogger.level = DEBUG"},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+ "status": {
+ "clusterInfo": {
+ "flink-revision": "f494be6 @ 2022-06-20T14:40:28 02:00",
+ "flink-version": "1.15.1",
+ },
+ "error": "",
+ "jobManagerDeploymentStatus": "READY",
+ "jobStatus": {
+ "jobId": "5d6feb14e05a3b00cbc55c2c8331fb7f",
+ "jobName": "State machine job",
+ "savepointInfo": {
+ "lastPeriodicSavepointTimestamp": 0,
+ "savepointHistory": [],
+ "triggerId": "",
+ "triggerTimestamp": 0,
+ "triggerType": "UNKNOWN",
+ },
+ "startTime": "1664124442817",
+ "state": "CREATED",
+ "updateTime": "1664124454261",
+ },
+ "reconciliationStatus": {
+ "lastReconciledSpec": '{"spec":{"job":{"jarURI":"local:///opt/flink/examples/streaming/StateMachineExample.jar","parallelism":2,"entryClass":null,"args":[],"state":"running","savepointTriggerNonce":null,"initialSavepointPath":null,"upgradeMode":"stateless","allowNonRestoredState":null},"restartNonce":null,"flinkConfiguration":{"taskmanager.numberOfTaskSlots":"2"},"image":"flink:1.15","imagePullPolicy":null,"serviceAccount":"flink","flinkVersion":"v1_15","ingress":{"template": [...]
+ "reconciliationTimestamp": 1664124436834,
+ "state": "DEPLOYED",
+ },
+ "taskManager": {
+ "labelSelector": "component=taskmanager,app=flink-stream-example",
+ "replicas": 1,
+ },
+ },
+}
+
+TEST_MISSING_CLUSTER = {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "kind": "FlinkDeployment",
+ "metadata": {
+ "creationTimestamp": "2022-09-25T18:49:59Z",
+ "finalizers": ["flinkdeployments.flink.apache.org/finalizer"],
+ "generation": 2,
+ "managedFields": [
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:spec": {
+ ".": {},
+ "f:flinkConfiguration": {
+ ".": {},
+ "f:taskmanager.numberOfTaskSlots": {},
+ },
+ "f:flinkVersion": {},
+ "f:image": {},
+ "f:ingress": {".": {}, "f:template": {}},
+ "f:job": {
+ ".": {},
+ "f:jarURI": {},
+ "f:parallelism": {},
+ "f:state": {},
+ "f:upgradeMode": {},
+ },
+ "f:jobManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ "f:logConfiguration": {
+ ".": {},
+ "f:log4j-console.properties": {},
+ },
+ "f:serviceAccount": {},
+ "f:taskManager": {
+ ".": {},
+ "f:resource": {".": {}, "f:cpu": {}, "f:memory": {}},
+ },
+ }
+ },
+ "manager": "OpenAPI-Generator",
+ "operation": "Update",
+ "time": "2022-09-25T18:49:59Z",
+ },
+ {
+ "apiVersion": "flink.apache.org/v1beta1",
+ "fieldsType": "FieldsV1",
+ "fieldsV1": {
+ "f:metadata": {
+ "f:finalizers": {
+ ".": {},
+ 'v:"flinkdeployments.flink.apache.org/finalizer"': {},
+ }
+ },
+ "f:spec": {
+ "f:job": {"f:args": {}},
+ "f:jobManager": {"f:replicas": {}},
+ },
+ "f:status": {
+ ".": {},
+ "f:clusterInfo": {},
+ "f:error": {},
+ "f:jobManagerDeploymentStatus": {},
+ "f:jobStatus": {
+ ".": {},
+ "f:savepointInfo": {
+ ".": {},
+ "f:lastPeriodicSavepointTimestamp": {},
+ "f:savepointHistory": {},
+ "f:triggerId": {},
+ "f:triggerTimestamp": {},
+ "f:triggerType": {},
+ },
+ },
+ "f:reconciliationStatus": {
+ ".": {},
+ "f:lastReconciledSpec": {},
+ "f:reconciliationTimestamp": {},
+ "f:state": {},
+ },
+ "f:taskManager": {
+ ".": {},
+ "f:labelSelector": {},
+ "f:replicas": {},
+ },
+ },
+ },
+ "manager": "okhttp",
+ "operation": "Update",
+ "time": "2022-09-25T18:50:00Z",
+ },
+ ],
+ "name": "flink-sm-ex1",
+ "namespace": "default",
+ "resourceVersion": "145575",
+ "uid": "6ccd47cf-c763-496e-b02e-28146b628646",
+ },
+ "spec": {
+ "flinkConfiguration": {"taskmanager.numberOfTaskSlots": "2"},
+ "flinkVersion": "v1_15",
+ "image": "flink:1.15",
+ "ingress": {"template": "{{name}}.{{namespace}}.flink.k8s.io"},
+ "job": {
+ "args": [],
+ "jarURI": "local:///opt/flink/examples/streaming/TopSpeedWindowing.jar",
+ "parallelism": 4,
+ "state": "running",
+ "upgradeMode": "stateless",
+ },
+ "jobManager": {"replicas": 1, "resource": {"cpu": 1, "memory": "2048m"}},
+ "logConfiguration": {"log4j-console.properties": "rootLogger.level = DEBUG\n"},
+ "serviceAccount": "flink",
+ "taskManager": {"resource": {"cpu": 1, "memory": "2048m"}},
+ },
+ "status": {
+ "clusterInfo": {},
+ "error": "",
+ "jobManagerDeploymentStatus": "MISSING",
+ "jobStatus": {
+ "savepointInfo": {
+ "lastPeriodicSavepointTimestamp": 0,
+ "savepointHistory": [],
+ "triggerId": "",
+ "triggerTimestamp": 0,
+ "triggerType": "UNKNOWN",
+ }
+ },
+ "reconciliationStatus": {
+ "lastReconciledSpec": '{"spec":{"job":{"jarURI":"local:///opt/flink/examples/streaming/TopSpeedWindowing.jar","parallelism":4,"entryClass":null,"args":[],"state":"suspended","savepointTriggerNonce":null,"initialSavepointPath":null,"upgradeMode":"stateless","allowNonRestoredState":null},"restartNonce":null,"flinkConfiguration":{"taskmanager.numberOfTaskSlots":"2"},"image":"flink:1.15","imagePullPolicy":null,"serviceAccount":"flink","flinkVersion":"v1_15","ingress":{"template": [...]
+ "reconciliationTimestamp": 1664131800071,
+ "state": "UPGRADING",
+ },
+ "taskManager": {"labelSelector": "", "replicas": 0},
+ },
+}
+
+TEST_POD_LOGS = [
+ b"2022-09-25 19:01:47,027 INFO KubernetesTaskExecutorRunner [] - ---------\n",
+ b"Successful registration at resource manager akka.tcp://flink@basic-example.default:6\n",
+ b"Receive slot request 80a7ef3e8cc1a2c09b4e3b2fbd70b28d for job 363eed78e59\n",
+ b"Checkpoint storage is set to 'jobmanager'\n",
+ b"Flat Map -> Sink: Print to Std. Out (2/2)#0 (e7492dc4a) switched to RUNNING.",
+]
+TEST_POD_LOG_RESULT = (
+ "2022-09-25 19:01:47,027 INFO KubernetesTaskExecutorRunner [] - ---------\n"
+ "Successful registration at resource manager akka.tcp://flink@basic-example.default:6\n"
+ "Receive slot request 80a7ef3e8cc1a2c09b4e3b2fbd70b28d for job 363eed78e59\n"
+ "Checkpoint storage is set to 'jobmanager'\n"
+ "Flat Map -> Sink: Print to Std. Out (2/2)#0 (e7492dc4a) switched to RUNNING."
+)
+
+TASK_MANAGER_POD = V1Pod(
+ api_version="V1", metadata=V1ObjectMeta(namespace="default", name="basic-example-taskmanager-1-1")
+)
+TASK_MANAGER_POD_LIST = V1PodList(api_version="v1", items=[TASK_MANAGER_POD], kind="PodList")
+
+
+@patch("airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_conn")
+class TestFlinkKubernetesSensor(unittest.TestCase):
+ def setUp(self):
+ db.merge_conn(Connection(conn_id="kubernetes_default", conn_type="kubernetes", extra=json.dumps({})))
+ db.merge_conn(
+ Connection(
+ conn_id="kubernetes_default",
+ conn_type="kubernetes",
+ extra=json.dumps({}),
+ )
+ )
+ db.merge_conn(
+ Connection(
+ conn_id="kubernetes_with_namespace",
+ conn_type="kubernetes",
+ extra=json.dumps({"extra__kubernetes__namespace": "mock_namespace"}),
+ )
+ )
+ args = {"owner": "airflow", "start_date": timezone.datetime(2020, 2, 1)}
+ self.dag = DAG("test_dag_id", default_args=args)
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ def test_cluster_ready_state(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+ assert sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_ERROR_CLUSTER,
+ )
+ def test_cluster_error_state(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+ with pytest.raises(AirflowException):
+ sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_NO_STATE_CLUSTER,
+ )
+ def test_new_application(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+
+ assert not sensor.poke(None)
+
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_DEPLOYED_NOT_READY_CLUSTER,
+ )
+ def test_deployed_not_ready_cluster(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+ assert not sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_DEPLOYING_CLUSTER,
+ )
+ def test_deploying_cluster(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+ assert not sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_MISSING_CLUSTER,
+ )
+ def test_missing_cluster(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example", dag=self.dag, task_id="test_task_id"
+ )
+ with pytest.raises(AirflowException):
+ sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="default",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ def test_namespace_from_sensor(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_with_namespace",
+ namespace="sensor_namespace",
+ task_id="test_task_id",
+ )
+ sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="sensor_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ def test_api_group_and_version_from_sensor(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ api_group = "flink.apache.org"
+ api_version = "v1beta1"
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_with_namespace",
+ task_id="test_task_id",
+ api_group=api_group,
+ api_version=api_version,
+ )
+ sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group=api_group,
+ name="flink-stream-example",
+ namespace="mock_namespace",
+ plural="flinkdeployments",
+ version=api_version,
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ def test_namespace_from_connection(self, mock_get_namespaced_crd, mock_kubernetes_hook):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ dag=self.dag,
+ kubernetes_conn_id="kubernetes_with_namespace",
+ task_id="test_task_id",
+ )
+ sensor.poke(None)
+ mock_kubernetes_hook.assert_called_once_with()
+ mock_get_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ name="flink-stream-example",
+ namespace="mock_namespace",
+ plural="flinkdeployments",
+ version="v1beta1",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_ERROR_CLUSTER,
+ )
+ @patch("logging.Logger.error")
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs",
+ return_value=TEST_POD_LOGS,
+ )
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_namespaced_pod_list",
+ return_value=TASK_MANAGER_POD_LIST,
+ )
+ def test_driver_logging_failure(
+ self, mock_namespaced_pod_list, mock_pod_logs, error_log_call, mock_namespaced_crd, mock_kube_conn
+ ):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ attach_log=True,
+ dag=self.dag,
+ task_id="test_task_id",
+ )
+ with pytest.raises(AirflowException):
+ sensor.poke(None)
+ mock_namespaced_pod_list.assert_called_once_with(
+ namespace="default", watch=False, label_selector="component=taskmanager,app=flink-stream-example"
+ )
+ mock_pod_logs.assert_called_once_with("basic-example-taskmanager-1-1", namespace="default")
+ error_log_call.assert_called_once_with(TEST_POD_LOG_RESULT)
+ mock_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ version="v1beta1",
+ namespace="default",
+ plural="flinkdeployments",
+ name="flink-stream-example",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ @patch("logging.Logger.info")
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs",
+ return_value=TEST_POD_LOGS,
+ )
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_namespaced_pod_list",
+ return_value=TASK_MANAGER_POD_LIST,
+ )
+ def test_driver_logging_completed(
+ self, mock_namespaced_pod_list, mock_pod_logs, info_log_call, mock_namespaced_crd, mock_kube_conn
+ ):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ attach_log=True,
+ dag=self.dag,
+ task_id="test_task_id",
+ )
+ sensor.poke(None)
+
+ mock_namespaced_pod_list.assert_called_once_with(
+ namespace="default", watch=False, label_selector="component=taskmanager,app=flink-stream-example"
+ )
+ mock_pod_logs.assert_called_once_with("basic-example-taskmanager-1-1", namespace="default")
+ log_info_call = info_log_call.mock_calls[4]
+ log_value = log_info_call[1][0]
+
+ assert log_value == TEST_POD_LOG_RESULT
+
+ mock_namespaced_crd.assert_called_once_with(
+ group="flink.apache.org",
+ version="v1beta1",
+ namespace="default",
+ plural="flinkdeployments",
+ name="flink-stream-example",
+ )
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_READY_CLUSTER,
+ )
+ @patch("logging.Logger.warning")
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs",
+ side_effect=ApiException("Test api exception"),
+ )
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_namespaced_pod_list",
+ return_value=TASK_MANAGER_POD_LIST,
+ )
+ def test_driver_logging_error(
+ self, mock_namespaced_pod_list, mock_pod_logs, warn_log_call, mock_namespaced_crd, mock_kube_conn
+ ):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ attach_log=True,
+ dag=self.dag,
+ task_id="test_task_id",
+ )
+ sensor.poke(None)
+ warn_log_call.assert_called_once()
+
+ @patch(
+ "kubernetes.client.api.custom_objects_api.CustomObjectsApi.get_namespaced_custom_object",
+ return_value=TEST_ERROR_CLUSTER,
+ )
+ @patch("logging.Logger.warning")
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_pod_logs",
+ side_effect=ApiException("Test api exception"),
+ )
+ @patch(
+ "airflow.providers.cncf.kubernetes.hooks.kubernetes.KubernetesHook.get_namespaced_pod_list",
+ return_value=TASK_MANAGER_POD_LIST,
+ )
+ def test_driver_logging_error_missing_state(
+ self, mock_namespaced_pod_list, mock_pod_logs, warn_log_call, mock_namespaced_crd, mock_kube_conn
+ ):
+ sensor = FlinkKubernetesSensor(
+ application_name="flink-stream-example",
+ attach_log=True,
+ dag=self.dag,
+ task_id="test_task_id",
+ )
+ with pytest.raises(AirflowException):
+ sensor.poke(None)
+ warn_log_call.assert_called_once()