44from pathlib import Path
55
66import requests
7+ from pydantic import BaseModel
78
89from localstack import config , constants
910from localstack .utils .catalog .common import AwsRemoteCatalog
11+ from localstack .utils .http import get_proxies
1012from localstack .utils .json import FileMappedDocument
1113
1214LOG = logging .getLogger (__name__ )
1315
1416AWS_CATALOG_FILE_NAME = "aws_catalog.json"
1517
1618
19+ class RemoteCatalogVersionResponse (BaseModel ):
20+ emulator_type : str
21+ version : str
22+
23+
1724class AwsCatalogLoaderException (Exception ):
1825 def __init__ (self , msg : str , * args ):
1926 super ().__init__ (msg , * args )
@@ -36,7 +43,20 @@ def get_remote_catalog(self) -> AwsRemoteCatalog:
3643 return catalog
3744
3845 def _get_latest_localstack_version (self ) -> str :
39- pass
46+ try :
47+ proxies = get_proxies ()
48+ response = requests .get (
49+ f"{ self .api_endpoint_catalog } /aws/version" ,
50+ verify = not config .is_env_true ("SSL_NO_VERIFY" ),
51+ proxies = proxies ,
52+ )
53+ if response .ok :
54+ return RemoteCatalogVersionResponse .model_validate (response .content ).version
55+ self ._raise_server_error (response )
56+ except requests .exceptions .RequestException as e :
57+ raise AwsCatalogLoaderException (
58+ f"An unexpected network error occurred when trying to fetch latest localstack version: { e } "
59+ ) from e
4060
4161 def _should_update_cached_catalog (self , current_catalog_version : str ) -> bool :
4262 try :
@@ -55,10 +75,6 @@ def _save_catalog_to_cache(self, catalog_doc: FileMappedDocument, catalog: AwsRe
5575 catalog_doc .save ()
5676
5777 def _get_catalog_from_platform (self ) -> AwsRemoteCatalog :
58- import requests
59-
60- from localstack .utils .http import get_proxies
61-
6278 try :
6379 proxies = get_proxies ()
6480 response = requests .post (
@@ -80,7 +96,7 @@ def _parse_catalog(self, document: bytes) -> AwsRemoteCatalog | None:
8096 catalog_json = json .loads (document )
8197 except JSONDecodeError as e :
8298 raise AwsCatalogLoaderException (f"Could not de-serialize json catalog: { e } " ) from e
83- remote_catalog = AwsRemoteCatalog ( ** catalog_json )
99+ remote_catalog = AwsRemoteCatalog . model_validate ( catalog_json )
84100 if remote_catalog .schema_version != self .supported_schema_version :
85101 raise AwsCatalogLoaderException (
86102 f"Unsupported schema version: '{ remote_catalog .schema_version } '. Only '{ self .supported_schema_version } ' is supported"
@@ -90,15 +106,14 @@ def _parse_catalog(self, document: bytes) -> AwsRemoteCatalog | None:
90106 def _raise_server_error (self , response : requests .Response ):
91107 try :
92108 server_error = response .json ()
93- if not server_error .get ("message" ):
109+ if error_message := server_error .get ("message" ):
94110 raise AwsCatalogLoaderException (
95111 f"Unexpected AWS catalog server error: { response .text } "
96112 )
97- message = server_error ["message" ]
98113 raise AwsCatalogLoaderException (
99- f"An unexpected server error occurred when trying to fetch remote catalog: { message } "
114+ f"A server error occurred while calling remote catalog API (HTTP { response . status_code } ) : { error_message } "
100115 )
101116 except Exception :
102117 raise AwsCatalogLoaderException (
103- f"An unexpected server error occurred when trying to fetch remote catalog: { response .text } "
118+ f"An unexpected server error occurred while calling remote catalog API (HTTP { response . status_code } ) : { response .text } "
104119 )
0 commit comments