Skip to content

Commit e9689c3

Browse files
authored
[FSTORE-368] Remove code for secret store / parameter store from the hsfs APIs (logicalclocks#248)
* Remove code for secret store / parameter store from the hsfs APIs * Fix locust_benchmark * Remove unused constants from client.external * Remove _get_secret from client.external
1 parent 5a1b4df commit e9689c3

File tree

8 files changed

+16
-149
lines changed

8 files changed

+16
-149
lines changed

locust_benchmark/common/hopsworks_client.py

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ def __init__(self, environment=None):
2626
host=self.hopsworks_config.get("host", "localhost"),
2727
port=self.hopsworks_config.get("port", 443),
2828
api_key_file=".api_key",
29-
secrets_store="local",
3029
engine="python",
3130
)
3231
self.fs = self.connection.get_feature_store()

python/hopsworks/connection.py

-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,6 @@ def connect(self):
245245
self._port,
246246
self._project,
247247
None,
248-
None,
249-
None,
250248
self._hostname_verification,
251249
self._trust_store_path,
252250
self._cert_folder,

python/hopsworks_common/client/__init__.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ def init(
3131
port: Optional[int] = None,
3232
project: Optional[str] = None,
3333
engine: Optional[str] = None,
34-
region_name: Optional[str] = None,
35-
secrets_store=None,
3634
hostname_verification: Optional[bool] = None,
3735
trust_store_path: Optional[str] = None,
3836
cert_folder: Optional[str] = None,
@@ -49,16 +47,14 @@ def init(
4947
port,
5048
project,
5149
engine,
52-
region_name,
53-
secrets_store,
5450
hostname_verification,
5551
trust_store_path,
5652
cert_folder,
5753
api_key_file,
5854
api_key_value,
5955
)
6056
elif isinstance(_client, external.Client) and not _client._project_name:
61-
_client._hsfs_post_init(project, engine, region_name)
57+
_client._hsfs_post_init(project, engine)
6258

6359

6460
def get_instance() -> Union[hopsworks.Client, external.Client]:

python/hopsworks_common/client/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ def _get_verify(self, verify, trust_store_path):
5454
5555
Credit to https://gist.github.com/gdamjan/55a8b9eec6cf7b771f92021d93b87b2c
5656
57-
:param verify: perform hostname verification, 'true' or 'false'
58-
:type verify: str
57+
:param verify: perform hostname verification
58+
:type verify: bool
5959
:param trust_store_path: path of the truststore locally if it was uploaded manually to
6060
the external environment such as AWS Sagemaker
6161
:type trust_store_path: str
@@ -64,7 +64,7 @@ def _get_verify(self, verify, trust_store_path):
6464
if verify is false, then return false
6565
:rtype: str or boolean
6666
"""
67-
if verify == "true":
67+
if verify:
6868
if trust_store_path is not None:
6969
return trust_store_path
7070
else:

python/hopsworks_common/client/external.py

+6-95
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717
from __future__ import annotations
1818

1919
import base64
20-
import json
2120
import logging
2221
import os
2322

24-
import boto3
2523
import requests
2624
from hopsworks_common.client import auth, base, exceptions
2725
from hopsworks_common.client.exceptions import FeatureStoreException
@@ -37,19 +35,12 @@
3735

3836

3937
class Client(base.Client):
40-
DEFAULT_REGION = "default"
41-
SECRETS_MANAGER = "secretsmanager"
42-
PARAMETER_STORE = "parameterstore"
43-
LOCAL_STORE = "local"
44-
4538
def __init__(
4639
self,
4740
host,
4841
port,
4942
project,
5043
engine,
51-
region_name,
52-
secrets_store,
5344
hostname_verification,
5445
trust_store_path,
5546
cert_folder,
@@ -65,17 +56,14 @@ def __init__(
6556
self._port = port
6657
self._base_url = "https://" + self._host + ":" + str(self._port)
6758
_logger.info("Base URL: %s", self._base_url)
68-
self._region_name = region_name or self.DEFAULT_REGION
69-
_logger.debug("Region name: %s", self._region_name)
7059

7160
if api_key_value is not None:
7261
_logger.debug("Using provided API key value")
7362
api_key = api_key_value
7463
else:
75-
_logger.debug("Querying secrets store for API key")
76-
if secrets_store is None:
77-
secrets_store = self.LOCAL_STORE
78-
api_key = self._get_secret(secrets_store, "api-key", api_key_file)
64+
_logger.debug(f"Reading api key from {api_key_file}")
65+
with open(api_key_file) as f:
66+
api_key = f.readline().strip()
7967

8068
_logger.debug("Using api key to setup header authentification")
8169
self._auth = auth.ApiKeyAuth(api_key)
@@ -84,17 +72,16 @@ def __init__(
8472
self._session = requests.session()
8573
self._connected = True
8674

87-
self._verify = self._get_verify(self._host, trust_store_path)
75+
self._verify = self._get_verify(hostname_verification, trust_store_path)
8876
_logger.debug("Verify: %s", self._verify)
8977

9078
self._cert_key = None
9179
self._cert_folder_base = cert_folder
9280
self._cert_folder = None
9381

94-
self._hsfs_post_init(project, engine, region_name)
82+
self._hsfs_post_init(project, engine)
9583

96-
def _hsfs_post_init(self, project, engine, region_name):
97-
self._region_name = region_name or self._region_name or self.DEFAULT_REGION
84+
def _hsfs_post_init(self, project, engine):
9885
self._project_name = project
9986
if project is not None:
10087
project_info = self._get_project_info(project)
@@ -295,82 +282,6 @@ def _get_client_key_path(self, project_name=None) -> str:
295282
_logger.debug(f"Getting client key path {path}")
296283
return path
297284

298-
def _get_secret(self, secrets_store, secret_key=None, api_key_file=None):
299-
"""Returns secret value from the AWS Secrets Manager or Parameter Store.
300-
301-
:param secrets_store: the underlying secrets storage to be used, e.g. `secretsmanager` or `parameterstore`
302-
:type secrets_store: str
303-
:param secret_key: key for the secret value, e.g. `api-key`, `cert-key`, `trust-store`, `key-store`, defaults to None
304-
:type secret_key: str, optional
305-
:param api_key_file: path to a file containing an api key, defaults to None
306-
:type api_key_file: str optional
307-
:raises hsfs.client.exceptions.ExternalClientError: `api_key_file` needs to be set for local mode
308-
:raises hsfs.client.exceptions.UnknownSecretStorageError: Provided secrets storage not supported
309-
:return: secret
310-
:rtype: str
311-
"""
312-
_logger.debug(f"Querying secrets store {secrets_store} for secret {secret_key}")
313-
if secrets_store == self.SECRETS_MANAGER:
314-
return self._query_secrets_manager(secret_key)
315-
elif secrets_store == self.PARAMETER_STORE:
316-
return self._query_parameter_store(secret_key)
317-
elif secrets_store == self.LOCAL_STORE:
318-
if not api_key_file:
319-
raise exceptions.ExternalClientError(
320-
"api_key_file needs to be set for local mode"
321-
)
322-
_logger.debug(f"Reading api key from {api_key_file}")
323-
with open(api_key_file) as f:
324-
return f.readline().strip()
325-
else:
326-
raise exceptions.UnknownSecretStorageError(
327-
"Secrets storage " + secrets_store + " is not supported."
328-
)
329-
330-
def _query_secrets_manager(self, secret_key):
331-
_logger.debug("Querying secrets manager for secret key: %s", secret_key)
332-
secret_name = "hopsworks/role/" + self._assumed_role()
333-
args = {"service_name": "secretsmanager"}
334-
region_name = self._get_region()
335-
if region_name:
336-
args["region_name"] = region_name
337-
client = boto3.client(**args)
338-
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
339-
return json.loads(get_secret_value_response["SecretString"])[secret_key]
340-
341-
def _assumed_role(self):
342-
_logger.debug("Getting assumed role")
343-
client = boto3.client("sts")
344-
response = client.get_caller_identity()
345-
# arns for assumed roles in SageMaker follow the following schema
346-
# arn:aws:sts::123456789012:assumed-role/my-role-name/my-role-session-name
347-
local_identifier = response["Arn"].split(":")[-1].split("/")
348-
if len(local_identifier) != 3 or local_identifier[0] != "assumed-role":
349-
raise Exception(
350-
"Failed to extract assumed role from arn: " + response["Arn"]
351-
)
352-
return local_identifier[1]
353-
354-
def _get_region(self):
355-
if self._region_name != self.DEFAULT_REGION:
356-
_logger.debug(f"Region name is not default, returning {self._region_name}")
357-
return self._region_name
358-
else:
359-
_logger.debug("Region name is default, returning None")
360-
return None
361-
362-
def _query_parameter_store(self, secret_key):
363-
_logger.debug("Querying parameter store for secret key: %s", secret_key)
364-
args = {"service_name": "ssm"}
365-
region_name = self._get_region()
366-
if region_name:
367-
args["region_name"] = region_name
368-
client = boto3.client(**args)
369-
name = "/hopsworks/role/" + self._assumed_role() + "/type/" + secret_key
370-
return client.get_parameter(Name=name, WithDecryption=True)["Parameter"][
371-
"Value"
372-
]
373-
374285
def _get_project_info(self, project_name):
375286
"""Makes a REST call to hopsworks to get all metadata of a project for the provided project.
376287

python/hopsworks_common/client/hopsworks.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ def __init__(self):
5454
self._cert_key = self._get_cert_pw()
5555
trust_store_path = self._get_trust_store_path()
5656
hostname_verification = (
57-
os.environ[self.REQUESTS_VERIFY]
57+
os.environ[self.REQUESTS_VERIFY] == "true"
5858
if self.REQUESTS_VERIFY in os.environ
59-
else "true"
59+
else True
6060
)
6161
self._project_id = os.environ[self.PROJECT_ID]
6262
self._project_name = self._project_name()

python/hsfs/connection.py

+4-39
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
from requests.exceptions import ConnectionError
3333

3434

35-
AWS_DEFAULT_REGION = "default"
3635
HOPSWORKS_PORT_DEFAULT = 443
37-
SECRETS_STORE_DEFAULT = "parameterstore"
3836
HOSTNAME_VERIFICATION_DEFAULT = True
3937
CERT_FOLDER_DEFAULT = "/tmp"
4038

@@ -58,7 +56,7 @@ class Connection:
5856
```
5957
6058
!!! hint "Save API Key as File"
61-
To get started quickly, without saving the Hopsworks API in a secret storage,
59+
To get started quickly,
6260
you can simply create a file with the previously created Hopsworks API Key and
6361
place it on the environment from which you wish to connect to the Hopsworks
6462
Feature Store.
@@ -105,19 +103,14 @@ class Connection:
105103
allows you to override this behaviour. `"training"` engine is useful when only
106104
feature store metadata is needed, for example training dataset location and label
107105
information when Hopsworks training experiment is conducted.
108-
region_name: The name of the AWS region in which the required secrets are
109-
stored, defaults to `"default"`.
110-
secrets_store: The secrets storage to be used, either `"secretsmanager"`,
111-
`"parameterstore"` or `"local"`, defaults to `"parameterstore"`.
112-
hostname_verification: Whether or not to verify Hopsworks’ certificate, defaults
106+
hostname_verification: Whether or not to verify Hopsworks' certificate, defaults
113107
to `True`.
114108
trust_store_path: Path on the file system containing the Hopsworks certificates,
115109
defaults to `None`.
116110
cert_folder: The directory to store retrieved HopsFS certificates, defaults to
117111
`"/tmp"`. Only required when running without a Spark environment.
118-
api_key_file: Path to a file containing the API Key, if provided,
119-
`secrets_store` will be ignored, defaults to `None`.
120-
api_key_value: API Key as string, if provided, `secrets_store` will be ignored`,
112+
api_key_file: Path to a file containing the API Key, defaults to `None`.
113+
api_key_value: API Key as string, if provided, `api_key_file` will be ignored,
121114
however, this should be used with care, especially if the used notebook or
122115
job script is accessible by multiple parties. Defaults to `None`.
123116
@@ -132,8 +125,6 @@ def __init__(
132125
port: int = HOPSWORKS_PORT_DEFAULT,
133126
project: Optional[str] = None,
134127
engine: Optional[str] = None,
135-
region_name: str = AWS_DEFAULT_REGION,
136-
secrets_store: str = SECRETS_STORE_DEFAULT,
137128
hostname_verification: bool = HOSTNAME_VERIFICATION_DEFAULT,
138129
trust_store_path: Optional[str] = None,
139130
cert_folder: str = CERT_FOLDER_DEFAULT,
@@ -144,8 +135,6 @@ def __init__(
144135
self._port = port
145136
self._project = project
146137
self._engine = engine
147-
self._region_name = region_name
148-
self._secrets_store = secrets_store
149138
self._hostname_verification = hostname_verification
150139
self._trust_store_path = trust_store_path
151140
self._cert_folder = cert_folder
@@ -240,8 +229,6 @@ def connect(self) -> None:
240229
self._port,
241230
self._project,
242231
self._engine,
243-
self._region_name,
244-
self._secrets_store,
245232
self._hostname_verification,
246233
self._trust_store_path,
247234
self._cert_folder,
@@ -295,8 +282,6 @@ def connection(
295282
port: int = HOPSWORKS_PORT_DEFAULT,
296283
project: Optional[str] = None,
297284
engine: Optional[str] = None,
298-
region_name: str = AWS_DEFAULT_REGION,
299-
secrets_store: str = SECRETS_STORE_DEFAULT,
300285
hostname_verification: bool = HOSTNAME_VERIFICATION_DEFAULT,
301286
trust_store_path: Optional[str] = None,
302287
cert_folder: str = CERT_FOLDER_DEFAULT,
@@ -309,8 +294,6 @@ def connection(
309294
port,
310295
project,
311296
engine,
312-
region_name,
313-
secrets_store,
314297
hostname_verification,
315298
trust_store_path,
316299
cert_folder,
@@ -345,24 +328,6 @@ def project(self) -> Optional[str]:
345328
def project(self, project: Optional[str]) -> str:
346329
self._project = project
347330

348-
@property
349-
def region_name(self) -> str:
350-
return self._region_name
351-
352-
@region_name.setter
353-
@not_connected
354-
def region_name(self, region_name: str) -> None:
355-
self._region_name = region_name
356-
357-
@property
358-
def secrets_store(self) -> str:
359-
return self._secrets_store
360-
361-
@secrets_store.setter
362-
@not_connected
363-
def secrets_store(self, secrets_store):
364-
self._secrets_store = secrets_store
365-
366331
@property
367332
def hostname_verification(self):
368333
return self._hostname_verification

python/hsml/connection.py

-2
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ def connect(self):
175175
self._port,
176176
self._project,
177177
None,
178-
None,
179-
None,
180178
self._hostname_verification,
181179
self._trust_store_path,
182180
None,

0 commit comments

Comments
 (0)