Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add libretranslate as an experimental app; add libretranslate to mastodon; update deps #335

Merged
merged 5 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/k8s_apps/experimental/libretranslate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
LibreTranslate is a self-hosted language translation tool.

## Example config

```yaml
apps:
libre_translate:
description: |
📖 [link=https://libretranslate.com/]libretranslate[/link] is a self-hosted translation tool.
enabled: false
init:
enabled: true
argo:
# secret keys to provide for the argocd secret plugin app, none by default
secret_keys:
hostname: ""
# git repo to install the Argo CD app from
repo: https://github.com/small-hack/argocd-apps
# path in the argo repo to point to. Trailing slash very important!
path: libretranslate/app_of_apps/
# either the branch or tag to point at in the argo repo above
revision: main
# kubernetes cluster to install the k8s app into, defaults to Argo CD default
cluster: https://kubernetes.default.svc
# namespace to install the k8s app in
namespace: libretranslate
# recurse directories in the provided git repo
directory_recursion: false
# source repos for Argo CD App Project (in addition to argo.repo)
project:
name: libretranslate
source_repos:
- https://small-hack.github.io/libretranslate-helm-chart
destination:
# automatically includes the app's namespace and argocd's namespace
namespaces:
- libretranslate
```
6 changes: 6 additions & 0 deletions docs/k8s_apps/mastodon.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ apps:
admin_user: "tootadmin"
# admin user's email
admin_email: ""
# api key for mastodon to do translations through libretranslate
libretranslate_api_key:
value_from:
env: MASTODON_LIBRETRANSLATE_API_KEY
# mail server to send verification and notification emails
smtp_host: "[email protected]"
# mail user for smtp host
Expand Down Expand Up @@ -114,6 +118,8 @@ apps:
smtp_port: '25'
# admin user for your mastodon instance
admin_user: tootadmin
# endpoint for libretranslate translations
libretranslate_hostname: ""
# hostname that users go to in the browser
hostname: ""
# set the local s3 provider for mastodon's public data in one bucket
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ nav:
- Kepler: k8s_apps/experimental/kepler.md
- Kyverno: k8s_apps/experimental/kyverno.md
- Kubevirt: k8s_apps/experimental/kubevirt.md
- LibreTranslate: k8s_apps/experimental/libretranslate.md
- Longhorn: k8s_apps/experimental/longhorn.md
- Openbao: k8s_apps/experimental/openbao.md
- MinIO: k8s_apps/experimental/minio.md
Expand Down
1,080 changes: 551 additions & 529 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "smol_k8s_lab"
version = "5.18.0"
version = "5.19.0"
description = "CLI and TUI to quickly install slimmer Kubernetes distros and then manage apps declaratively using Argo CD"
authors = ["Jesse Hitch <[email protected]>",
"Max Roby <[email protected]>"]
Expand Down Expand Up @@ -59,10 +59,10 @@ mkdocs-video = "^1.5"
optional = true

