diff --git a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
index 02f6b38a852c5..87ff85308d15d 100644
--- a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
@@ -80,6 +80,7 @@ body:
- odbc
- openfaas
- openlineage
+ - opensearch
- opsgenie
- oracle
- pagerduty
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index b9858abfa99ed..aab84e7083ffd 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -676,10 +676,10 @@ deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc
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, openlineage, opsgenie, oracle, otel, pagerduty, pandas, papermill,
-password, pinot, plexus, postgres, presto, rabbitmq, redis, s3, salesforce, samba, segment,
-sendgrid, sentry, sftp, singularity, slack, smtp, snowflake, spark, sqlite, ssh, statsd, tableau,
-tabular, telegram, trino, vertica, virtualenv, webhdfs, winrm, yandex, zendesk
+mysql, neo4j, odbc, openfaas, openlineage, opensearch, opsgenie, oracle, otel, pagerduty, pandas,
+papermill, password, pinot, plexus, postgres, presto, rabbitmq, redis, s3, salesforce, samba,
+segment, sendgrid, sentry, sftp, singularity, slack, smtp, 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 26351cf4254e6..027d4a621c000 100644
--- a/INSTALL
+++ b/INSTALL
@@ -103,10 +103,10 @@ deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc
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, openlineage, opsgenie, oracle, otel, pagerduty, pandas, papermill,
-password, pinot, plexus, postgres, presto, rabbitmq, redis, s3, salesforce, samba, segment,
-sendgrid, sentry, sftp, singularity, slack, smtp, snowflake, spark, sqlite, ssh, statsd, tableau,
-tabular, telegram, trino, vertica, virtualenv, webhdfs, winrm, yandex, zendesk
+mysql, neo4j, odbc, openfaas, openlineage, opensearch, opsgenie, oracle, otel, pagerduty, pandas,
+papermill, password, pinot, plexus, postgres, presto, rabbitmq, redis, s3, salesforce, samba,
+segment, sendgrid, sentry, sftp, singularity, slack, smtp, 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/opensearch/CHANGELOG.rst b/airflow/providers/opensearch/CHANGELOG.rst
new file mode 100644
index 0000000000000..4cb4526149fa0
--- /dev/null
+++ b/airflow/providers/opensearch/CHANGELOG.rst
@@ -0,0 +1,27 @@
+ .. 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.
+
+``apache-airflow-providers-opensearch``
+
+Changelog
+---------
diff --git a/airflow/providers/opensearch/__init__.py b/airflow/providers/opensearch/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/airflow/providers/opensearch/__init__.py
@@ -0,0 +1,16 @@
+# 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/opensearch/hooks/__init__.py b/airflow/providers/opensearch/hooks/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/airflow/providers/opensearch/hooks/__init__.py
@@ -0,0 +1,16 @@
+# 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/opensearch/hooks/opensearch.py b/airflow/providers/opensearch/hooks/opensearch.py
new file mode 100644
index 0000000000000..97907e54d52ca
--- /dev/null
+++ b/airflow/providers/opensearch/hooks/opensearch.py
@@ -0,0 +1,122 @@
+#
+# 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
+from functools import cached_property
+from typing import Any
+
+from opensearchpy import OpenSearch, RequestsHttpConnection
+
+from airflow.exceptions import AirflowException
+from airflow.hooks.base import BaseHook
+
+
+class OpenSearchHook(BaseHook):
+ """
+ Provide a thin wrapper around the OpenSearch client.
+
+ :param: open_search_conn_id: Connection to use with Open Search
+ :param: log_query: Whether to log the query used for Open Search
+ """
+
+ conn_name_attr = "opensearch_conn_id"
+ default_conn_name = "opensearch_default"
+ conn_type = "opensearch"
+ hook_name = "OpenSearch Hook"
+
+ def __init__(self, open_search_conn_id: str, log_query: bool, **kwargs: Any):
+ super().__init__(**kwargs)
+ self.conn_id = open_search_conn_id
+ self.log_query = log_query
+
+ self.use_ssl = self.conn.extra_dejson.get("use_ssl", False)
+ self.verify_certs = self.conn.extra_dejson.get("verify_certs", False)
+ self.__SERVICE = "es"
+
+ @cached_property
+ def conn(self):
+ return self.get_connection(self.conn_id)
+
+ @cached_property
+ def client(self) -> OpenSearch:
+ """This function is intended for Operators that forward high level client objects."""
+ auth = (self.conn.login, self.conn.password)
+ client = OpenSearch(
+ hosts=[{"host": self.conn.host, "port": self.conn.port}],
+ http_auth=auth,
+ use_ssl=self.use_ssl,
+ verify_certs=self.verify_certs,
+ connection_class=RequestsHttpConnection,
+ )
+ return client
+
+ def search(self, query: dict, index_name: str, **kwargs: Any) -> Any:
+ """
+ Run a search query against the connected OpenSearch cluster.
+
+ :param: query: The query for the search against OpenSearch.
+ :param: index_name: The name of the index to search against
+ """
+ if self.log_query:
+ self.log.info("Searching %s with Query: %s", index_name, query)
+ return self.client.search(body=query, index=index_name, **kwargs)
+
+ def index(self, document: dict, index_name: str, doc_id: int, **kwargs: Any) -> Any:
+ """
+ Index a document on OpenSearch.
+
+ :param: document: A dictionary representation of the document
+ :param: index_name: the name of the index that this document will be associated with
+ :param: doc_id: the numerical identifier that will be used to identify the document on the index.
+ """
+ return self.client.index(index=index_name, id=doc_id, body=document, **kwargs)
+
+ def delete(self, index_name: str, query: dict | None = None, doc_id: int | None = None) -> Any:
+ """
+ Delete from an index by either a query or by the document id.
+
+ :param: index_name: the name of the index to delete from
+ :param: query: If deleting by query a dict representation of the query to run to
+ identify documents to delete.
+ :param: doc_id: The identifier of the document to delete.
+ """
+ if query is not None:
+ if self.log_query:
+ self.log.info("Deleting from %s using Query: %s", index_name, query)
+ return self.client.delete_by_query(index=index_name, body=query)
+ elif doc_id is not None:
+ return self.client.delete(index=index_name, id=doc_id)
+ else:
+ AirflowException("To delete a document you must include one of either a query or a document id. ")
+
+ @staticmethod
+ def get_ui_field_behaviour() -> dict[str, Any]:
+ """Returns custom UI field behaviour for Open Search Connection."""
+ return {
+ "hidden_fields": ["schema"],
+ "relabeling": {
+ "extra": "Open Search Configuration",
+ },
+ "placeholders": {
+ "extra": json.dumps(
+ {"use_ssl": True, "verify_certs": True},
+ indent=2,
+ ),
+ },
+ }
diff --git a/airflow/providers/opensearch/operators/__init__.py b/airflow/providers/opensearch/operators/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/airflow/providers/opensearch/operators/__init__.py
@@ -0,0 +1,16 @@
+# 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/opensearch/operators/opensearch.py b/airflow/providers/opensearch/operators/opensearch.py
new file mode 100644
index 0000000000000..08ab1dc0ce21b
--- /dev/null
+++ b/airflow/providers/opensearch/operators/opensearch.py
@@ -0,0 +1,194 @@
+#
+# 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 functools import cached_property
+from typing import TYPE_CHECKING, Any, Sequence
+
+from opensearchpy.exceptions import OpenSearchException
+
+from airflow.exceptions import AirflowException
+from airflow.models import BaseOperator
+from airflow.providers.opensearch.hooks.opensearch import OpenSearchHook
+
+if TYPE_CHECKING:
+ from airflow.utils.context import Context
+
+
+class OpenSearchQueryOperator(BaseOperator):
+ """
+ Runs a query search against a given index on an OpenSearch cluster and returns results.
+
+ .. seealso::
+ For more information on how to use this operator, take a look at the guide:
+ :ref:`howto/operator:OpenSearchQueryOperator`
+
+ :param: query: A Dictionary Open Search DSL query.
+ :param: search_object: A Search object from opensearch-dsl.
+ :param: index_name: The name of the index to search for documents.
+ :param: opensearch_conn_id: opensearch connection to use
+ :param: log_query: Whether to log the query used. Defaults to True and logs query used.
+ """
+
+ template_fields: Sequence[str] = ["query"]
+
+ def __init__(
+ self,
+ *,
+ query: dict | None = None,
+ search_object: Any | None = None,
+ index_name: str | None = None,
+ opensearch_conn_id: str = "opensearch_default",
+ log_query: bool = True,
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.query = query
+ self.index_name = index_name
+ self.opensearch_conn_id = opensearch_conn_id
+ self.log_query = log_query
+ self.search_object = search_object
+
+ @cached_property
+ def hook(self) -> OpenSearchHook:
+ """Gets an instance of an OpenSearchHook."""
+ return OpenSearchHook(open_search_conn_id=self.opensearch_conn_id, log_query=self.log_query)
+
+ def execute(self, context: Context) -> Any:
+ """Executes a search against a given index or a Search object on an OpenSearch Cluster."""
+ result = None
+
+ if self.query is not None:
+ if not self.query.get("query"):
+ raise AirflowException("Query input is missing required field Query in dictionary")
+ if self.index_name is None:
+ raise AirflowException("Index name is required when using the query input.")
+ try:
+ result = self.hook.search(index_name=self.index_name, query=self.query)
+ except OpenSearchException as e:
+ raise AirflowException(e)
+ elif self.search_object is not None:
+ try:
+ result = self.search_object.using(self.hook.client).execute()
+ except OpenSearchException as e:
+ raise AirflowException(e)
+ else:
+ raise AirflowException(
+ """Input missing required input of query or search_object.
+ Either query or search_object is required."""
+ )
+ return result
+
+
+class OpenSearchCreateIndexOperator(BaseOperator):
+ """
+ Create a new index on an Open Search cluster with a given index name.
+
+ .. seealso::
+ For more information on how to use this operator, take a look at the guide:
+ :ref:`howto/operator:OpenSearchCreateIndexOperator`
+
+ :param: index_name: The name of the index to be created.
+ :param: index_body: A dictionary that defines index settings
+ :param: opensearch_conn_id: opensearch connection to use
+ """
+
+ def __init__(
+ self,
+ *,
+ index_name: str,
+ index_body: dict[str, Any],
+ opensearch_conn_id: str = "opensearch_default",
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.index_name = index_name
+ self.index_body = index_body
+ self.opensearch_conn_id = opensearch_conn_id
+
+ @cached_property
+ def hook(self) -> OpenSearchHook:
+ """Gets an instance of an OpenSearchHook."""
+ return OpenSearchHook(open_search_conn_id=self.opensearch_conn_id, log_query=False)
+
+ def execute(self, context: Context) -> Any:
+ """Creates an index on an Open Search cluster."""
+ try:
+ self.hook.client.indices.create(index=self.index_name, body=self.index_body)
+ except OpenSearchException as e:
+ raise AirflowException(e)
+
+
+class OpenSearchAddDocumentOperator(BaseOperator):
+ """
+ Add a new document to a given Index or overwrite an existing one.
+
+ .. seealso::
+ For more information on how to use this operator, take a look at the guide:
+ :ref:`howto/operator:OpenSearchAddDocumentOperator`
+
+ :param: index_name: The name of the index to put the document.
+ :param: document: A dictionary representation of the document.
+ :param: document_id: The id for the document in the index.
+ :param: doc_class: A Document subclassed object using opensearch-dsl
+ :param: opensearch_conn_id: opensearch connection to use
+ """
+
+ def __init__(
+ self,
+ *,
+ index_name: str | None = None,
+ document: dict[str, Any] | None = None,
+ doc_id: int | None = None,
+ doc_class: Any | None = None,
+ opensearch_conn_id: str = "opensearch_default",
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.index_name = index_name
+ self.document = document
+ self.doc_id = doc_id
+ self.doc_class = doc_class
+ self.opensearch_conn_id = opensearch_conn_id
+
+ @cached_property
+ def hook(self) -> OpenSearchHook:
+ """Gets an instance of an OpenSearchHook."""
+ return OpenSearchHook(open_search_conn_id=self.opensearch_conn_id, log_query=False)
+
+ def execute(self, context: Context) -> Any:
+ """Saves a document to a given index on an OpenSearch cluster."""
+ if self.doc_class is not None:
+ try:
+ doc = self.doc_class.init(using=self.hook.client)
+ result = doc.save(using=self.hook.client)
+ except OpenSearchException as e:
+ raise AirflowException(e)
+ elif self.index_name is not None and self.document is not None and self.doc_id is not None:
+ try:
+ result = self.hook.index(
+ index_name=self.index_name, document=self.document, doc_id=self.doc_id
+ )
+ except OpenSearchException as e:
+ raise AirflowException(e)
+ else:
+ raise AirflowException(
+ "Index name, document dictionary and doc_id or a Document subclassed object is required."
+ )
+
+ return result
diff --git a/airflow/providers/opensearch/provider.yaml b/airflow/providers/opensearch/provider.yaml
new file mode 100644
index 0000000000000..270d7cd2085dd
--- /dev/null
+++ b/airflow/providers/opensearch/provider.yaml
@@ -0,0 +1,52 @@
+# 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-opensearch
+name: Opensearch
+description: |
+ `Opensearch `__
+
+suspended: false
+versions:
+ - 1.0.0
+
+dependencies:
+ - apache-airflow>=2.5.0
+ - opensearch-py>=2.2.0
+
+integrations:
+ - integration-name: Opensearch
+ external-doc-url: https://opensearch.org/
+ how-to-guide:
+ - /docs/apache-airflow-providers-opensearch/operators/opensearch.rst
+ logo: /integration-logos/opensearch/opensearch.png
+ tags: [software]
+
+hooks:
+ - integration-name: Opensearch
+ python-modules:
+ - airflow.providers.opensearch.hooks.opensearch
+
+operators:
+ - integration-name: Opensearch
+ python-modules:
+ - airflow.providers.opensearch.operators.opensearch
+
+connection-types:
+ - hook-class-name: airflow.providers.opensearch.hooks.opensearch.OpenSearchHook
+ connection-type: opensearch
diff --git a/docs/apache-airflow-providers-opensearch/changelog.rst b/docs/apache-airflow-providers-opensearch/changelog.rst
new file mode 100644
index 0000000000000..d1bb0e4735929
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/changelog.rst
@@ -0,0 +1,19 @@
+
+ .. 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:: ../../airflow/providers/opensearch/CHANGELOG.rst
diff --git a/docs/apache-airflow-providers-opensearch/commits.rst b/docs/apache-airflow-providers-opensearch/commits.rst
new file mode 100644
index 0000000000000..d36d55467eec3
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/commits.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.
+
+
+Package apache-airflow-providers-opensearch
+------------------------------------------------------
+
+`OpenSearch `__
+
+
+This is detailed commit list of changes for versions provider package: ``opensearch``.
+For high-level changelog, see :doc:`package information including changelog `.
+
+1.0.0
+.....
diff --git a/docs/apache-airflow-providers-opensearch/connections/index.rst b/docs/apache-airflow-providers-opensearch/connections/index.rst
new file mode 100644
index 0000000000000..72d2846638b3a
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/connections/index.rst
@@ -0,0 +1,29 @@
+
+ .. 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.
+
+
+
+OpenSearch Connections
+=======================
+
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ *
diff --git a/docs/apache-airflow-providers-opensearch/connections/opensearch.rst b/docs/apache-airflow-providers-opensearch/connections/opensearch.rst
new file mode 100644
index 0000000000000..781f5da502cd4
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/connections/opensearch.rst
@@ -0,0 +1,37 @@
+ .. 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.
+
+
+
+OpenSearch Connection
+=====================
+The OpenSearch connection provides credentials for an OpenSearch instance.
+
+Configuring the Connection
+--------------------------
+Host (required)
+ The host address of the Open Search instance.
+Login (required)
+ The login user.
+Password (required)
+ The password for the login user.
+Extra (optional)
+ Specifying the extra parameters as a (json dictionary) that can be used in the OpenSearch connection.
+ The following parameters are all optional:
+
+ * ``use_ssl``: Boolean on requiring an ssl connection. Default is false.
+ * ``verify_certs``: Boolean indicating to verify certs for ssl. Default is false.
diff --git a/docs/apache-airflow-providers-opensearch/index.rst b/docs/apache-airflow-providers-opensearch/index.rst
new file mode 100644
index 0000000000000..d122ba3831577
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/index.rst
@@ -0,0 +1,102 @@
+
+ .. 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-opensearch``
+=======================================
+
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Basics
+
+ Home
+ Changelog
+ Security
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Guides
+
+ Connection types
+ Operators
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: References
+
+ Python API <_api/airflow/providers/opensearch/index>
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: System tests
+
+ System Tests <_api/tests/system/providers/opensearch/index>
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Resources
+
+ PyPI Repository
+ Installing from sources
+
+.. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN AT RELEASE TIME!
+
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Commits
+
+ Detailed list of commits
+
+
+Package apache-airflow-providers-opensearch
+------------------------------------------------------
+`OpenSearch `__
+
+Release: 1.0.0
+
+Provider package
+----------------
+
+This is a provider package for ``opensearch`` provider. All classes for this provider package
+are in ``airflow.providers.opensearch`` 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-opensearch``
+
+Requirements
+------------
+
+The minimum Apache Airflow version supported by this provider package is ``2.5.0``.
+
+=================== ==================
+PIP package Version required
+=================== ==================
+``apache-airflow`` ``>=2.5.0``
+``opensearchpy`` ``>=2.2.0``
+=================== ==================
diff --git a/docs/apache-airflow-providers-opensearch/installing-providers-from-sources.rst b/docs/apache-airflow-providers-opensearch/installing-providers-from-sources.rst
new file mode 100644
index 0000000000000..b4e730f4ff21a
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/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:: ../exts/includes/installing-providers-from-sources.rst
diff --git a/docs/apache-airflow-providers-opensearch/operators/index.rst b/docs/apache-airflow-providers-opensearch/operators/index.rst
new file mode 100644
index 0000000000000..bc0f38e1108f6
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/operators/index.rst
@@ -0,0 +1,29 @@
+
+ .. 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.
+
+
+
+Open Search Operators
+======================
+
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ *
diff --git a/docs/apache-airflow-providers-opensearch/operators/opensearch.rst b/docs/apache-airflow-providers-opensearch/operators/opensearch.rst
new file mode 100644
index 0000000000000..77bb8a270e84f
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/operators/opensearch.rst
@@ -0,0 +1,72 @@
+ .. 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.
+
+=============
+OpenSearch
+=============
+
+`OpenSearch `__
+
+
+Operators
+---------
+
+.. _howto/operator:OpenSearchCreateIndexOperator:
+
+Create an Index in Open Search
+==============================
+
+Use :class:`~airflow.providers.opensearch.operators.opensearch.OpenSearchCreateIndexOperator`
+to create a new index in an Open Search domain.
+
+
+
+.. exampleinclude:: /../../tests/system/providers/opensearch/example_opensearch.py
+ :language: python
+ :start-after: [START howto_operator_opensearch_create_index]
+ :dedent: 4
+ :end-before: [END howto_operator_opensearch_create_index]
+
+
+.. _howto/operator:OpenSearchAddDocumentOperator:
+
+Add a Document to an Index on OpenSearch
+=========================================
+
+Use :class:`~airflow.providers.opensearch.operators.opensearch.OpenSearchAddDocumentOperator`
+to add single documents to an Open Search Index
+
+.. exampleinclude:: /../../tests/system/providers/opensearch/example_opensearch.py
+ :language: python
+ :start-after: [START howto_operator_opensearch_add_document]
+ :dedent: 4
+ :end-before: [END howto_operator_opensearch_add_document]
+
+
+.. _howto/operator:OpenSearchQueryOperator:
+
+Run a query against an Open Search Index
+=========================================
+
+Use :class:`~airflow.providers.opensearch.operators.opensearch.OpenSearchQueryOperator`
+to run a query against an Open Search index.
+
+.. exampleinclude:: /../../tests/system/providers/opensearch/example_opensearch.py
+ :language: python
+ :start-after: [START howto_operator_opensearch_query]
+ :dedent: 4
+ :end-before: [END howto_operator_opensearch_query]
diff --git a/docs/apache-airflow-providers-opensearch/security.rst b/docs/apache-airflow-providers-opensearch/security.rst
new file mode 100644
index 0000000000000..66c6f79a4ecfc
--- /dev/null
+++ b/docs/apache-airflow-providers-opensearch/security.rst
@@ -0,0 +1,38 @@
+
+ .. 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.
+
+Releasing security patches
+--------------------------
+
+Airflow providers are released independently from Airflow itself and the information about vulnerabilities
+is published separately. You can upgrade providers independently from Airflow itself, following the
+instructions found in :doc:`apache-airflow:installation/installing-from-pypi`.
+
+When we release Provider version, the development is always done from the ``main`` branch where we prepare
+the next version. The provider uses strict `SemVer `_ versioning policy. Depending on
+the scope of the change, Provider will get ''MAJOR'' version upgrade when there are
+breaking changes, ``MINOR`` version upgrade when there are new features or ``PATCHLEVEL`` version upgrade
+when there are only bug fixes (including security bugfixes) - and this is the only version that receives
+security fixes by default, so you should upgrade to latest version of the provider if you want to receive
+all released security fixes.
+
+The only exception to that rule is when we have a critical security fix and good reason to provide an
+out-of-band release for the provider, in which case stakeholders in the provider might decide to cherry-pick
+and prepare a branch for an older version of the provider following the
+`mixed governance model `_
+and requires interested parties to cherry-pick and test the fixes.
diff --git a/docs/apache-airflow/extra-packages-ref.rst b/docs/apache-airflow/extra-packages-ref.rst
index c24fe2d437278..1fd5e157f6a60 100644
--- a/docs/apache-airflow/extra-packages-ref.rst
+++ b/docs/apache-airflow/extra-packages-ref.rst
@@ -301,6 +301,8 @@ These are extras that provide support for integration with external systems via
+---------------------+-----------------------------------------------------+--------------------------------------+--------------+
| openlineage | ``pip install 'apache-airflow[openlineage]'`` | Sending OpenLineage events | |
+---------------------+-----------------------------------------------------+--------------------------------------+--------------+
+| opensearch | ``pip install 'apache-airflow[opensearch]'`` | Opensearch hooks and operators | |
++---------------------+-----------------------------------------------------+--------------------------------------+--------------+
| papermill | ``pip install 'apache-airflow[papermill]'`` | Papermill hooks and operators | |
+---------------------+-----------------------------------------------------+--------------------------------------+--------------+
| sftp | ``pip install 'apache-airflow[sftp]'`` | SFTP hooks, operators and sensors | |
diff --git a/docs/integration-logos/opensearch/opensearch.png b/docs/integration-logos/opensearch/opensearch.png
new file mode 100644
index 0000000000000..a51d300b3bb83
Binary files /dev/null and b/docs/integration-logos/opensearch/opensearch.png differ
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 14d7d52dd0737..b37bdf3c2277a 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1054,6 +1054,8 @@ Oozie
openapi
openfaas
openlineage
+OpenSearch
+opensearch
oper
OperatorLineage
Opsgenie
diff --git a/generated/provider_dependencies.json b/generated/provider_dependencies.json
index 3185f825abe0b..1a8c9c3a89c69 100644
--- a/generated/provider_dependencies.json
+++ b/generated/provider_dependencies.json
@@ -667,6 +667,14 @@
],
"excluded-python-versions": []
},
+ "opensearch": {
+ "deps": [
+ "apache-airflow>=2.5.0",
+ "opensearch-py>=2.2.0"
+ ],
+ "cross-providers-deps": [],
+ "excluded-python-versions": []
+ },
"opsgenie": {
"deps": [
"apache-airflow>=2.5.0",
diff --git a/images/breeze/output-commands-hash.txt b/images/breeze/output-commands-hash.txt
index b01b168832a08..18bd1a776e473 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:c97d8a728bb02c2be73002c4b39d0829
-build-docs:c5da2956cfff3989a9699c32aee63a13
+build-docs:27f59f285448615a47ee2ee22645ef2b
ci:find-backtracking-candidates:17fe56b867a745e5032a08dfcd3f73ee
ci:fix-ownership:3e5a73533cc96045e72cb258783cfc96
ci:free-space:49af17b032039c05c41a7a8283f365cc
@@ -36,25 +36,25 @@ prod-image:build:20f84ddadc2fe4ae2723b7ccdde0197f
prod-image:pull:3817ef211b023b76df84ee1110ef64dd
prod-image:verify:bd2b78738a7c388dbad6076c41a9f906
prod-image:e9ecd759e51ebd926df3170b29d1d2dc
-release-management:add-back-references:6da27012538a7cc79ddd4ec650470470
+release-management:add-back-references:298fd8d5dd342a076037e996f39ba371
release-management:create-minor-branch:a3834afc4aa5d1e98002c9e9e7a9931d
release-management:generate-constraints:01aef235b11e59ed7f10c970a5cdaba7
-release-management:generate-issue-content-providers:756d5dfd135c3e473756022ca6150c24
+release-management:generate-issue-content-providers:19c4c98c30b820685e5775a5396aebdf
release-management:generate-providers-metadata:d4e8e5cfaa024e3963af02d7a873048d
release-management:install-provider-packages:34c38aca17d23dbb454fe7a6bfd8e630
release-management:prepare-airflow-package:85d01c57e5b5ee0fb9e5f9d9706ed3b5
-release-management:prepare-provider-documentation:a53cd338bd719c77108b53bc8d45b634
-release-management:prepare-provider-packages:fc69d2ab8abdcbafcaaa63da380f4b76
-release-management:publish-docs:45a6ea090bfcf564ea0dd8fc61655d8a
+release-management:prepare-provider-documentation:d0dbef40ff62a19c966889f3735e747c
+release-management:prepare-provider-packages:5a87973bd373d20b6881f6fd62fbeb05
+release-management:publish-docs:130b14797fc4cd5f33d39c8277584f1c
release-management:release-prod-images:cfbfe8b19fee91fd90718f98ef2fd078
release-management:start-rc-process:b27bd524dd3c89f50a747b60a7e892c1
release-management:start-release:419f48f6a4ff4457cb9de7ff496aebbe
release-management:update-constraints:02ec4b119150e3fdbac52026e94820ef
release-management:verify-provider-packages:96dce5644aad6b37080acf77b3d8de3a
-release-management:885a5fe8a39a3773011cf1f9bd2983ad
-sbom:generate-providers-requirements:f8328b801efa7908d5b14b25a0097c4d
+release-management:856c346e8ec1cf320f656bcfe0af7451
+sbom:generate-providers-requirements:51e0c660a5f7846ada099e871ebd4c67
sbom:update-sbom-information:653be48be70b4b7ff5172d491aadc694
-sbom:104afc4ac8c007dcd99218d1b040047e
+sbom:b98ded4bbb76f0cb205cea32f3102aee
setup:autocomplete:fffcd49e102e09ccd69b3841a9e3ea8e
setup:check-all-params-in-groups:7aa55fa1b0f17a6f7b7ca225c6b82574
setup:config:aaff9748d0970f7cb02e592ac4046d5d
diff --git a/images/breeze/output_build-docs.svg b/images/breeze/output_build-docs.svg
index 1e801afbf58c4..71e474fd5caf4 100644
--- a/images/breeze/output_build-docs.svg
+++ b/images/breeze/output_build-docs.svg
@@ -1,4 +1,4 @@
-