diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index caeae818..e63b5097 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: services: elasticsearch_8_svc: - image: docker.elastic.co/elasticsearch/elasticsearch:8.10.4 + image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0 env: cluster.name: stac-cluster node.name: es01 diff --git a/CHANGELOG.md b/CHANGELOG.md index d50d6ff9..66dd8d67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed +- Elasticsearch drivers from 7.17.9 to 8.11.0 [#169](https://github.com/stac-utils/stac-fastapi-elasticsearch/pull/169) + ### Fixed - Exclude unset fields in search response [#166](https://github.com/stac-utils/stac-fastapi-elasticsearch/issues/166) diff --git a/docker-compose.yml b/docker-compose.yml index 1cad4dee..db3352fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,7 @@ services: elasticsearch: container_name: es-container - image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTICSEARCH_VERSION:-8.10.4} + image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTICSEARCH_VERSION:-8.11.0} environment: ES_JAVA_OPTS: -Xms512m -Xmx1g volumes: diff --git a/stac_fastapi/elasticsearch/setup.py b/stac_fastapi/elasticsearch/setup.py index 6ff8cd86..c0f941f0 100644 --- a/stac_fastapi/elasticsearch/setup.py +++ b/stac_fastapi/elasticsearch/setup.py @@ -13,8 +13,8 @@ "stac-fastapi.types==2.4.8", "stac-fastapi.api==2.4.8", "stac-fastapi.extensions==2.4.8", - "elasticsearch[async]==7.17.9", - "elasticsearch-dsl==7.4.1", + "elasticsearch[async]==8.11.0", + "elasticsearch-dsl==8.11.0", "pystac[validation]", "uvicorn", "orjson", diff --git a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py index e1630d67..8634d3b9 100644 --- a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py +++ b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py @@ -1,5 +1,6 @@ """API configuration.""" import os +import ssl from typing import Any, Dict, Set from elasticsearch import AsyncElasticsearch, Elasticsearch # type: ignore @@ -7,24 +8,36 @@ def _es_config() -> Dict[str, Any]: + # Determine the scheme (http or https) + use_ssl = os.getenv("ES_USE_SSL", "true").lower() == "true" + scheme = "https" if use_ssl else "http" + + # Configure the hosts parameter with the correct scheme + hosts = [f"{scheme}://{os.getenv('ES_HOST')}:{os.getenv('ES_PORT')}"] + + # Initialize the configuration dictionary config = { - "hosts": [{"host": os.getenv("ES_HOST"), "port": os.getenv("ES_PORT")}], + "hosts": hosts, "headers": {"accept": "application/vnd.elasticsearch+json; compatible-with=7"}, - "use_ssl": True, - "verify_certs": True, } - if (u := os.getenv("ES_USER")) and (p := os.getenv("ES_PASS")): - config["http_auth"] = (u, p) + # Explicitly exclude SSL settings when not using SSL + if not use_ssl: + return config - if (v := os.getenv("ES_USE_SSL")) and v == "false": - config["use_ssl"] = False + # Include SSL settings if using https + config["ssl_version"] = ssl.TLSVersion.TLSv1_3 # type: ignore + config["verify_certs"] = os.getenv("ES_VERIFY_CERTS", "true").lower() != "false" # type: ignore - if (v := os.getenv("ES_VERIFY_CERTS")) and v == "false": - config["verify_certs"] = False + # Include CA Certificates if verifying certs + if config["verify_certs"]: + config["ca_certs"] = os.getenv( + "CURL_CA_BUNDLE", "/etc/ssl/certs/ca-certificates.crt" + ) - if v := os.getenv("CURL_CA_BUNDLE"): - config["ca_certs"] = v + # Handle authentication + if (u := os.getenv("ES_USER")) and (p := os.getenv("ES_PASS")): + config["http_auth"] = (u, p) return config diff --git a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py index 6b2cd433..4554e74c 100644 --- a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py +++ b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py @@ -170,18 +170,19 @@ def indices(collection_ids: Optional[List[str]]) -> str: async def create_collection_index() -> None: - """Create the index for Collections in Elasticsearch. + """ + Create the index for a Collection. + + Returns: + None - This function creates the Elasticsearch index for the `Collections` with the predefined mapping. - If the index already exists, the function ignores the error and continues execution. """ client = AsyncElasticsearchSettings().create_client - await client.indices.create( + await client.options(ignore_status=400).indices.create( index=f"{COLLECTIONS_INDEX}-000001", aliases={COLLECTIONS_INDEX: {}}, mappings=ES_COLLECTIONS_MAPPINGS, - ignore=400, # ignore 400 already exists code ) await client.close() @@ -200,12 +201,11 @@ async def create_item_index(collection_id: str): client = AsyncElasticsearchSettings().create_client index_name = index_by_collection_id(collection_id) - await client.indices.create( + await client.options(ignore_status=400).indices.create( index=f"{index_by_collection_id(collection_id)}-000001", aliases={index_name: {}}, mappings=ES_ITEMS_MAPPINGS, settings=ES_ITEMS_SETTINGS, - ignore=400, # ignore 400 already exists code ) await client.close() diff --git a/stac_fastapi/elasticsearch/tests/api/test_api.py b/stac_fastapi/elasticsearch/tests/api/test_api.py index c50256da..74f0bb55 100644 --- a/stac_fastapi/elasticsearch/tests/api/test_api.py +++ b/stac_fastapi/elasticsearch/tests/api/test_api.py @@ -363,6 +363,7 @@ async def test_search_polygon_intersects_get(app_client, ctx): assert len(resp_json["features"]) == 1 +@pytest.mark.asyncio async def test_search_point_intersects_post(app_client, ctx): point = [150.04, -33.14] intersects = {"type": "Point", "coordinates": point}