[tool.poetry.group.dev.dependencies]
deptry = "^0.20"
deptry = "^0.21"
textual-dev = "^1.6"
pytest-textual-snapshot = "^1.0"
poethepoet = "^0.29.0"
poethepoet = "^0.30"
# for creating app images: https://pypi.org/project/poetry-plugin-appimage/
# poetry-plugin-appimage = "^0.0.4"
# [tool.poetry-plugin-appimage]
Expand Down
11 changes: 11 additions & 0 deletions smol_k8s_lab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .k8s_apps.networking.netmaker import configure_netmaker
from .k8s_apps.operators import setup_operators
from .k8s_apps.operators.minio import configure_minio_tenant
from .k8s_apps.social.libre_translate import configure_libretranslate
from .k8s_distros import create_k8s_distro, delete_cluster
from .tui import launch_config_tui
from .utils.rich_cli.console_logging import CONSOLE, sub_header, header
Expand Down Expand Up @@ -302,6 +303,11 @@ def main(config: str = "",
if prometheus_stack['enabled']:
configure_prometheus_stack(argocd, prometheus_stack, oidc_obj, bw)

# set up self hosted translation
libre_translate_dict = apps.pop('libre_translate', {})
if libre_translate_dict:
configure_libretranslate(argocd, libre_translate_dict, bw)

# setup nextcloud, home assistant, mastodon, and matrix
setup_federated_apps(
argocd,
Expand Down Expand Up @@ -387,6 +393,11 @@ def main(config: str = "",
final_msg += ("\n🏠 Home Assistant, for managing your IoT needs:\n"
f"[blue][link]https://{home_assistant_hostname}[/][/]\n")

libretranslate_hostname = SECRETS.get('libretranslate_hostname', "")
if libretranslate_hostname:
final_msg += ("\n📖, LibreTranslate for self-hosted language translations:\n"
f"[blue][link]https://{libretranslate_hostname}[/][/]\n")

netmaker_hostname = SECRETS.get('netmaker_admin_hostname', "")
if netmaker_hostname:
final_msg += ("\n🛜 Netmaker, for managing your own VPN:\n"
Expand Down
40 changes: 40 additions & 0 deletions smol_k8s_lab/config/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,40 @@ apps:
# automatically includes the app's namespace and argocd's namespace
namespaces: []

libre_translate:
description: |
📖 [link=https://libretranslate.com/]libretranslate[/link] is a self-hosted translation tool.

If init is enabled, we'll generate an api key for you.
enabled: false
init:
enabled: true
argo:
# secret keys to provide for the argocd secret plugin app, none by default
secret_keys:
hostname: ""
# git repo to install the Argo CD app from
repo: https://github.com/small-hack/argocd-apps
# path in the argo repo to point to. Trailing slash very important!
path: libretranslate/app_of_apps/
# either the branch or tag to point at in the argo repo above
revision: main
# kubernetes cluster to install the k8s app into, defaults to Argo CD default
cluster: https://kubernetes.default.svc
# namespace to install the k8s app in
namespace: libretranslate
# recurse directories in the provided git repo
directory_recursion: false
# source repos for Argo CD App Project (in addition to argo.repo)
project:
name: libretranslate
source_repos:
- https://small-hack.github.io/libretranslate-helm-chart
destination:
# automatically includes the app's namespace and argocd's namespace
namespaces:
- libretranslate

longhorn:
description: |
🐮 [link=https://longhorn.io/]Longhorn[/link] is a Cloud native distributed block storage for Kubernetes.
Expand Down Expand Up @@ -810,6 +844,10 @@ apps:
admin_user: "tootadmin"
# admin user's email
admin_email: ""
# api key for mastodon to do translations through libretranslate
libretranslate_api_key:
value_from:
env: MASTODON_LIBRETRANSLATE_API_KEY
# mail server to send verification and notification emails
smtp_host: "[email protected]"
# mail user for smtp host
Expand Down Expand Up @@ -848,6 +886,8 @@ apps:
admin_user: tootadmin
# hostname that users go to in the browser
hostname: ""
# endpoint for libretranslate translations
libretranslate_hostname: ""
# set the local s3 provider for mastodon's public data in one bucket
# and private database backups in another. can be minio or seaweedfs
s3_provider: seaweedfs
Expand Down
118 changes: 118 additions & 0 deletions smol_k8s_lab/k8s_apps/social/libre_translate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# internal libraries
from smol_k8s_lab.bitwarden.bw_cli import BwCLI, create_custom_field
from smol_k8s_lab.k8s_tools.argocd_util import ArgoCD
from smol_k8s_lab.utils.passwords import create_password
from smol_k8s_lab.utils.rich_cli.console_logging import sub_header, header

# external libraries
import logging as log


def configure_libretranslate(argocd: ArgoCD,
cfg: dict,
bitwarden: BwCLI = None) -> None:
"""
creates a libretranslate app and initializes it with secrets if you'd like :)

required:
argocd - ArgoCD() object for argo operations
cfg - dictionary with at least argocd key and init key

optional:
bitwarden - BwCLI() object with session token to create bitwarden items
"""
# check immediately if this app is installed
app_installed = argocd.check_if_app_exists('libretranslate')

# get any secret keys passed in
secrets = cfg['argo']['secret_keys']
if secrets:
libretranslate_hostname = secrets['hostname']

# verify if initialization is enabled
init_enabled = cfg['init']['enabled']

# process restore dict
restore_dict = cfg['init'].get('restore', {"enabled": False})
restore_enabled = restore_dict['enabled']
if restore_enabled:
header_start = "Restoring"
else:
if app_installed:
header_start = "Syncing"
else:
header_start = "Setting up"

header(f"{header_start} [green]libretranslate[/], for selfhosting your own languages translation",
'📖')

# we need namespace no matter the install type
libre_translate_namespace = cfg['argo']['namespace']

# if the user has chosen to use smol-k8s-lab initialization
if not app_installed and init_enabled:
# immediately create namespace
argocd.k8s.create_namespace(libre_translate_namespace)

# if bitwarden is enabled, we create login items for each set of credentials
if bitwarden and not restore_enabled:
setup_bitwarden_items(argocd,
libretranslate_hostname,
bitwarden)
# these are standard k8s secrets
else:
# libretranslate admin credentials and smtp credentials
argocd.k8s.create_secret('libretranslate-credentials',
'libretranslate',
{"api_key": create_password(),
"api_origin": libretranslate_hostname,
})

if not app_installed:
# then install the app as normal
argocd.install_app('libretranslate', cfg['argo'])
else:
log.info("libretranslate already installed 🎉")

# if bitwarden and init are enabled, make sure we populate appset secret
# plugin secret with bitwarden item IDs
if bitwarden and init_enabled:
refresh_bitwarden(argocd, libretranslate_hostname, bitwarden)


def setup_bitwarden_items(argocd: ArgoCD,
libretranslate_hostname: str,
bitwarden: BwCLI) -> None:
"""
setup initial bitwarden items for home assistant
"""
sub_header("Creating libretranslate items in Bitwarden")

# admin credentials for initial owner user
origin = create_custom_field('origin', libretranslate_hostname)
api_id = bitwarden.create_login(
name=f'libretranslate-credentials-{libretranslate_hostname}',
item_url=libretranslate_hostname,
user="n/a",
password=bitwarden.generate(),
fields=[origin]
)

# update the libretranslate values for the argocd appset
argocd.update_appset_secret({'libretranslate_credentials_bitwarden_id': api_id})


def refresh_bitwarden(argocd: ArgoCD,
libretranslate_hostname: str,
bitwarden: BwCLI) -> None:
"""
refresh bitwardens item in the appset secret plugin
"""
log.debug("Making sure libretranslate Bitwarden item IDs are in appset "
"secret plugin secret")

api_id = bitwarden.get_item(
f"libretranslate-credentials-{libretranslate_hostname}"
)[0]['id']

argocd.update_appset_secret({'libretranslate_credentials_bitwarden_id': api_id})
20 changes: 19 additions & 1 deletion smol_k8s_lab/k8s_apps/social/mastodon.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def configure_mastodon(argocd: ArgoCD,
secrets = cfg['argo']['secret_keys']
if secrets:
mastodon_hostname = secrets['hostname']
mastodon_libretranslate_hostname = secrets['libretranslate_hostname']

# we need namespace immediately
mastodon_namespace = cfg['argo']['namespace']
Expand Down Expand Up @@ -110,6 +111,7 @@ def configure_mastodon(argocd: ArgoCD,
mail_user,
mail_pass,
rake_secrets,
mastodon_libretranslate_hostname,
bitwarden)

# these are standard k8s secrets yaml
Expand Down Expand Up @@ -256,6 +258,10 @@ def refresh_bweso(argocd: ArgoCD,
f"mastodon-server-secrets-{mastodon_hostname}", False
)[0]['id']

libretranslate_api_key_id = bitwarden.get_item(
f"libretranslate-credentials-{mastodon_hostname}", False
)[0]['id']

# {'mastodon_admin_credentials_bitwarden_id': admin_id,
argocd.update_appset_secret(
{'mastodon_smtp_credentials_bitwarden_id': smtp_id,
Expand All @@ -266,6 +272,7 @@ def refresh_bweso(argocd: ArgoCD,
'mastodon_s3_mastodon_credentials_bitwarden_id': s3_id,
'mastodon_s3_backups_credentials_bitwarden_id': s3_backups_id,
'mastodon_elasticsearch_credentials_bitwarden_id': elastic_id,
'mastodon_libretranslate_bitwarden_id': libretranslate_api_key_id,
'mastodon_server_secrets_bitwarden_id': secrets_id}
)

Expand All @@ -283,6 +290,7 @@ def setup_bitwarden_items(argocd: ArgoCD,
mail_user: str,
mail_pass: str,
rake_secrets: dict,
mastodon_libretranslate_hostname: str,
bitwarden: BwCLI) -> None:
# S3 credentials
# endpoint that gets put into the secret should probably have http in it
Expand Down Expand Up @@ -431,6 +439,15 @@ def setup_bitwarden_items(argocd: ArgoCD,
]
)

endpoint = create_custom_field('endpoint', mastodon_libretranslate_hostname)
libretranslate_api_key_id = bitwarden.create_login(
name=f'libretranslate-credentials-{mastodon_hostname}',
item_url=mastodon_libretranslate_hostname,
user="n/a",
password=bitwarden.generate(),
fields=[endpoint]
)

# update the mastodon values for the argocd appset
# 'mastodon_admin_credentials_bitwarden_id': admin_id,
argocd.update_appset_secret(
Expand All @@ -442,7 +459,8 @@ def setup_bitwarden_items(argocd: ArgoCD,
'mastodon_s3_mastodon_credentials_bitwarden_id': s3_id,
'mastodon_s3_backups_credentials_bitwarden_id': s3_backups_id,
'mastodon_elasticsearch_credentials_bitwarden_id': elastic_id,
'mastodon_server_secrets_bitwarden_id': secrets_id})
'mastodon_server_secrets_bitwarden_id': secrets_id,
'mastodon_libretranslate_bitwarden_id': libretranslate_api_key_id})

# reload the bitwarden ESO provider
try:
Expand Down