Skip to content

Commit

Permalink
Add hashi-vault-engine-name parameter (#399)
Browse files Browse the repository at this point in the history
* Add hashi-vault-engine-name parameter

Signed-off-by: eiabea <developer@eiabea.com>

* Remove cloudflare from default ipfs gateways (#400)

Signed-off-by: cyc60 <avsysoev60@gmail.com>

* Run linters

Signed-off-by: cyc60 <avsysoev60@gmail.com>

* Review fix

Signed-off-by: cyc60 <avsysoev60@gmail.com>

* Add wallet error hint (#401)

Signed-off-by: cyc60 <avsysoev60@gmail.com>

---------

Signed-off-by: eiabea <developer@eiabea.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Co-authored-by: Alexander Sysoev <avsysoev60@gmail.com>
  • Loading branch information
eiabea and cyc60 authored Aug 27, 2024
1 parent 687a0da commit 9b831ec
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 5 deletions.
14 changes: 13 additions & 1 deletion src/commands/validators_exit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
from src.common.validators import validate_eth_address
from src.common.vault_config import VaultConfig
from src.config.networks import AVAILABLE_NETWORKS
from src.config.settings import DEFAULT_HASHI_VAULT_PARALLELISM, settings
from src.config.settings import (
DEFAULT_HASHI_VAULT_ENGINE_NAME,
DEFAULT_HASHI_VAULT_PARALLELISM,
settings,
)
from src.validators.keystores.base import BaseKeystore
from src.validators.keystores.load import load_keystore

Expand Down Expand Up @@ -77,6 +81,12 @@ class ValidatorExit:
envvar='HASHI_VAULT_URL',
help='The base URL of the vault service, e.g. http://vault:8200.',
)
@click.option(
'--hashi-vault-engine-name',
envvar='HASHI_VAULT_ENGINE_NAME',
help='The name of the secret engine, e.g. keystores',
default=DEFAULT_HASHI_VAULT_ENGINE_NAME,
)
@click.option(
'--hashi-vault-token',
envvar='HASHI_VAULT_TOKEN',
Expand Down Expand Up @@ -128,6 +138,7 @@ def validators_exit(
hashi_vault_key_path: list[str] | None,
hashi_vault_token: str | None,
hashi_vault_url: str | None,
hashi_vault_engine_name: str,
hashi_vault_parallelism: int,
data_dir: str,
verbose: bool,
Expand All @@ -149,6 +160,7 @@ def validators_exit(
hashi_vault_token=hashi_vault_token,
hashi_vault_key_paths=hashi_vault_key_path,
hashi_vault_url=hashi_vault_url,
hashi_vault_engine_name=hashi_vault_engine_name,
hashi_vault_parallelism=hashi_vault_parallelism,
verbose=verbose,
log_level=log_level,
Expand Down
4 changes: 4 additions & 0 deletions src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
DEFAULT_MIN_VALIDATORS_REGISTRATION = 1

DEFAULT_HASHI_VAULT_PARALLELISM = 8
DEFAULT_HASHI_VAULT_ENGINE_NAME = 'secret'


# pylint: disable-next=too-many-public-methods,too-many-instance-attributes
Expand Down Expand Up @@ -50,6 +51,7 @@ class Settings(metaclass=Singleton):
dappnode: bool = False
hashi_vault_key_paths: list[str] | None
hashi_vault_url: str | None
hashi_vault_engine_name: str
hashi_vault_token: str | None
hashi_vault_parallelism: int
hot_wallet_file: Path
Expand Down Expand Up @@ -111,6 +113,7 @@ def set(
dappnode: bool = False,
hashi_vault_key_paths: list[str] | None = None,
hashi_vault_url: str | None = None,
hashi_vault_engine_name: str = DEFAULT_HASHI_VAULT_ENGINE_NAME,
hashi_vault_token: str | None = None,
hashi_vault_parallelism: int = DEFAULT_HASHI_VAULT_PARALLELISM,
hot_wallet_file: str | None = None,
Expand Down Expand Up @@ -167,6 +170,7 @@ def set(
raise RuntimeError('Found duplicate addresses in hashi vault key paths')

self.hashi_vault_url = hashi_vault_url
self.hashi_vault_engine_name = hashi_vault_engine_name
self.hashi_vault_key_paths = hashi_vault_key_paths
self.hashi_vault_token = hashi_vault_token
self.hashi_vault_parallelism = hashi_vault_parallelism
Expand Down
6 changes: 6 additions & 0 deletions src/test_fixtures/hashi_vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ def _mocked_error_path(url, **kwargs) -> CallbackResult:
callback=partial(_mocked_secret_path, _hashi_vault_pk_sk_mapping_2),
repeat=True,
)
# Mocked signing keys endpoints with custom engine name
m.get(
f'{hashi_vault_url}/v1/custom/data/ethereum/signing/keystores',
callback=partial(_mocked_secret_path, _hashi_vault_pk_sk_mapping_1),
repeat=True,
)
# Mocked inacessible signing keys endpoint
m.get(
f'{hashi_vault_url}/v1/secret/data/ethereum/inaccessible/keystores',
Expand Down
7 changes: 5 additions & 2 deletions src/validators/keystores/hashi_vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
class HashiVaultConfiguration:
token: str
url: str
engine_name: str
key_paths: list[str]
parallelism: int

Expand All @@ -36,14 +37,15 @@ def from_settings(cls) -> 'HashiVaultConfiguration':
return cls(
token=settings.hashi_vault_token,
url=settings.hashi_vault_url,
engine_name=settings.hashi_vault_engine_name,
key_paths=settings.hashi_vault_key_paths,
parallelism=settings.hashi_vault_parallelism,
)

def secret_url(self, key_path: str) -> str:
return urllib.parse.urljoin(
self.url,
f'/v1/secret/data/{key_path}',
f'/v1/{self.engine_name}/data/{key_path}',
)


Expand All @@ -66,7 +68,8 @@ async def load() -> 'HashiVaultKeystore':
keys_responses = await asyncio.gather(
*[
HashiVaultKeystore._load_hashi_vault_keys(
session=session, secret_url=hashi_vault_config.secret_url(key_path)
session=session,
secret_url=hashi_vault_config.secret_url(key_path),
)
for key_path in key_chunk
]
Expand Down
33 changes: 31 additions & 2 deletions src/validators/keystores/tests/test_hashi_vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async def test_hashi_vault_keystores_loading(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_paths = []
settings.hashi_vault_parallelism = 1
Expand All @@ -23,7 +24,8 @@ async def test_hashi_vault_keystores_loading(

async with ClientSession() as session:
keystore = await HashiVaultKeystore._load_hashi_vault_keys(
session=session, secret_url=config.secret_url('ethereum/signing/keystores')
session=session,
secret_url=config.secret_url('ethereum/signing/keystores'),
)

assert len(keystore) == 2
Expand All @@ -34,6 +36,7 @@ async def test_hashi_vault_keystores_not_configured(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = None
settings.hashi_vault_key_path = None
settings.hashi_vault_parallelism = 1
Expand All @@ -47,6 +50,7 @@ async def test_hashi_vault_keystores_inaccessible(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_path = []
settings.hashi_vault_parallelism = 1
Expand All @@ -57,7 +61,8 @@ async def test_hashi_vault_keystores_inaccessible(
config = HashiVaultConfiguration.from_settings()
async with ClientSession() as session:
await HashiVaultKeystore._load_hashi_vault_keys(
session=session, secret_url=config.secret_url('ethereum/inaccessible/keystores')
session=session,
secret_url=config.secret_url('ethereum/inaccessible/keystores'),
)

@pytest.mark.usefixtures('mocked_hashi_vault')
Expand All @@ -66,6 +71,7 @@ async def test_hashi_vault_keystores_parallel(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_paths = [
'ethereum/signing/keystores',
Expand All @@ -84,6 +90,7 @@ async def test_hashi_vault_keystores_sequential(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_paths = [
'ethereum/signing/keystores',
Expand All @@ -102,6 +109,7 @@ async def test_hashi_vault_duplicates_parallel(
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'secret'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_paths = [
'ethereum/signing/keystores',
Expand All @@ -112,3 +120,24 @@ async def test_hashi_vault_duplicates_parallel(
keystore = HashiVaultKeystore({})
with pytest.raises(RuntimeError, match='Found duplicate key in path'):
await keystore.load()

@pytest.mark.usefixtures('mocked_hashi_vault')
async def test_hashi_vault_keystores_loading_custom_engine_name(
self,
hashi_vault_url: str,
):
settings.hashi_vault_url = hashi_vault_url
settings.hashi_vault_engine_name = 'custom'
settings.hashi_vault_token = 'Secret'
settings.hashi_vault_key_paths = []
settings.hashi_vault_parallelism = 1

config = HashiVaultConfiguration.from_settings()

async with ClientSession() as session:
keystore = await HashiVaultKeystore._load_hashi_vault_keys(
session=session,
secret_url=config.secret_url('ethereum/signing/keystores'),
)

assert len(keystore) == 2

0 comments on commit 9b831ec

Please sign in to comment.