feat(charts/authentik): add blueprints-sidecar to collect from cluster#146
feat(charts/authentik): add blueprints-sidecar to collect from cluster#146genofire wants to merge 1 commit intogoauthentik:mainfrom
Conversation
ecf0dce to
779cd53
Compare
e029b1d to
9a2529a
Compare
|
@BeryJu please review |
ab19593 to
e0050a0
Compare
|
@BeryJu i do not know where this CI error cames from: |
122c5c1 to
7be14dd
Compare
|
solved |
|
thanks @benedikt-bartscher i will add the sidecar to all component |
7be14dd to
521f6f2
Compare
|
done - lets review again |
|
I can vouch that this sidecar works as expected. Nice work @genofire. New configmaps with label (or any other yaml filename) result in blueprint in Authentik. Deletion of configmap removes from Authentik. Be great to get this merged. I've not tried the operator, but this seems a lower-effort way to deliver gitops blueprints. CRD & controller will have to be kept up-to-date with the blueprint spec. This is lower maintenance. |
|
Only downside is blueprints containing secrets referred to using env var tag eg |
|
you could store the blueprint in a kubernetes Secret eigther (instatt of ConfigMap). So your secrets are stored secure. For your problem, maybe there could this operator works reloader |
|
Good suggestions. Long story, but need to stick with configMaps and Nearly gitops Authentik :-) Just need resources created by deleted blueprints to be cleaned up. |
|
It's mid of 2025 and this sidecar method works like a charm! Now able to get rid of keycloak and terraform mess to have fully-featured GitOps authentik instance managed by argocd continuously deployed configmaps. Yes, it still forces me to delete resources by hand, but it's better than nothing. |
would be great if blueprint, could have a mecanism to delete related object if there not present anymore ( without the need of cahnge the |
technically, there's and, kiwigrid sidecar has ability to run So, maybe something like this can be used to handle blueprints properly (DO NOT USE IN PRODUCTION, CODE NOT TESTED)#!/bin/python
import os
import yaml
import hashlib
import json
import copy
def hash_identification(identification):
id_str = json.dumps(identification, sort_keys=True)
return hashlib.sha256(id_str.encode()).hexdigest()
blueprints_dir = os.getenv("FOLDER", "/tmp/blueprints/")
sidecar_dir = os.getenv("BLUEPRINTS_FOLDER", "/blueprints/sidecar/")
state_file = os.getenv("PERSISTENT_STATE_FILE", "/tmp/blueprints_state.json")
# Load previous state if exists
if os.path.exists(state_file):
with open(state_file) as f:
previous_state = json.load(f)
else:
previous_state = {}
# Scan for YAML files
yaml_files = [f for f in os.listdir(blueprints_dir) if f.endswith(('.yaml', '.yml'))]
# Load YAML contents
yaml_contents = {}
for file in yaml_files:
with open(os.path.join(blueprints_dir, file)) as f:
yaml_contents[file] = yaml.safe_load(f)
# Build current state from YAML
state = {}
for filename, content in yaml_contents.items():
state[filename] = {}
for entry in content.get('entries', []):
entry_id = entry.get('id') or hash_identification(entry.get('identification', {}))
state[filename][entry_id] = entry
# Update state: add new, mark missing as absent
updated_state = copy.deepcopy(previous_state)
for filename, entries in state.items():
if filename not in updated_state:
updated_state[filename] = {}
# Mark entries not in YAML as absent
for prev_id in list(updated_state[filename].keys()):
if prev_id not in entries:
updated_state[filename][prev_id]['state'] = 'absent'
# Add/update entries from YAML
for entry_id, entry in entries.items():
updated_state[filename][entry_id] = entry
# Prepare updated YAML contents for writing
updated_yaml_contents = copy.deepcopy(yaml_contents)
for filename, entries in updated_state.items():
current_entries = {e.get('id') or hash_identification(e.get('identification', {})) for e in yaml_contents.get(filename, {}).get('entries', [])}
for entry_id, entry in entries.items():
if entry_id not in current_entries:
if filename not in updated_yaml_contents:
updated_yaml_contents[filename] = {'entries': []}
updated_yaml_contents[filename]['entries'].append(entry)
# Write updated YAML files to sidecar directory
os.makedirs(sidecar_dir, exist_ok=True)
for filename, content in updated_yaml_contents.items():
with open(os.path.join(sidecar_dir, filename), "w") as f:
yaml.safe_dump(content, f, sort_keys=False)
# Save updated state
with open(state_file, "w") as f:
json.dump(updated_state, f, indent=2)Please, publish updated version of the code here if you have luck to make it kinda working. if code still needs improvements to be used in production, hide it under details spolier. |
from what it think it shoudl not be handle by sidecar, but by Authentik itself like new blueprint => set it in DB => if do not exist anymore => remove from DB |
I limited by technology i can understand. Making changes in authentik logic should break someone's production, and making changes safe to "not break the things" are difficult without examination of the entire codebase. But scripts on sidecar are independent from the authentik version, that's the point why we can use it as sidecar now, and integrate into main codebase later. |
fix:
Helm values:
<1> normally just current namespace
Collects ConfigMaps and Secrets based on label and put them into goauthentik, here an example ConfigMap: