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 @@ - +