Skip to content

Commit

Permalink
Set up grafana oidc directly via zitadel instead of using vouch if `i…
Browse files Browse the repository at this point in the history
…nit.enabled`; also upgrade textual dep to `0.72.0` (#285)

* adding support for setting up grafana oidc directly via zitadel instead of using vouch

* change the default prometheus config directory

* fix name of prometheus grafana oidc value

* Add new path to prometheus docs

* add init.enabled to prometheus

* fix distinction between prometheus and prometheus_crds for app installation
  • Loading branch information
jessebot authored Jul 12, 2024
1 parent 0b876b2 commit f170408
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 155 deletions.
164 changes: 82 additions & 82 deletions docs/assets/images/screenshots/help_text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions docs/k8s_apps/prometheus.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,18 @@ apps:
```yaml
apps:
prometheus:
prometheus:
description: |
Full monitoring stack with [link=https://prometheus.io/docs/introduction/overview/]Prometheus[/link], grafana, loki, and alert manager.
Full monitoring stack with [link=https://prometheus.io/docs/introduction/overview/]Prometheus[/link], [link=https://grafana.com/oss/loki/]Loki[/link], [link=https://prometheus.io/docs/alerting/latest/alertmanager/]Alert Manager[/link], and [link=https://grafana.com/oss/grafana/]Grafana[/link].
smol-k8s-lab supports initialization by setting up your ingress hostnames.
smol-k8s-lab supports initialization by setting up your ingress hostnames. It will also setup Oauth2 for Grafana directly by creating an app in Zitadel for you.
For Prometheus and Alert Manager, we use vouch-proxy via Ingress resource annotations to forward users to Zitadel for auth, so the frontend is not insecure.
enabled: false
init:
# if init is enabled, we'll set up an app in Zitadel for using Oauth2 with Grafana
enabled: true
argo:
# secrets keys to make available to Argo CD ApplicationSets
secret_keys:
Expand All @@ -78,7 +83,7 @@ apps:
# path in the argo repo to point to. Trailing slash very important! This
# is an app of apps. Change to "monitoring/kube-prometheus-stack/" to
# only install kube-prometheus-stack (foregoing loki and push gateway)
path: prometheus/
path: prometheus/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
Expand Down
110 changes: 55 additions & 55 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 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.10.0"
version = "5.11.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 @@ -43,7 +43,7 @@ requests = "^2.32"
rich = "^13.0"
ruamel-yaml = "^0.18"
ruamel-yaml-string = "^0.1"
textual = "^0.71"
textual = "^0.72"
xdg-base-dirs = "^6.0"
pygame = "^2.5"
python-ulid = "^2.6"
Expand Down
23 changes: 15 additions & 8 deletions smol_k8s_lab/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3.11
#!/usr/bin/env python4.11
"""
NAME: smol-k8s-lab
DESCRIPTION: package, cli, and tui for setting up k8s on metal with
Expand All @@ -24,6 +24,7 @@
from .constants import KUBECONFIG, VERSION
from .k8s_apps import (setup_oidc_provider, setup_base_apps,
setup_k8s_secrets_management, setup_federated_apps)
from .k8s_apps.monitoring.prometheus_stack import configure_prometheus_stack
from .k8s_apps.networking.netmaker import configure_netmaker
from .k8s_apps.operators import setup_operators
from .k8s_apps.operators.minio import configure_minio_tenant
Expand Down Expand Up @@ -257,13 +258,13 @@ def main(config: str = "",
# Setup minio, our local s3 provider, is essential for creating buckets
# and cnpg operator, our postgresql operator for creating postgres clusters
setup_operators(argocd,
apps.pop('prometheus_crds', {}),
apps.pop('longhorn', {}),
apps.pop('k8up', {}),
apps.pop('minio_operator', {}),
apps.pop('seaweedfs', {}),
apps.pop('cnpg_operator', {}),
apps.pop('postgres_operator', {}),
apps.pop('prometheus_crds', {'enabled': False}),
apps.pop('longhorn', {'enabled': False}),
apps.pop('k8up', {'enabled': False}),
apps.pop('minio_operator', {'enabled': False}),
apps.pop('seaweedfs', {'enabled': False}),
apps.pop('cnpg_operator', {'enabled': False}),
apps.pop('postgres_operator', {'enabled': False}),
bw)

# global pvc storage class
Expand Down Expand Up @@ -295,6 +296,12 @@ def main(config: str = "",
bw,
oidc_obj)

# this is currently just to make sure that grafana zitadel auth gets set up
prometheus_stack = apps.pop('prometheus', {'enabled': False})
if prometheus_stack['enabled']:
configure_prometheus_stack(argocd, prometheus_stack, oidc_obj, bw)

# setup nextcloud, home assistant, mastodon, and matrix
setup_federated_apps(
argocd,
api_tls_verify,
Expand Down
12 changes: 8 additions & 4 deletions smol_k8s_lab/config/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@ apps:
postgres-operator is a Kubernetes operator for postgresql by Zalando.
smol-k8s-lab supports initialization by setting up your ingress hostnames, and then also creating a local s3 endpoint exclusively for backups with and additional configurable endpoint for backups to an external s3
enabled: true
enabled: false
init:
enabled: true
backups:
Expand Down Expand Up @@ -1392,11 +1392,15 @@ apps:

prometheus:
description: |
Full monitoring stack with [link=https://prometheus.io/docs/introduction/overview/]Prometheus[/link], grafana, loki, and alert manager.
Full monitoring stack with [link=https://prometheus.io/docs/introduction/overview/]Prometheus[/link], [link=https://grafana.com/oss/loki/]Loki[/link], [link=https://prometheus.io/docs/alerting/latest/alertmanager/]Alert Manager[/link], and [link=https://grafana.com/oss/grafana/]Grafana[/link].
smol-k8s-lab supports initialization by setting up your ingress hostnames.
smol-k8s-lab supports initialization by setting up your ingress hostnames. It will also setup Oauth2 for Grafana directly by creating an app in Zitadel for you.
For Prometheus and Alert Manager, we use vouch-proxy via Ingress resource annotations to forward users to Zitadel for auth, so the frontend is not insecure.
enabled: false
init:
# if init is enabled, we'll set up an app in Zitadel for using Oauth2 with Grafana
enabled: true
argo:
# secrets keys to make available to Argo CD ApplicationSets
secret_keys:
Expand All @@ -1413,7 +1417,7 @@ apps:
# path in the argo repo to point to. Trailing slash very important! This
# is an app of apps. Change to "monitoring/kube-prometheus-stack/" to
# only install kube-prometheus-stack (foregoing loki and push gateway)
path: prometheus/
path: prometheus/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
Expand Down
5 changes: 4 additions & 1 deletion smol_k8s_lab/k8s_apps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ def setup_oidc_provider(argocd: ArgoCD,
argocd_fqdn: str = "") -> Zitadel | None:
"""
sets up oidc provider. only zitadel is supported right now
if we choose to add keycloak back, we'll be adding the following arg
Returns Zitadel object for configuring other Zitadel authed services
IF we choose to add keycloak back, we'll be adding the following arg
keycloak_dict: dict = {}
"""
header("Setting up [green]OIDC[/]/[green]Oauth[/] Applications")
Expand Down
151 changes: 151 additions & 0 deletions smol_k8s_lab/k8s_apps/monitoring/prometheus_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# external libraries
import logging as log

# internal libraries
from smol_k8s_lab.k8s_tools.argocd_util import ArgoCD
from smol_k8s_lab.bitwarden.bw_cli import BwCLI
from smol_k8s_lab.k8s_apps.identity_provider.zitadel_api import Zitadel
from smol_k8s_lab.utils.rich_cli.console_logging import sub_header, header

def configure_prometheus_stack(argocd: ArgoCD,
cfg: dict,
zitadel: Zitadel,
bitwarden: BwCLI = None) -> bool:
"""
creates a prometheus stack app and initializes it with secrets if you'd like :)
required:
argocd - ArgoCD() object for Argo CD operations
cfg - dict, with at least argocd key and init key
optional:
zitadel - Zitadel() object with session token to create zitadel oidc app and roles
bitwarden - BwCLI() object with session token to create bitwarden items
"""
# verify immediately if prometheus is installed
app_installed = argocd.check_if_app_exists('prometheus')

# verify if initialization is enabled
init = cfg.get('init', {'enabled': True, 'restore': {'enabled': False}})
init_enabled = init.get('enabled', True)

if app_installed:
header_start = "Syncing"
else:
header_start = "Setting up"

header(f"{header_start} [green]prometheus[/], so you can monitor your infrastructure",
'🔥')

secrets = cfg['argo']['secret_keys']
if secrets:
grafana_hostname = secrets['grafana_hostname']

# always declare prometheus namespace immediately
prometheus_namespace = cfg['argo']['namespace']

# initial secrets to deploy this app from scratch
if init_enabled and not app_installed:
argocd.k8s.create_namespace(prometheus_namespace)

# create prometheus OIDC Application
if zitadel:
log.debug("Creating an OIDC application in Zitadel...")
zitadel_hostname = zitadel.hostname
logout_uris = [f"https://{grafana_hostname}"]
redirect_uris = f"https://{grafana_hostname}/login/generic_oauth"
oidc_creds = zitadel.create_application("grafana",
redirect_uris,
logout_uris)
zitadel.create_role("grafana_users", "grafana Users", "grafana_users")
zitadel.update_user_grant(['grafana_users'])
else:
zitadel_hostname = ""

# if the user has bitwarden enabled
if bitwarden:
setup_bitwarden_items(argocd,
grafana_hostname,
prometheus_namespace,
zitadel_hostname,
oidc_creds,
bitwarden)

# else create these as Kubernetes secrets
else:
if zitadel:
# oidc secret
argocd.k8s.create_secret(
'grafana-oidc-credentials',
'grafana',
{'user': oidc_creds['client_id'],
'password': oidc_creds['client_secret']}
)

if not app_installed:
argocd.install_app('prometheus', cfg['argo'])
else:
if bitwarden and init_enabled:
log.info("prometheus already installed 🎉")
refresh_bweso(argocd, grafana_hostname, bitwarden)


def refresh_bweso(argocd: ArgoCD, grafana_hostname: str, bitwarden: BwCLI):
"""
refresh the bitwarden item IDs for use with argocd-appset-secret-plugin
"""
# update the prometheus values for the argocd appset
log.debug("making sure prometheus and grafana bitwarden IDs are present in "
"appset secret plugin")

oidc_id = bitwarden.get_item(
f"grafana-oidc-credentials-{grafana_hostname}", False
)[0]['id']

argocd.update_appset_secret(
{'prometheus_grafana_oidc_credentials_bitwarden_id': oidc_id})


def setup_bitwarden_items(argocd: ArgoCD,
grafana_hostname: str,
prometheus_namespace: str,
zitadel_hostname: str,
oidc_creds: str,
bitwarden: BwCLI):
"""
setup all the required secrets as items in bitwarden
"""
sub_header("Creating prometheus related secrets in Bitwarden")

# OIDC credentials
log.info("Creating OIDC credentials for grafana in Bitwarden")
if zitadel_hostname:
if oidc_creds:
# for the credentials to zitadel
oidc_id = bitwarden.create_login(
name='grafana-oidc-credentials',
item_url=grafana_hostname,
user=oidc_creds['client_id'],
password=oidc_creds['client_secret']
)
else:
# we assume the credentials already exist if they fail to create
oidc_id = bitwarden.get_item(
f"grafana-oidc-credentials-{grafana_hostname}"
)[0]['id']

# update the grafana values for the argocd appset
argocd.update_appset_secret(
{'prometheus_grafana_oidc_credentials_bitwarden_id': oidc_id}
)

# reload the bitwarden ESO provider
try:
argocd.k8s.reload_deployment('bitwarden-eso-provider',
'external-secrets')
except Exception as e:
log.error(
"Couldn't scale down the [magenta]bitwarden-eso-provider[/]"
"deployment in [green]external-secrets[/] namespace. Recieved: "
f"{e}"
)

0 comments on commit f170408

Please sign in to comment.