Skip to content

Commit

Permalink
Integrate VaultAPI features
Browse files Browse the repository at this point in the history
Include an option to load env vars from Vault
  • Loading branch information
dormant-user committed Feb 15, 2025
1 parent a3da745 commit bf91814
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 119 deletions.
12 changes: 9 additions & 3 deletions docs/genindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -606,9 +606,11 @@ <h2 id="E">E</h2>
</li>
<li><a href="index.html#jarvis.lib.installer.Env">Env (class in jarvis.lib.installer)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.env_loader">env_loader() (in module jarvis.modules.models.classes)</a>
<li><a href="index.html#jarvis.modules.models.classes.env_file_loader">env_file_loader() (in module jarvis.modules.models.classes)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.EnvConfig.Config.env_prefix">env_prefix (jarvis.modules.models.classes.EnvConfig.Config attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.env_vault_loader">env_vault_loader() (in module jarvis.modules.models.classes)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.EnvConfig">EnvConfig (class in jarvis.modules.models.classes)</a>
</li>
Expand Down Expand Up @@ -863,6 +865,8 @@ <h2 id="G">G</h2>
<li><a href="index.html#jarvis.modules.speaker.speak.Speaker.get_english_voices">get_english_voices() (jarvis.modules.speaker.speak.Speaker method)</a>
</li>
<li><a href="index.html#jarvis.api.squire.discover.get_entrypoints">get_entrypoints() (in module jarvis.api.squire.discover)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.get_env">get_env() (in module jarvis.modules.models.classes)</a>
</li>
<li><a href="index.html#jarvis.api.routers.basics.get_favicon">get_favicon() (in module jarvis.api.routers.basics)</a>
</li>
Expand Down Expand Up @@ -895,11 +899,11 @@ <h2 id="G">G</h2>
<li><a href="index.html#jarvis.executors.location.get_location_from_coordinates">get_location_from_coordinates() (in module jarvis.executors.location)</a>
</li>
<li><a href="index.html#jarvis.api.triggers.stock_monitor.StockMonitor.get_prices">get_prices() (jarvis.api.triggers.stock_monitor.StockMonitor method)</a>
</li>
<li><a href="index.html#jarvis.executors.files.get_processes">get_processes() (in module jarvis.executors.files)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.executors.files.get_processes">get_processes() (in module jarvis.executors.files)</a>
</li>
<li><a href="index.html#jarvis.executors.internet.get_public_ip">get_public_ip() (in module jarvis.executors.internet)</a>
</li>
<li><a href="index.html#jarvis.executors.files.get_recognizer">get_recognizer() (in module jarvis.executors.files)</a>
Expand Down Expand Up @@ -1980,6 +1984,8 @@ <h2 id="J">J</h2>
</li>
</ul></li>
<li><a href="index.html#jarvis.api.server.jarvis_api">jarvis_api() (in module jarvis.api.server)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.json_parser">json_parser() (in module jarvis.modules.models.classes)</a>
</li>
</ul></td>
</tr></table>
Expand Down
47 changes: 45 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5664,8 +5664,51 @@ <h1>———-Models———-<a class="headerlink" href="#models" title="Permal
</pre></div>
</div>
<dl class="py function">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.env_loader">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.models.classes.</span></span><span class="sig-name descname"><span class="pre">env_loader</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">key</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><a class="reference internal" href="#jarvis.modules.models.classes.EnvConfig" title="jarvis.modules.models.classes.EnvConfig"><span class="pre">EnvConfig</span></a></span></span><a class="headerlink" href="#jarvis.modules.models.classes.env_loader" title="Permalink to this definition">¶</a></dt>
<dt class="sig sig-object py" id="jarvis.modules.models.classes.get_env">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.models.classes.</span></span><span class="sig-name descname"><span class="pre">get_env</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">key</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Any</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#jarvis.modules.models.classes.get_env" title="Permalink to this definition">¶</a></dt>
<dd><p>Get environment variables with case insensitivity.</p>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.json_parser">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.models.classes.</span></span><span class="sig-name descname"><span class="pre">json_parser</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">secret</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">Any</span></span></span><a class="headerlink" href="#jarvis.modules.models.classes.json_parser" title="Permalink to this definition">¶</a></dt>
<dd><p>JSON parser for environment variables passed via VaultAPI.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>secret</strong> – Receives secret as a string from Vault.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Returns the JSON parsed value.</p>
</dd>
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p>Any</p>
</dd>
</dl>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.env_vault_loader">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.models.classes.</span></span><span class="sig-name descname"><span class="pre">env_vault_loader</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">key</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><a class="reference internal" href="#jarvis.modules.models.classes.EnvConfig" title="jarvis.modules.models.classes.EnvConfig"><span class="pre">jarvis.modules.models.classes.EnvConfig</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span></span><a class="headerlink" href="#jarvis.modules.models.classes.env_vault_loader" title="Permalink to this definition">¶</a></dt>
<dd><p>Load env config by retrieving a DB table.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>key</strong> – Table name env var to look for.</p></li>
<li><p><strong>default</strong> – Default value if table name env var is not found.</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Returns a reference to the <code class="docutils literal notranslate"><span class="pre">EnvConfig</span></code> object.</p>
</dd>
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><a class="reference internal" href="#jarvis.modules.models.classes.EnvConfig" title="jarvis.modules.models.classes.EnvConfig">EnvConfig</a></p>
</dd>
</dl>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.env_file_loader">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.models.classes.</span></span><span class="sig-name descname"><span class="pre">env_file_loader</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">key</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><a class="reference internal" href="#jarvis.modules.models.classes.EnvConfig" title="jarvis.modules.models.classes.EnvConfig"><span class="pre">EnvConfig</span></a></span></span><a class="headerlink" href="#jarvis.modules.models.classes.env_file_loader" title="Permalink to this definition">¶</a></dt>
<dd><p>Loads environment variables based on filetypes.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
Expand Down
Binary file modified docs/objects.inv
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/searchindex.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions jarvis/lib/version_pinned_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pydantic==2.7.*
pydantic-settings==2.3.*
PyJWT==2.8.*
python-dateutil==2.9.*
python-dotenv==1.0.*
python-multipart==0.0.*
pytz # Follows year based versioning
PyYAML==6.0.*
Expand Down
1 change: 1 addition & 0 deletions jarvis/lib/version_upgrade_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
gmail-connector>=1.0.2
py3-tts>=3.5
pycontrols>=0.0.4
VaultAPI-Client>=0.1.1
vpn-server>=1.7.1
62 changes: 55 additions & 7 deletions jarvis/modules/models/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from datetime import datetime
from ipaddress import IPv4Address
from multiprocessing import current_process
from typing import Dict, List, Optional
from typing import Any, Dict, List, Optional
from uuid import UUID

