Skip to content

Commit

Permalink
removing part_of_app_of_apps feature (#100)
Browse files Browse the repository at this point in the history
* removing part_of_app_of_apps feature

* fix vouch bitwarden id stuff... even though I thought I did that already

* bump pyproject again

* finish cleaning up the last of app_of_apps stuff in favor of using appsets more effeciently and directory recursion

* Update smol_k8s_lab/k8s_apps/secrets_management/external_secrets_operator.py - fix typo

Co-authored-by: Max! <[email protected]>

---------

Co-authored-by: Max! <[email protected]>
  • Loading branch information
jessebot and cloudymax authored Dec 2, 2023
1 parent f753dda commit 819c036
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 149 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "smol_k8s_lab"
version = "2.0.0a1"
version = "2.0.0a2"
description = "Bootstrap simple projects on Kubernetes with kind, k3d, and k3s. this is an alpha release"
authors = ["Jesse Hitch <[email protected]>",
"Max Roby <[email protected]>"]
Expand Down
7 changes: 3 additions & 4 deletions smol_k8s_lab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def main(config: str = "",
apps.pop('ingress_nginx'),
apps['cert_manager'],
argo_enabled,
apps['appset_secret_plugin']['enabled'],
apps['argocd']['argo']['directory_recursion'],
SECRETS,
bw)

Expand All @@ -226,7 +226,7 @@ def main(config: str = "",
setup_k8s_secrets_management(k8s_obj,
distro,
apps.pop('external_secrets_operator'),
apps.pop('bitwarden_eso_provider'),
SECRETS['global_external_secrets'],
apps.pop('infisical'),
apps.pop('vault'),
bw)
Expand Down Expand Up @@ -285,9 +285,8 @@ def main(config: str = "",
header("Installing the rest of the Argo CD apps")
for app_key, app_meta in apps.items():
if app_meta['enabled']:
app_of_apps = app_meta['argo'].get('part_of_app_of_apps', False)
app_installed = check_if_argocd_app_exists(app_key)
if not app_of_apps and not app_installed:
if not app_installed:
argo_app = app_key.replace('_', '-')
sub_header(f"Installing app: {argo_app}")
install_with_argocd(k8s_obj, argo_app, app_meta['argo'])
Expand Down
101 changes: 19 additions & 82 deletions smol_k8s_lab/config/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ apps:
[link=https://argo-cd.readthedocs.io/en/stable/]Argo CD[/link] is a declarative, GitOps continuous delivery tool for Kubernetes.
smol-k8s-lab installs Argo CD with helm initially to support initial configuration of your admin user and disabling of dex. After your OIDC provider is configured, Argo CD begins managing itself using the below configured Argo CD repo.
The Appset Secret Plugin is required if you want to use the default [link="https://github.com/small-hack/argocd-apps"]small-hack/argocd-apps[/link] [gold3]argo.repo[/gold3] and default enabled if Argo CD is enabled, so we can create a k8s Secret with your more private info such as hostnames, IP addresses, and emails in a deployment that runs alongside Argo CD to provide Argo CD ApplicationSets This plugin has no ingress and cannot be reached from outside the cluster.
To disable Appset Secret Plugin, please set directory recursion to false.
Learn more: [link=https://github.com/small-hack/appset-secret-plugin]https://github.com/small-hack/appset-secret-plugin[/link]
argo:
# secrets keys to make available to Argo CD ApplicationSets
secret_keys:
Expand All @@ -158,13 +164,13 @@ apps:
repo: "https://github.com/small-hack/argocd-apps"
# path in the argo repo to point to. Trailing slash very important!
# change to argocd/argocd to not use app of apps with secret plugin
path: "argocd/"
path: "argocd/app_of_apps/"
# either the branch or tag to point at in the argo repo above
revision: main
# namespace to install the k8s app in
namespace: "argocd"
# recurse directories in the provided git repo
directory_recursion: false
# recurse directories in the provided git repo, if true, we also deploy the appset secret plugin
directory_recursion: true
# source repos for Argo CD argo-cd Project (in addition to argo_cd.argo.repo)
project:
source_repos:
Expand All @@ -175,83 +181,6 @@ apps:
namespaces:
- prometheus

appset_secret_plugin:
# Required if you want to use the default small-hack/argocd-apps argo.repo and
# default enabled if ArgoCD is enabled, so we can create a k8s Secret with
# your more private info such as hostnames, IP addresses, and emails in a
# deployment that runs alongside ArgoCD to provide Argo CD ApplicationSets
# This plugin has no ingress and cannot be reached from outside the cluster
enabled: true
description: |
Required if you want to use the default [link="https://github.com/small-hack/argocd-apps"]small-hack/argocd-apps[/link] [gold3]argo.repo[/gold3] and default enabled if Argo CD is enabled, so we can create a k8s Secret with your more private info such as hostnames, IP addresses, and emails in a deployment that runs alongside Argo CD to provide Argo CD ApplicationSets This plugin has no ingress and cannot be reached from outside the cluster
Switch to initialization off if you don't want to deploy a default secret with all keys in each apps.{app}.argo.secret_keys
Learn more: [link=https://github.com/small-hack/appset-secret-plugin]https://github.com/small-hack/appset-secret-plugin[/link]
init:
# switch to false if you don't want to create an initial secret of values
# to provide to other Argo CD ApplicationSets
enabled: true
argo:
# secrets keys to make available to Argo CD ApplicationSet itself
secret_keys: {}
# skip installing this app b/c its part of another app of apps with this
# name. If equals "" we'll instead use the repo, path, revision, and namespace
part_of_app_of_apps: "argo_cd"
# 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: "argocd/"
# either the branch or tag to point at in the argo repo above
revision: main
# namespace to install the k8s app in
namespace: "argocd"
# recurse directories in the provided git repo
directory_recursion: false
project:
source_repos:
- https://small-hack.github.io/appset-secret-plugin
destination:
# automatically includes the app's namespace and argocd's namespace
namespaces: []

bitwarden_eso_provider:
enabled: true
description: |
The [link="https://github.com/jessebot/bitwarden-eso-provider/"]Bitwarden External Secrets Provider[/link] is used to store k8s secrets in Bitwarden®. This deployment has no ingress and can't be connected to from outside the cluster. There is a networkPolicy that only allows the pod to communicate with the External Secrets Operator in the same namespaces.
smol-k8s-lab support initialization by creating a Kubernetes secret with your Bitwarden credentials so that the provider can unlock your vault. You will need to setup an [link=https://bitwarden.com/help/personal-api-key/]API key[/link] ahead of time. You can pass these credentials in by setting the following environment variables:
BITWARDEN_PASSWORD, BITWARDEN_CLIENTSECRET, BITWARDEN_CLIENTID
init:
# Switch to false if you don't want to be prompted for your Bitwarden
# API credentials to be created as a Kubernetes secret.
enabled: true
argo:
# skip installing this app b/c its part of another app of apps with this
# name. If equals "" we'll instead use the below repo, path, revision, and namespace
part_of_app_of_apps: external_secrets_operator
# 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: external-secrets-operator/bitwarden
# either the branch or tag to point at in the argo repo above
revision: main
# namespace to install the k8s app in
namespace: external-secrets
# recurse directories in the provided git repo
directory_recursion: false
# optional secrets keys to pass to the Argo CD Appset secret plugin generator
secret_keys: {}
# source repos for Argo CD App Project (in addition to app.argo.repo)
project:
# where the helm chart lives. Go here for more info
source_repos:
- https://small-hack.github.io/bitwarden-eso-provider
destination:
# automatically includes the app's namespace and argocd's namespace
namespaces: []

# This app is installed with helm or manifests depending on what is recommended
# for your k8s distro. Becomes managed by Argo CD if you enable it below
cert_manager:
Expand Down Expand Up @@ -355,6 +284,14 @@ apps:
enabled: true
description: |
[link=https://external-secrets.io/latest/]External Secrets Operator[/link] is a Kubernetes operator that integrates external secret management systems like HashiCorp Vault, CyberArk Conjur, Bitwarden, Gitlab, and many more. The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret.
To deploy the Bitwarden provider, please set apps_global_config.external_secrets to "bitwarden".
The [link="https://github.com/jessebot/bitwarden-eso-provider/"]Bitwarden External Secrets Provider[/link] is used to store k8s secrets in Bitwarden®. This deployment has no ingress and can't be connected to from outside the cluster. There is a networkPolicy that only allows the pod to communicate with the External Secrets Operator in the same namespaces.
smol-k8s-lab support initialization by creating a Kubernetes secret with your Bitwarden credentials so that the provider can unlock your vault. You will need to setup an [link=https://bitwarden.com/help/personal-api-key/]API key[/link] ahead of time. You can pass these credentials in by setting the following environment variables:
BITWARDEN_PASSWORD, BITWARDEN_CLIENTSECRET, BITWARDEN_CLIENTID
# Initialization of the app through smol-k8s-lab
init:
enabled: false
Expand All @@ -366,7 +303,7 @@ apps:
# ONLY the external-secrets-operator, so this will not use app of apps and
# therefore we will not deploy the Bitwarden ESO provider. Use if you want to use
# a different provider
path: external-secrets-operator/
path: external-secrets-operator/app_of_apps/
# either the branch or tag to point at in the argo repo above
revision: main
# namespace to install the k8s app in
Expand Down Expand Up @@ -1070,7 +1007,7 @@ apps:
# 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: "vouch-proxy/"
path: "vouch-proxy/app_of_apps/"
# either the branch or tag to point at in the argo repo above
revision: main
# namespace to install the k8s app in
Expand Down
8 changes: 3 additions & 5 deletions smol_k8s_lab/k8s_apps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
def setup_k8s_secrets_management(k8s_obj: K8s,
k8s_distro: str,
eso_dict: dict = {},
bitwarden_eso_provider_dict: dict = {},
eso_provider: str = "",
infisical_dict: dict = {},
vault_dict: dict = {},
bitwarden: BwCLI = None) -> None:
Expand All @@ -45,13 +45,11 @@ def setup_k8s_secrets_management(k8s_obj: K8s,

# setup external secrets operator and bitwarden external secrets
if eso_dict['enabled']:
header_msg += 'External Secrets Operator[/]'
if bitwarden_eso_provider_dict['enabled']:
header_msg += ' and [blue]Bitwarden[/] as the Provider'
header_msg += f'External Secrets Operator[/] and [blue]{eso_provider}[/] as the Provider'
header(header_msg, '🤫')
configure_external_secrets(k8s_obj,
eso_dict,
bitwarden_eso_provider_dict,
eso_provider,
k8s_distro,
bitwarden)

Expand Down
22 changes: 14 additions & 8 deletions smol_k8s_lab/k8s_apps/identity_provider/vouch.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ def configure_vouch(k8s_obj: K8s,
create_custom_field("endSessionEndpoint", auth_dict['end_session_url']),
create_custom_field("preferredDomain", preferred_domain)
]

log.info(f"vouch oauth fields are {fields}")

# create oauth OIDC bitwarden item
oauth_id = bitwarden.create_login(
name='vouch-oauth-config',
Expand All @@ -100,7 +102,9 @@ def configure_vouch(k8s_obj: K8s,
domains_obj = create_custom_field("domains", domains)
emails_obj = create_custom_field("allowList", emails)
jwt_secret_obj = create_custom_field("jwtSecret", jwt_secret)

log.debug(f"emails_obj is {emails_obj} and domains_obj is {domains_obj}")

# create vouch config bitwarden item
vouch_id = bitwarden.create_login(
name='vouch-config',
Expand All @@ -111,10 +115,11 @@ def configure_vouch(k8s_obj: K8s,
)

# update the vouch values for the argocd appset
fields = {'vouch_oauth_config_bitwarden_id': oauth_id,
'vouch_config_bitwarden_id': vouch_id}

update_argocd_appset_secret(k8s_obj, fields)
update_argocd_appset_secret(
k8s_obj,
{'vouch_oauth_config_bitwarden_id': oauth_id,
'vouch_config_bitwarden_id': vouch_id}
)

# reload the bitwarden ESO provider
try:
Expand Down Expand Up @@ -163,10 +168,11 @@ def configure_vouch(k8s_obj: K8s,
)[0]['id']

# update the vouch values for the argocd appset
fields = {'vouch_oauth_bitwarden_id': oauth_id,
'vouch_config_bitwarden_id': vouch_id}

update_argocd_appset_secret(k8s_obj, fields)
update_argocd_appset_secret(
k8s_obj,
{'vouch_oauth_config_bitwarden_id': oauth_id,
'vouch_config_bitwarden_id': vouch_id}
)


def create_vouch_app(provider: str,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,85 +1,63 @@
#!/usr/bin/env python3.11
"""
Name: external_secrets
DESCRIPTION: configures external secrets, currently only with gitlab
DESCRIPTION: configures external secrets, currently only with Bitwarden and GitLab
hopefully with more supported providers in the future
AUTHOR: @jessebot
LICENSE: GNU AFFERO GENERAL PUBLIC LICENSE Version 3
"""
import logging as log
from smol_k8s_lab.bitwarden.bw_cli import BwCLI
from smol_k8s_lab.k8s_tools.argocd_util import install_with_argocd, wait_for_argocd_app
from smol_k8s_lab.k8s_tools.k8s_lib import K8s
from smol_k8s_lab.utils.rich_cli.console_logging import sub_header
from smol_k8s_lab.utils.subproc import subproc


def configure_external_secrets(k8s_obj: K8s,
eso_dict: dict,
bweso_dict: dict = {},
eso_provider: str = "",
distro: str = "",
bitwarden: BwCLI = None) -> None:
"""
configure external secrets and provider. (and optionally bweso)
configure external secrets and provider. (and optionally bweso or gitlab)
"""
k8s_obj.create_namespace("external-secrets")

if eso_provider == "bitwarden":
setup_bweso_provider(k8s_obj, distro, bitwarden)
elif eso_provider == "gitlab":
setup_gitlab_provider(k8s_obj, eso_dict['init']['values']['gitlab_access_token'])

install_with_argocd(k8s_obj, 'external-secrets-operator', eso_dict['argo'])
wait_for_argocd_app('external-secrets-operator')

if bweso_dict['enabled']:
setup_bweso(k8s_obj, distro, bweso_dict['argo'], bitwarden)
# wait for bitwarden external secrets provider to be up
wait_for_argocd_app('bitwarden-eso-provider')


def setup_bweso(k8s_obj: K8s,
distro: str,
bweso_argo_dict: dict = {},
bitwarden: BwCLI = None) -> None:
def setup_bweso_provider(k8s_obj: K8s, distro: str, bitwarden: BwCLI = None) -> None:
"""
Creates an initial secret for use with the bitwarden provider for ESO
"""
sub_header("Installing the Bitwarden External Secrets Provider...")

# this is a standard k8s secrets yaml
k8s_obj.create_secret('bweso-login', 'external-secrets',
k8s_obj.create_secret('bweso-login',
'external-secrets',
{"BW_PASSWORD": bitwarden.password,
"BW_CLIENTSECRET": bitwarden.client_secret,
"BW_CLIENTID": bitwarden.client_id,
"BW_HOST": bitwarden.host})

if distro == 'kind':
image = "docker.io/jessebot/bweso:v0.2.0"
image = "docker.io/jessebot/bweso:v0.5.0"
cmds = [f"docker pull --platform=linux/amd64 {image}",
f"kind load docker-image {image} --name smol-k8s-lab-kind"]
subproc(cmds)

if bweso_argo_dict.get('part_of_app_of_apps', None):
log.debug("Looks like this app is actually part of an app of apps "
"that will be deployed")
return True

install_with_argocd(k8s_obj, 'bitwarden-eso-provider', bweso_argo_dict)
# wait for bitwarden external secrets provider to be up
wait_for_argocd_app('bitwarden-eso-provider')


def setup_gitlab_provider(k8s_obj: K8s, external_secrets_config: dict) -> None:
def setup_gitlab_provider(k8s_obj: K8s, gitlab_access_token: str) -> None:
"""
setup the gitlab external secrets operator config
Accepts dict as arg:
dict = {'namespace': 'somenamespace', 'access_token': 'tokenhere'}
setup the GitLab external secrets operator provider config by creating a
secret with the GitLab access token
"""
gitlab_access_token = external_secrets_config['access_token']
gitlab_namespace = external_secrets_config['namespace']

# create the namespace if does not exist
subproc([f'kubectl create namespace {gitlab_namespace}'], error_ok=True)

# this currently only works with gitlab
gitlab_secret = {'apiVersion': 'v1',
'kind': 'Secret',
'metadata': {'name': 'gitlab-secret',
'namespace': gitlab_namespace,
'labels': {'type': 'gitlab'}},
'type': 'Opaque',
'stringData': {'token': gitlab_access_token}}

k8s_obj.apply_custom_resources([gitlab_secret])
k8s_obj.create_secret('gitlab-secret',
'external-secrets',
{'token': gitlab_access_token})
5 changes: 0 additions & 5 deletions smol_k8s_lab/k8s_tools/argocd_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ def install_with_argocd(k8s_obj: K8s, app: str, argo_dict: dict) -> None:
proj_namespaces = argo_dict['project']['destination']['namespaces']
proj_namespaces.append(app_namespace)

if argo_dict.get('part_of_app_of_apps', None):
log.debug("Looks like this app is actually part of an app of apps "
"that will be deployed")
return True

# make sure the namespace already exists
k8s_obj.create_namespace(app_namespace)

Expand Down

0 comments on commit 819c036

Please sign in to comment.