import jlrpy
Expand All @@ -39,6 +39,7 @@
)
from pydantic_settings import BaseSettings
from pyhtcc import Zone
from vaultapi import VaultAPIClient

from jarvis import indicators, scripts
from jarvis.modules.exceptions import InvalidEnvVars, UnsupportedOS
Expand Down Expand Up @@ -496,7 +497,51 @@ def validate_weather_alert(cls, value: str) -> str | None:
raise InvalidEnvVars("format should be '%I:%M %p'")


def env_loader(key, default) -> EnvConfig:
def get_env(key: str, default: Any = None):
"""Get environment variables with case insensitivity."""
for _key, _value in os.environ.items():
if _key.lower() == key.lower():
return _value
return default


def json_parser(secret: str) -> Any:
"""JSON parser for environment variables passed via VaultAPI.
Args:
secret: Receives secret as a string from Vault.
Returns:
Any:
Returns the JSON parsed value.
"""
try:
value = json.loads(secret)
if isinstance(value, int):
return str(value)
return value
except json.JSONDecodeError:
return secret


def env_vault_loader(key, default) -> EnvConfig | None:
"""Load env config by retrieving a DB table.
Args:
key: Table name env var to look for.
default: Default value if table name env var is not found.
Returns:
EnvConfig:
Returns a reference to the ``EnvConfig`` object.
"""
if vault_env_vars := VaultAPIClient().get_table(table_name=get_env(key, default)):
return EnvConfig(
**{k.lower(): json_parser(v) for k, v in vault_env_vars.items()}
)


def env_file_loader(key, default) -> EnvConfig:
"""Loads environment variables based on filetypes.
Args:
Expand All @@ -507,10 +552,8 @@ def env_loader(key, default) -> EnvConfig:
EnvConfig:
Returns a reference to the ``EnvConfig`` object.
"""
for _key, _value in os.environ.items():
if _key.lower() == key.lower():
env_file = pathlib.Path(_value)
break
if env_file_r := get_env(key, default):
env_file = pathlib.Path(env_file_r)
else:
env_file = pathlib.Path(default)
if env_file.suffix.lower() == ".json":
Expand All @@ -533,7 +576,12 @@ def env_loader(key, default) -> EnvConfig:
)


env = env_loader(key="env_file", default=".env")
# noinspection PyBroadException
try:
# todo: Parse when loading secrets into vault
env = env_vault_loader(key="vault_table", default="jarvis")
except Exception:
env = env_file_loader(key="env_file", default=".env")


class FileIO(BaseModel):
Expand Down
Loading

0 comments on commit bf91814

Please sign in to comment.